使SpriteSheets工作cocos2d

时间:2013-06-06 19:45:03

标签: cocos2d-iphone ccsprite sprite-sheet ccspritebatchnode

所以我一直在研究我的cocos2d游戏一段时间,现在只使用一个静态的一帧精灵,因为我还没有得到完整spritesheet的图形。现在我有spritesheet,我在实现它时遇到了麻烦。

我目前制作“玩家”(精灵)的方式是拥有一个单独的玩家类,如下所示

Player.h

@interface Player : CCSprite{
CCAction *_WalkAction;
}
@property (nonatomic, assign) CCAction *WalkAction;
@property (nonatomic, assign) CGPoint velocity;
@property (nonatomic, assign) CGPoint desiredPosition;
@property (nonatomic, assign) BOOL onGround;
@property (nonatomic, assign) BOOL forwardMarch;
@property (nonatomic, assign) BOOL mightAsWellJump;
@property (nonatomic, assign) BOOL isGoingLeft;

-(void)update:(ccTime)dt;
-(CGRect)collisionBoundingBox;

@end

和Player.m(我不会展示完整的东西,因为它很长,它只是定义了角色的所有内容)

-(id)initWithFile:(NSString *)filename {
if (self = [super initWithFile:filename]) {
    self.velocity = ccp(0.0, 0.0);
}
return self;
}

  //THIS IS ONLY A FRACTION OF MY UPDATE METHOD, THE REST OF IT IS ALL SETTING VELOCITY AND WHATNOT FOR MY PHYSICS ENGINE, BUT THIS IS THE ONLY RELEVANT PART
-(void)update:(ccTime)dt {
if (self.forwardMarch) {
        self.velocity = ccpAdd(self.velocity, forwardStep);
 //[self runAction: _WalkAction];
    }    
}

现在在我的GameLevelLayer.m中我像这样初始化精灵(这是我们从player.m中的init获取文件名的地方):

//In my init
map = [[CCTMXTiledMap alloc] initWithTMXFile:@"level1.tmx"];
    [self addChild:map];

 player = [[Player alloc] initWithFile:@"banker1.png"];
    player.position = ccp(100, 50);
    [map addChild:player z:15];

这样一切都运行得很好。当我尝试将精灵变成带spritesheet的精灵时,就会出现问题。所以我尝试在player.m

中这样做
-(id)initWithFile:(NSString *)filename {
if (self = [super initWithFile:filename]) {

    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 = [CCSprite spriteWithSpriteFrameName:@"banker1.png"];

//HERE IS WHERE self.WalkAction IS DEFINED

        self.WalkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
        [spriteSheet addChild:self];
    }

}
return self;
}

//And then run it in my update method

if (self.forwardMarch) {
        self.velocity = ccpAdd(self.velocity, forwardStep);
    [self runAction: _WalkAction];

}

仅供参考,self.forwardMarch是每次用户按下按钮移动玩家时设置的bool,所以无论什么时候我都按这样移动玩家。

但是当我尝试这个时,我得到了错误

'NSInvalidArgumentException', reason: '-[CCSprite setWalkAction:]: unrecognized selector sent to instance 0x88fab50'

感谢任何帮助。

我还在cocos2d论坛上发布了这个,如果你更喜欢他们的代码显示系统(颜色编码和诸如此类) http://www.cocos2d-iphone.org/forums/topic/making-spritesheets-work/

修改

好的,所以我取得了一些进展,但我仍然有点陷入困境。我已经在GameLevelLayer.m的初始化中定义了batchnodes和所有动作

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

    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"BankerSpriteSheet_default.png"];
    [self addChild:spriteSheet];
    [player 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];
        player = [[Player alloc] initWithSpriteFrameName:@"banker1.png"];
        player.WalkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim restoreOriginalFrame:NO]];
        //[spriteSheet addChild:player];
    }

    //player = [[Player alloc] initWithFile:@"koalio_stand.png"];
    player.position = ccp(100, 50);
    player.scale = 0.2;
    [map addChild:player z:15];

然后在我的Player.m中运行

[self runAction: self.WalkAction];
//I've also tried [self runAction: _WalkAction]; The result is the same

我使用NSLogs来发现上面的部分([self runAction:self.WalkAction];正在被调用但没有完成。这是我的崩溃发生的地方,但是控制台没有输出为什么有崩溃..字面上只是说(lldb)

1 个答案:

答案 0 :(得分:0)

问题是在实际错误之上一行。您使用[CCSprite spriteWith ...]中的结果为self分配,该结果替换现有的self并将其替换为CCSprite。而是将init行更改为self = [super initWithSpriteFrameName:..]