0

そのため、この問題で何ヶ月も非常にイライラした後、少し休憩した後、私は戻ってきて、問題を完全に解決しようとしています.

私が持っているコードは乱雑でまだらで、数え切れないほどの観点からのものであるため、コードを投稿するつもりはありません。

私の問題はこれです:

スプライトがあり、その情報は player.m というクラスに保存されています。ゲームレベルがあり、GameLevelLayer.m に保存されています

player.m に速度、方向、およびキャラクターに関するすべての情報を格納してから、GameLevelLayer.m を実装、移動、境界を使用して衝突などをチェックします。

スプライトシートを使用してキャラクターを動かしたいと思っています (スプライトシートの方法は知っていますが、2 つの異なるクラスで作業しているときにその方法を知りません)。

私の質問は、バッチノードとスプライトシート情報 (CCBatchnode、キャッシュなど) とすべてのアクションとすべてを player.m で作成し、それらを GameLevelLayer.m で実行することですか? それとも、GameLevelLayer.m ですべてを作成しますか?

私は何ヶ月もこれで立ち往生しているので、ここで本当に助けが必要です

編集:

コミュニティメンバーからの提案のおかげで、私はここにいます。

これは私の player.m 全体です (簡単に言えば、私はプレーヤーに関するすべてを定義しています ' init に注意を払いたいだけかもしれません。それが問題のようです。他のものは私の物理エンジンです')

#import "Player.h"
#import "SimpleAudioEngine.h"
#import "GameLevelLayer.h"

@implementation Player

@synthesize velocity = _velocity;
@synthesize desiredPosition = _desiredPosition;
@synthesize onGround = _onGround;
@synthesize forwardMarch = _forwardMarch, mightAsWellJump = _mightAsWellJump, isGoingLeft = _isGoingLeft;
@synthesize WalkAction = _WalkAction;
@synthesize isMoving = _isMoving;

-(id)initWithTexture:(CCTexture2D *)texture{
if (self = [super init]) {

    self.velocity = ccp(0.0, 0.0);

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: @"BankerSpriteSheet_default.plist"];

    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"BankerSpriteSheet_default.png"];
    [self addChild:spriteSheet];

    NSMutableArray *walkAnimFrames = [NSMutableArray array];
    for(int i = 1; i <=6; ++i) {
        [walkAnimFrames addObject: [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: [NSString stringWithFormat:@"banker%d.png", i]]];

        CCAnimation *walkAnim = [CCAnimation animationWithFrames:walkAnimFrames delay:0.1f];
        self = [super initWithSpriteFrameName:@"banker1.png"];
        self.WalkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
        //[_Banker runAction:_WalkAction];
        [spriteSheet addChild:self];
        [[CCAnimationCache sharedAnimationCache] addAnimation:walkAnim name:@"walkAnim"];
    }
}
return self;
}

-(void)update:(ccTime)dt {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize];
CGPoint jumpForce = ccp(0.0, 310.0);
float jumpCutoff = 150.0;

if (self.mightAsWellJump && self.onGround) {
    self.velocity = ccpAdd(self.velocity, jumpForce);
    if (![defaults boolForKey:@"All Muted"]) {
        if (![defaults boolForKey:@"SFX Muted"]) {
            [[SimpleAudioEngine sharedEngine] playEffect:@"jump.wav"];
        }
    }

} else if (!self.mightAsWellJump && self.velocity.y > jumpCutoff) {
    self.velocity = ccp(self.velocity.x, jumpCutoff);
}

CGPoint gravity = ccp(0.0, -450.0);
CGPoint gravityStep = ccpMult(gravity, dt);
CGPoint forwardMove = ccp(800.0, 0.0);
CGPoint forwardStep = ccpMult(forwardMove, dt);

self.velocity = ccp(self.velocity.x * 0.90, self.velocity.y); //2

if (self.forwardMarch) {
        self.velocity = ccpAdd(self.velocity, forwardStep);
    if (!self.isMoving) {
        //[self runAction: _WalkAction];
        //self.isMoving = YES;
    }
} //3

CGPoint minMovement = ccp(0.0, -450.0);
CGPoint maxMovement = ccp(120.0, 250.0);
self.velocity = ccpClamp(self.velocity, minMovement, maxMovement);

self.velocity = ccpAdd(self.velocity, gravityStep);

CGPoint stepVelocity = ccpMult(self.velocity, dt);
if (!self.isGoingLeft) {
    self.desiredPosition = ccpAdd(self.position, stepVelocity);
}else{
    self.desiredPosition = ccp(self.position.x-stepVelocity.x, self.position.y+stepVelocity.y);
}

}

-(CGRect)collisionBoundingBox {

CGRect collisionBox = CGRectInset(self.boundingBox, 3, 0);
//CGRect collisionBox = self.boundingBox;
//collisionBox = CGRectOffset(collisionBox, 0, -2);
CGPoint diff = ccpSub(self.desiredPosition, self.position);
CGRect returnBoundingBox = CGRectOffset(collisionBox, diff.x, diff.y);
return returnBoundingBox;

}



@end

問題は、プレーヤーを通常のスプライトのようにゲームに表示する方法と、プレーヤーが前進し始めたときにアニメーションを実行する方法です。

4

1 に答える 1

0

あなたのゲーム アーキテクチャは非常に優れています。プレーヤーのプロパティをプレーヤーに保持し、GameLayer を使用してプレーヤー アクションを送信することが最善の方法です。

プレーヤー クラスが CCSprite から拡張されている場合は、プレーヤーに関連するすべてのものをプレーヤー クラスに配置します。その上でアニメーションを実行し、プレーヤー コンストラクターにキャッシュをロードします (CCSpriteinitWithTexture:rect:rotated:または のようなカスタム自動解放コンストラクターを使用します+(id)player)。

次に、GameLevelLayer で、プレーヤーを追加するための CCSpriteBatchNode が必要になります。このバッチ ノードを使用して、同じスプライト シートを使用する他のオブジェクトを追加できます。

編集:

コードを確認すると、あなたinitWithTextureは間違っています。正しいのは、次のように呼び出すこと[super initWithTexture:]です。

-(id)initWithTexture:(CCTexture2D *)texture{
    if (self = [super initWithTexture:texture]) {

次に、GameLevelLayer でプレーヤーを作成し、それを CCSpriteBatchNode に追加します。

// *** In GameLevelLayer.m ***
// Create player
Player *player = [Player spriteWithFile:@"player.png"];
// Create batch node
CCSpriteBatchNode *batchNode = [CCSpriteBatchNode batchNodeWithTexture:player.texture];
// Add batch node as child
[self addChild:batchNode];
// Add player as batch node's child
[batchNode addChild:player];
// Set player position
player.position = ccp(100,100);

GameLevelLayer は、プレーヤーを作成するためにこれだけを行う必要があります。ユーザー入力を検出すると、プレーヤーで「jump」、「moveRight」、「moveLeft」などのメソッドを呼び出します。また、衝突を検出し、「die」、「getSpecialItem」などのアクションをプレイヤーに送信します。

// *** In GameLevelLayer.m ***
[player jump];
[player die];

したがって、プレイヤーはこれらのメソッドを処理し、独自のロジックを実行してアクションを実行する必要があります。

// *** In Player.m ***
- (void)moveRight
{
    self.position = ccpAdd(self.position, ccp(10,0));
}
于 2013-07-29T15:20:46.023 に答える