动画不能正常工作(Cocos2d)
Posted
技术标签:
【中文标题】动画不能正常工作(Cocos2d)【英文标题】:Animations are not working properly(Cocos2d) 【发布时间】:2011-10-12 07:03:24 【问题描述】:我的问题是动画在精灵移动期间无法正常工作。 下面是我正在使用的代码
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
[selSprite resumeSchedulerAndActions];
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self selectSpriteForTouch:touchLocation];
return TRUE;
- (void)selectSpriteForTouch:(CGPoint)touchLocation
CCSprite * newSprite = nil;
for (CCSprite *sprite in movableSprite)
if (CGRectContainsPoint(sprite.boundingBox, touchLocation))
newSprite = sprite;
break;
if (newSprite != selSprite)
[selSprite stopAllActions];
selSprite = newSprite;
_MoveableSpritetouch = TRUE;
if(_MoveableSpritetouch==TRUE)
movement=0;
CGRect selRect=CGRectMake((SpriteX)-20.0,(SpriteY)-20.0,40.0,40.0);
if(CGRectContainsPoint(selRect, touchLocation))
[selSprite stopAllActions];
if((selSprite==MarshallCar)&& (!(CGRectContainsPoint(selRect, touchLocation))))
movement=1;
[self reorderChild:selSprite z:5];
NSMutableArray *MarshallCarWalkAnimFrames = [NSMutableArray array];
for(int i = MarshallCarTouchStartFrameIndex; i <= MarshallCarTouchEndFrameIndex; ++i)
[MarshallCarWalkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"mcar_move_%d.png", i]]];
MarshallCarWalkAnim = [CCAnimation animationWithFrames:MarshallCarWalkAnimFrames delay:MarshallCarTouchFrameDelay];
walkMarshallCar = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:MarshallCarWalkAnim restoreOriginalFrame:NO]];
[selSprite runAction:walkMarshallCar];
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
if(gameState == TRUE)
CGPoint point = [touch locationInView:[touch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
if (moveDifference.x>0)
selSprite.flipX = YES;
else
selSprite.flipX = NO;
[selSprite setPosition:point];
-(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
movement=0;
if(selSprite==MarshallCar)
[selSprite setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"mcar_idle.png"]];
[selSprite pauseSchedulerAndActions];
移动的动画帧不是每次都在移动时播放,有时会播放,有时不播放。当您第一次触摸和移动精灵时,它会正常播放,但如果触摸另一个精灵然后再次移动前一个精灵,则不会播放移动动画。
有人知道为什么会这样吗? 请告诉我删除此错误的正确代码。 谢谢!!!
【问题讨论】:
【参考方案1】:我相信你的问题是 if/else if 构造:
if (_MoveableSpritetouch==TRUE)
CGRect selRect = CGRectMake(SpriteX - 20, SpriteY - 20, 40, 40);
if(CGRectContainsPoint(selRect, touchLocation))
[selSprite stopAllActions];
else if(...)
...
[selSprite runAction:walkMarshallCar];
如果您没有立即看到它:如果触摸位置在 selRect 内,则您在所选(新)精灵上调用 stopAllActions 并且不执行任何其他操作。仅当触摸位置不在该矩形内时,您才会运行动画操作。
我认为“矩形内”检查是多余的,因为您已经在上面几行调用了 stopAllActions。
请允许我对您的代码进行一些一般性评论:
“selectSpriteForTouch”方法告诉我你正在选择一个新的精灵。该功能就是这样做的。但它并不宣传播放动画。您可能希望将其重构为单独的“playAnimationOnSelectedSprite”方法。
您多次编写了 20.0 和 40.0。这意味着您实际上将双精度(8 字节浮点数据类型)传递给采用浮点数(4 字节浮点)的 CGPoint。严格来说,使用带有后缀“f”的 20.0f 将其表示为浮点数据类型,或者使用整数,因为您不使用浮点部分。
我不清楚为什么将 (SpriteX) 放在括号中,如果您想提高可读性,您可以通过在逗号和操作数后添加空格来实现更多目标。
在 Objective-C 中,使用 YES 和 NO 宏代替 TRUE 和 FALSE。
布尔变量 _MoveableSpritetouch 似乎是多余的,除非在其他地方需要。在任何情况下,您都应该将以下 if(_MoveableSpritetouch==TRUE) 块移动到您将 _MoveableSpritetouch 变量设置为 TRUE 的位置,因为它只会通过设置变量使您的代码更难阅读,留下您所在的代码块( if(selSprite != newSprite) ) 只是为了跳转到您已经知道无论如何都会运行的另一个代码块 ( if(_MoveableSpritetouch==TRUE) )。
【讨论】:
我已经编辑了代码 [ if((selSprite==MarshallCar)&& (!(CGRectContainsPoint(selRect, touchLocation) ] 现在告诉我有什么问题。【参考方案2】:if((selSprite==MarshallCar)&& (!(CGRectContainsPoint(selRect, touchLocation))))
movement=1;
[self reorderChild:selSprite z:5];
NSMutableArray *MarshallCarWalkAnimFrames = [NSMutableArray array];
for(int i = MarshallCarTouchStartFrameIndex; i <= MarshallCarTouchEndFrameIndex; ++i)
[MarshallCarWalkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"mcar_move_%d.png", i]]];
MarshallCarWalkAnim = [CCAnimation animationWithFrames:MarshallCarWalkAnimFrames delay:MarshallCarTouchFrameDelay];
walkMarshallCar = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:MarshallCarWalkAnim restoreOriginalFrame:NO]];
[selSprite runAction:walkMarshallCar];
我添加了 [selSprite stopAllActions]; 它开始正常工作,因为在触摸结束方法中我暂停了动作 但没有恢复它们,所以当我第二次触摸精灵时,它没有播放动画,因为动作暂停了。
【讨论】:
以上是关于动画不能正常工作(Cocos2d)的主要内容,如果未能解决你的问题,请参考以下文章
从时间轴播放 Spritebuilder 动画 - Cocos2d