Заставляем 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:..]