0

因此,在对这个问题连续数月感到非常沮丧之后休息了一会儿,我现在回来尝试一劳永逸地解决我的问题。

我不打算发布代码,因为我拥有的代码是杂乱无章的,并且来自无数的观点。

我的问题是这样的:

我有一个精灵,他的信息存储在一个名为 player.m 的类中。我有一个游戏关卡,它存储在 GameLevelLayer.m

我让 player.m 存储速度、方向和有关角色的所有信息,然后我让 GameLevelLayer.m 实现、移动、使用边界检查碰撞等。

我现在想使用 spritesheet 使角色移动(我知道如何进行 spritesheeting,我只是不知道如何在使用两个不同的类时做到这一点)

我的问题是,我是否在 player.m 中创建批处理节点和 spritesheet 信息(CCBatchnodes、缓存等)以及所有操作和所有内容,然后在 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 来发送玩家动作是最好的方法。

如果您的 Player 类从 CCSprite 扩展,则将与播放器相关的所有内容放在您的 Player 类中:在其上运行动画,在播放器构造函数上加载缓存(使用 CCSpriteinitWithTexture:rect:rotated:或自定义自动释放构造函数,如 a +(id)player)。

然后,在您的 GameLevelLayer 中,您将需要一个 CCSpriteBatchNode 来将您的玩家添加到其中。您可以使用此批处理节点来添加使用相同 spritesheet 的其他对象。

编辑:

查看您的代码,您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 只需执行此操作即可创建您的 Player。当它检测到用户输入时,调用播放器中的“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 回答