Cocos2D:将精灵和动画子类化为CCLayer给我带来了麻烦



我开始用《Tiled》尝试Cocos2D,并将玩家精灵和动作编码在CCLayer中。在继续之前,我想将播放器子类化为CCLayer,我希望这是正确的。

我的头和主代码如下:

HeroClass.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface HeroClass : CCLayer {
    CCSprite *_hero;
    CCAction *_heroSpriteFlyAction;
}
@property(nonatomic, retain) CCSprite *hero;
@property(nonatomic, retain) CCAction *heroSpriteFlyAction;
@end

HeroClass.m

#import "HeroClass.h"
@implementation HeroClass
@synthesize hero =_hero;
@synthesize heroSpriteFlyAction = _heroSpriteFlyAction;
-(id) init{
    self = [super init];
    if (!self) {
        return nil;
    }
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"heroTestSheet.plist"];
    CCSpriteBatchNode *heroSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"heroTestSheet.png"];
    [self addChild:heroSpriteSheet];
    NSMutableArray *heroSpriteFlyAnimFrames = [NSMutableArray array];
    for(int i = 1; i <= 2; ++i) {
        [heroSpriteFlyAnimFrames addObject:
         [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
          [NSString stringWithFormat:@"heroFrame%d.png", i]]];
    }
    CCAnimation *heroSpriteFlyAnim = [CCAnimation animationWithFrames:heroSpriteFlyAnimFrames delay:0.03f];
    self = [CCSprite spriteWithSpriteFrameName:@"heroFrame1.png"];  
    _heroSpriteFlyAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:heroSpriteFlyAnim restoreOriginalFrame:NO]];
    [self runAction:_heroSpriteFlyAction];
    [heroSpriteSheet addChild:self];

    return self;
}
- (void) dealloc{
    self.hero = nil;
    self.heroSpriteFlyAction = nil;
    [super dealloc];
}
@end

我想我想实现的想法是,我可以访问的东西在这个类的属性在其他文件。上面的代码在构建时没有给出错误,但可能我没有做正确的事情。问题是我的迁移是现在发生的事情在我的CCLayer类DebugZoneLayer,它创建地图,应该添加我的球员精灵,但给我错误。

在DebugZoneLayer.h中,我导入了HeroClass.h,并从英雄精灵的HeroClass中创建了一个指针,并赋予它一个属性。这里没有错误,但这可能是我错误的开始:

#import "cocos2d.h"
#import "HeroClass.h"
@class HeroClass;
// DebugZone Layer
@interface DebugZoneLayer : CCLayer {
    HeroControl *heroControl;
    HeroClass *hero;    
    CCTMXTiledMap *theMap;
    CCTMXLayer *blocksCollidable;
    CCTMXLayer *invisiblePropertiesLayer;   
}

@property(nonatomic, retain) CCSprite *hero;
在DebugZoneLayer

。m,当我合成hero时,它给出了错误"Type of property 'hero' does not match Type of ivar 'hero'

@synthesize hero;

文件的其余部分给出了更多与引用hero相关的错误,但至少这是它开始的地方。

编辑(更新)

只是想提一下,因为这个问题已经解决了,我清理了HeroClass中的一些主要问题。导致崩溃的M:

#import "HeroClass.h"
@implementation HeroClass
@synthesize heroSprite =_heroSprite;
@synthesize heroSpriteSheet =_heroSpriteSheet;
@synthesize heroSpriteFlyAction = _heroSpriteFlyAction;
-(id) init{
    self = [super init];
    if (!self) {
        return nil;
    }
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"heroTestSheet.plist"];
    _heroSpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"heroTestSheet.png"];
    //[self addChild:_heroSpriteSheet];
    NSMutableArray *heroSpriteFlyAnimFrames = [NSMutableArray array];
    for(int i = 1; i <= 2; ++i) {
        [heroSpriteFlyAnimFrames addObject:
         [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
          [NSString stringWithFormat:@"heroFrame%d.png", i]]];
    }
    CCAnimation *heroSpriteFlyAnim = [CCAnimation animationWithFrames:heroSpriteFlyAnimFrames delay:0.03f];
    _heroSprite = [CCSprite spriteWithSpriteFrameName:@"heroFrame1.png"];  
    _heroSpriteFlyAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:heroSpriteFlyAnim restoreOriginalFrame:NO]];
    [self runAction:_heroSpriteFlyAction];
    [_heroSpriteSheet addChild:_heroSprite];

    return self;
}
- (void) dealloc{
    self.heroSprite = nil;
    self.heroSpriteSheet = nil;
    self.heroSpriteFlyAction = nil;
    [super dealloc];
}
@end

这不是100%与你的问题有关。但是你的属性还有一个问题。

将属性定义为retain,并在dealloc函数中释放它,但实际上您从未保留该对象。

_heroSprite = [CCSprite spriteWithSpriteFrameName:@"heroFrame1.png"];

在这个位置,_heroSprite变量包含启用了自动释放的精灵…你没有保留它。

当然你不会丢失它,因为它会被这一行保留:

[heroSpriteSheet addChild:_heroSprite];

但是当子元素从表单中移除时,它将被释放。

所以这在dealloc中是不必要的:self.heroSprite = nil;[_heroSprite release];甚至会使你的代码崩溃。

如前所述,代码可以工作,但是当您稍后查看它时,可能会感到困惑。

您应该将属性声明为(nonatomic, assign)或使用

适当地保留它。
self.herosprite = [CCSprite spriteWithSpriteFrameName:@"heroFrame1.png"];

尝试更改DebugZoneLayer类中的属性:

@property(nonatomic, retain) CCSprite *hero;

:

@property(nonatomic, retain) HeroClass *hero;

最新更新