0

在我的游戏中,我为我的敌人创建了一个 CCSprite (cocos2d) 的子类。因为我想从这个子类的每个实例中控制动画,所以我必须将我的主类中的动画代码(它加载敌人)翻译到这个子类。

我发现这相当困难,但是....过了一段时间,它神奇地开始起作用了。

不幸的是,在这个子类中创建和设置属性后,我开始出现奇怪的崩溃。因为它们在 cocosDenshion 和其他与我的敌人阶级无关的地方,并且在对我的代码和网络进行深入研究之后,我确信它存在某种数据损坏,我几乎完全可以肯定它是因为我用他的动画代码完成了我的敌人课程完全错误的方式。

老实说,我什至无法再考虑这里发生的事情以及这实际上是如何工作的:S ...我完全被卡住了。任何帮助深表感谢!

所以我的主要问题是:在 CCSprite 子类中实现动画的正确方法是什么?/我在这里做错了什么?

在这里简化了我的代码:(它每 2 秒触发一次动画以显示我想如何使用它)

#import "cocos2d.h"

@interface Npc : CCSprite 
{
    CCAction *_runAnimation;
    NSString* name;
    int strength;
}

@property (nonatomic, retain) CCAction *runAnimation;
@property int strength;
@property (nonatomic, retain) NSString* name;

- (Npc*)loadAnimation;
- (void)animate;
@end

#import "Npc.h"

@implementation Npc

@synthesize runAnimation = _runAnimation;
@synthesize name;
@synthesize strength;

-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect
{
    if( (self=[super initWithTexture:texture rect:rect]))
    {
    }
    return self;
}

- (Npc*)loadAnimation
{

    int lastFrame = 11;
    NSString *creatureFile = @"vis 1";

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:
     [NSString stringWithFormat:@"%@.plist", creatureFile]];
    CCSpriteBatchNode* sheet = [CCSpriteBatchNode batchNodeWithFile:
                                [NSString stringWithFormat:@"%@.png", creatureFile]];

    self = [Npc spriteWithTexture:sheet.texture];
    NSMutableArray* animFrames = [[NSMutableArray alloc] init];     

    for (int x = 0; x < lastFrame; x++) 
    {
        [animFrames addObject:
         [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
          [NSString stringWithFormat:@"%@ %d.png", creatureFile, x]]];              
    }

    CCAnimation* anim = [CCAnimation animationWithFrames: animFrames delay: 0.1];

    self.runAnimation = [CCAnimate actionWithAnimation:anim restoreOriginalFrame:NO];

    [self runAction:_runAnimation];

    return self;
}

- (void)animate
{
    [self runAction:self.runAnimation]; 
}

- (void)dealloc 
{
    [super dealloc];

    [name release];
}

@end

#import "HelloWorldLayer.h"
#import "Npc.h"

@implementation HelloWorldLayer

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];
    HelloWorldLayer *layer = [HelloWorldLayer node];
    [scene addChild: layer];
    return scene;
}


-(id) init
{

if( (self=[super init])) 
{
    timer = 0; 

    creatureTemp = [Npc spriteWithFile:@"Icon.png"];
    creature = [creatureTemp loadAnimation];
    creature.position = ccp(100,100);
    [self addChild:creature];

    [self schedule:@selector(nextFrame:)];

}
return self;
}


- (void)nextFrame:(ccTime)dt
{
    timer += dt;
    if (timer > 2.)
    {
        [creature animate];
        timer = 0.;
    }
}

- (void) dealloc
{
    [super dealloc];
}
@end

- - - - - - - - - -编辑 - - - - - - - - - -

我在 Ray Wenderlich 的教程的帮助下更改了我的代码:http ://www.raywenderlich.com/3888/how-to-create-a-game-like-tiny-wings-part-1

这是我认为更接近它应该的样子。不幸的是,它仍然在我的 iPhone(不是模拟器)上的 SimpleAudioEngine(我实现正确)上崩溃,所以我仍然做错了。

在 Npc 类之上:

@synthesize batchNode = _batchNode;

Npc类的初始化:

-(id) initNpc
{
    if( (self=[super initWithSpriteFrameName:@"vis 1 0.png"]))
    {
        _normalAnim = [[CCAnimation alloc] init];

        NSMutableArray* animFrames = [[NSMutableArray alloc] init]; 

        int lastFrame = 11;

        for (int x = 0; x < lastFrame; x++) 
        {
            [animFrames addObject:
             [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
              [NSString stringWithFormat:@"vis 1 %d.png", x]]]; 
        }

        _normalAnim = [CCAnimation animationWithFrames: animFrames delay: 0.1];
        self.runAnimation = [CCAnimate actionWithAnimation:_normalAnim restoreOriginalFrame:NO];


    }
    return self;
}

和 HelloWorldLayer 的初始化

-(id) init
{

    if( (self=[super init])) 
    {
        timer = 0; 


        _batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
        [self addChild:_batchNode];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

        creature = [[[Npc alloc] initNpc] autorelease];
        creature.position = ccp(200,200);

        [_batchNode addChild:creature];

        [self schedule:@selector(nextFrame:)];

        [[SimpleAudioEngine sharedEngine] preloadEffect:@"super1.mp3"];

    }
    return self;
}
4

2 回答 2

2

您在 loadAnimation 中重新分配 self :

 self = [Npc spriteWithTexture:sheet.texture];

那时我停止阅读代码。由于 self 已经是 Npc 类的一个实例,您必须问自己为什么要在诸如 loadAnimation 之类的 Npc 实例方法中执行此操作。

于 2012-08-10T13:52:43.413 回答
0

所以,我明白了....这是代码:

NPC.h:

#import "cocos2d.h"

@interface Npc : CCSprite 
{
    CCAction *_runAnimation;

    CCAnimation *_normalAnim;
    CCAnimate *_normalAnimate;

}

@property (nonatomic, retain) CCAction *runAnimation;


- (void)animate;
- (id)initNpc;

@end

人机界面

@synthesize runAnimation = _runAnimation;
@synthesize batchNode = _batchNode;

-(id) initNpc
{  
    if( (self=[super initWithSpriteFrameName:@"vis 1 0.png"]))
    {
        _normalAnim = [[CCAnimation alloc] init];        
        NSMutableArray* animFrames = [[NSMutableArray alloc] init];         
        int lastFrame = 7;        
        for (int x = 0; x < lastFrame; x++) 
        {
            [animFrames addObject:
             [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
              [NSString stringWithFormat:@"vis 1 %d.png", x]]]; 
        }        
        _normalAnim = [CCAnimation animationWithFrames: animFrames delay: 0.1];
        self.runAnimation = [CCAnimate actionWithAnimation:_normalAnim restoreOriginalFrame:NO];       
    }
    return self;
}

- (void)animate
{
    [self runAction:_runAnimation];
}

在 HelloWorldLayer.m

-(id) init
{

    if( (self=[super init])) 
    {

        _batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
        [self addChild:_batchNode];
        [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

        timer = 0; 

        creature = [[[Npc alloc] initNpc] autorelease];
        creature.position = ccp(200,200);

        [_batchNode addChild:creature];

        [self schedule:@selector(nextFrame:)];

    }
    return self;
}

- (void)nextFrame:(ccTime)dt
{
    timer += dt;
    if (timer > 2.)
    {
        [creature animate];
        timer = 0.;

    }
}

还有关于 cocosDenshion 的奇怪崩溃。这也解决了......它原来是 SimpleAudioEngine 中的一个已知错误,只有当我有一个异常断点处于活动状态时它才会抛出异常。解决方法:为我的声音创建一个类,如果我需要一个异常断点,我将声音注释掉......

- 不得不说,我确实更喜欢:

_batchNode = [CCSpriteBatchNode batchNodeWithFile:@"vis 1.png"];
    [self addChild:_batchNode];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"vis 1.plist"];

在 Npc 类中,但这对我来说太高级了。如果有人知道这一点,请告诉我......实际上会很高兴知道,更好地理解 oop。但这不是绝对必要的...

于 2012-08-24T01:35:41.203 回答