我试图在cocos2d中为一个对象设置动画,然后在动画完成后将其从图层中删除但由于是一个完整的新手,下面的内容对我来说不起作用。
我有两种状态 kStateDead 和 kStateScore 一旦被调用就会执行动画,然后从场景中移除但目前还没有发生
我检查了动画并且它们都有效,所以我在对象中添加了一个调试标签,它确实将状态更改为 kStateDead 或 kStateScore 。我还在状态中添加了一个 CCLOG ,并发现在调试区域中它不断重复 kStateDead 中的 CCLOG 或< strong> kStateScore (但不播放动画)这没有任何意义,因为我已经要求它在动画播放后删除并清理对象。
请参阅下面的控制台输出以及代码。任何有助于我朝着正确方向前进的帮助(不要指望你为我解决它!)将不胜感激。
2014-02-20 14:29:14.088 TestBallexercise [999:12c03] ball-&gt;将状态改为死亡
2014-02-20 14:29:14.089 TestBallexercise [999:12c03] ball-&gt;将状态改为死亡
2014-02-20 14:29:14.090 TestBallexercise [999:12c03] ball-&gt;将状态更改为死亡
2014-02-20 14:29:14.104 TestBallexercise [999:12c03] ball-&gt;将状态改为死亡
2014-02-20 14:29:14.105 TestBallexercise [999:12c03] ball-&gt;将状态更改为死亡
2014-02-20 14:29:14.106 TestBallexercise [999:12c03] ball-&gt;将状态改为死亡
-(void)changeState:(CharacterStates)newState {
[self stopAllActions];
[self setCharacterState:newState];
CGSize screenSize1 = [CCDirector sharedDirector].winSize;
characterState = newState;
id action = nil;
switch (newState) {
case kStateScore:
CCLOG(@"ball - score!");
action = [CCSequence actions:
[CCAnimate actionWithAnimation:scoreAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
nil];
break;
case kStateDead:
CCLOG(@"ball->change state to dead");
action = [CCSequence actions:
[CCAnimate actionWithAnimation:deadAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
nil];
break;
}
if (action !=nil)
[self runAction:action];
}
-(void)updateStateWithDeltaTime:(ccTime)deltaTime andListOfGameObjects:(CCArray *)listOfGameObjects {
CGPoint currentSpitePosition = [self position];
CGRect ballBoundingBox = [self adjustedBoundingBox];
if ((currentSpitePosition.x > screenSize3.width*0.95f)) {{
[self changeState:kStateScore];
}
return;
}
if ((currentSpitePosition.y < screenSize3.height*0.10f)) {{
[self changeState:kStateDead];
}
return;
}
if ([self numberOfRunningActions] == 0) {
if (characterState == kStateDead) {
[self setVisible:NO];
[self removeFromParentAndCleanup:YES];
return;
}
if (characterState == kStateScore) {
// [self changeState:kStateDead];
[self setVisible:NO];
[self removeFromParentAndCleanup:YES];
return;
}}}
答案 0 :(得分:1)
以一定的时间间隔重复调用update
函数。一旦允许的条件为kStateDead
,则调用changeState
并返回update
函数。在changeState
函数内部,操作将开始但同时再次调用update
函数,其中kStateDead的条件仍然为真,因此再次调用changeState,其中第一行中的stopsAllActions。因此,使sprite看起来不是动画。代码永远不会到达更新函数中的清理代码块。
有几种方法可以解决此问题。要么像
那样修改条件if ((currentSpitePosition.y < screenSize3.height*0.10f) && self.characterState != kStateDead) //this will ensure that once dead, changeState to dead is not called again.
但是,我建议你因为想要在动画完成后删除对象,所以最好添加一个回调来让你知道动画已经完成并在回调中执行清理代码。这可以通过
来完成action = [CCSequence actions:
[CCAnimate actionWithAnimation:deadAnim
restoreOriginalFrame:NO],
[CCDelayTime actionWithDuration:3.5f],
[CCFadeOut actionWithDuration:0.9f],
[CCCallFunc actionWithTarget:self selector:@selector(removeSelf)],
nil];
你可以在removeSelf函数中进行清理
-(void) removeSelf{
//your clean up code
}