Заставляем SpriteSheets Работать cocos2d

Поэтому я некоторое время работал над своей игрой cocos2d, просто используя статический однокадровый спрайт, потому что я еще не получил графику для полной таблицы спрайтов. Теперь у меня есть спрайт-лист, и у меня возникают проблемы с его реализацией.

В настоящее время я делаю своего "Игрока" (спрайт), имея отдельный класс игрока, показанный ниже

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 я инициирую спрайт следующим образом (это откуда мы получаем имя файла от init в player.m):

//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];

Так что все работает отлично. Проблема возникает, когда я пытаюсь превратить этот спрайт в спрайт с таблицей спрайтов. Поэтому я пытаюсь сделать это в 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/

РЕДАКТИРОВАТЬ:

Итак, я немного продвинулся, но я все еще немного застрял. Я определил batchnodes и все действия в начале GameLevelLayer.m

[[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 ответ

Проблема на одну строку выше фактической ошибки. Вы присваиваете себе результат с [CCSprite spriteWith...], который заменяет существующее "я" и заменяет его на CCSprite. Вместо этого измените строку инициализации на self = [super initWithSpriteFrameName:..]

Другие вопросы по тегам