2011-08-08 69 views
0

我在想如果有人能解释我如何在cocos2d中重新使用动画?我习惯于所谓的通常的方式:我创建一个'游戏对象',加载动画,然后简单地调用我的动画,如gameObj->idle();gameObj->walkToPoint(); ...cocos2d中的动画

我知道这些帮助器方法应该由我自己定义,我也学习了很多有关CC2d的指南,并以不同的方式使用动画,但这些指南太简单了,不会拍摄真实案例。

因此,在我写这从plist中和PNG纹理加载动画方法的那一刻,会将此纹理父层和第一精灵分配给“游戏对象”精灵。但我有一些问题 - 我仍然无法找到播放动画的方式。

情况对我来说比较困难(但我知道,这是通常的情况:) - 动画应该被分配到“操作”,并应该有不同类型的动作。例如 - 空闲动作永远播放,死亡播放一次,并停留在最后一帧,并且拍摄动作播放一次,并恢复先前的帧 - 闲置的一个。

为了简单起见,我将展示一些基本的代码w \ o复杂的检查和for..in循环(我想知道谁决定将所有帧以cc2d动画格式存储为Array,并将它们加载为frame_%d,而不是将Dictionary结构Animations->Idle->FramesAnimations->Shoot->Frames,但这不是主要的一点:))

//These things are global 
CCAnimation *idleAnim; 
CCAction * idleAction; // idle animation should be played forever 

CCAnimation *deathAnim; 
CCAction * deathAction; // death animation should be played once and stop at last frame 

CCAnimation *shootAnim; 
CCAction * shootAction; // shoot animation should be played once and idle frame restored 


    // loading animations with simple for loops 
    - (id)init { 
    self = [super initWithColor:ccc4(255,255,255,255)]; 
if (self) {  

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile: 
    @"player.plist"]; 
    CCSpriteBatchNode *spriteSheet = [CCSpriteBatchNode 
             batchNodeWithFile:@"player.png"]; 

    [self addChild:spriteSheet]; 

    NSMutableArray *idleAnimFrames = [NSMutableArray array]; 
    for(int i = 1; i <= 20; ++i) { 
     [idleAnimFrames addObject: 
     [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: 
     [NSString stringWithFormat:@"hero_idle01_%04i_Layer-%i.png", i-1, i]]]; 
    } 

    idleAnim = [CCAnimation animationWithFrames:idleAnimFrames delay:0.1f]; 

    idleAction = [CCRepeatForever actionWithAction: 
        [CCAnimate actionWithAnimation:idleAnim restoreOriginalFrame:NO]]; 



    NSMutableArray *deathAnimFrames = [NSMutableArray array]; 
    for(int i = 0; i <= 30; ++i) { 
     [deathAnimFrames addObject: 
     [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: 
     [NSString stringWithFormat:@"hero_death01_%04i_Layer-%i.png", i, i+1]]]; 
    } 

    deathAnim = [CCAnimation animationWithFrames:deathAnimFrames delay:0.1f]; 

    deathAction = [CCAnimate actionWithAnimation:deathAnim restoreOriginalFrame:NO]; 





    NSMutableArray *shootAnimFrames = [NSMutableArray array]; 
    for(int i = 0; i <= 19; ++i) { 
     [shootAnimFrames addObject: 
     [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: 
     [NSString stringWithFormat:@"hero_idleshoot02_%04i_Layer-%i.png", i, i+1]]]; 
    } 

    shootAnim = [CCAnimation animationWithFrames:shootAnimFrames delay:0.1f]; 

    shootAction = [CCAnimate actionWithAnimation:shootAnim restoreOriginalFrame:YES]; 



    self.player = [CCSprite spriteWithSpriteFrameName:@"hero_idle01_0000_Layer-1.png"];   

    self.player.position = ccp(20, self.size.height/2); 

    [self.player runAction:shootAction]; 

    [spriteSheet addChild:self.player]; 

    [self.player runAction:[CCRotateTo actionWithDuration:0.0f angle:45]]; 



    [self schedule:@selector(gameLogic:) interval:1.0]; 
    } 
    return self; 
} 

该代码可以正常运行(负载空闲的动画,永远播放它),但我无法找到的行动,并很好地animatinos之间切换的方式。例如,当有人不想拍摄动画时,我看到了一些方法,他删除了原始精灵从拍摄中获取第一个精灵,玩过拍摄,删除了拍摄精灵,恢复了原始精灵。但是,如果精灵被旋转了呢?人们应该通过精灵之间的原始精灵的所有参数,例如翻转,旋转,缩放等等。通常游戏对象是从CCSprite继承而来的,所以这种方法通常意味着应该一直删除和恢复主游戏对象?这对我来说并不明确。

我尝试了接下来的事情,但他们没有为我工作,程序只是暂停,没有任何东西写入调试(我是来宾,这是因为错误发生在其他线程中,负责触摸处理的线程)。

// somewhere after touch happened in [shootToPoint:(CGPoing)point] method 
    [idleAction stop]; 
    [shootAction startWithTarget:self.player]; 
    [self.player runAction:[CCSequence actions: 
          shootAction, 
          [CCCallFuncN actionWithTarget:self selector:@selector(shooted)], 
          nil]]; 

而在shooted方法我再次呼吁这样的事:

[shootActino stop]; // or [self.player stopAllActions] - doesn't matter I guess 
    [idleAction startWithTarget:self.player]; 
    CCSprite *sprite = (Bullet *)sender; // remove bullet sprite from memory 
    [self removeChild:sprite cleanup:YES]; // remove bullet sprite from memory 
    // other routines... 

所以有人可以解释我如何创建的helper方法的游戏对象切换动画?请不要将我发送到cc2d文档,因为目前还不清楚如何从网络上的cc2d文档或其他教程解决这个简单问题。

回答

2

因为要创建具有辅助方法,而不是你的情况下,分配/ initWith ......之后就被自动释放,这就是为什么你得到一个崩溃。

例如你的空闲动画应该像这样创建:

NSMutableArray *idleAnimFrames = [[NSMutableArray alloc] init]; 
for(int i = 1; i <= 20; ++i) { 
    [idleAnimFrames addObject: 
    [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName: 
     [NSString stringWithFormat:@"hero_idle01_%04i_Layer-%i.png", i-1, i]]]; 
} 

CCAnimation *idleAnimation = [[CCAnimation alloc] initWithFrames:idleAnimFrames delay:0.1f]; 
[idleAnimFrames release]; 

CCAnimate *idleAnimate = [[CCAnimate alloc] initWithAnimation:idleAnimation restoreOriginalFrame:NO]; 
[idleAnimation release]; 

idleAction = [[CCRepeatForever alloc] initWithAction:idleAnimate]; 
[idleAnimate release]; 

这样,直到你释放它(你应该在你的dealloc方法做,否则当你的地方,你可以使用这个动作多次'完成了它)。

+0

哦,我一直在使用objective-c一段时间,但仍然陷入这些保留/释放陷阱......我知道正确的答案是在角落附近:)非常感谢你! – asdf