开发者

Animations are not working properly(Cocos2d)

My problem is that animation are not working properly during movements of sprite. Below is the code which i'm using

- (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];
}

The animation frames for movement are not playing every time during movements sometimes it plays or sometimes not. It plays properly when you touch and move your sprite for the first time but if touch another sprite and then again move the previous sprite the animations for movement won't play.

Is anyone having any idea why this is happening? Please tell me the proper code for removing this bug. Thanks!!!


I believe your problem is the if/else if construct:

if (_MoveableSpritetouch==TRUE)
{
        CGRect selRect = CGRectMake(SpriteX - 20, SpriteY - 20, 40, 40);
        if(CGRectContainsPoint(selRect, touchLocation))
        {  
            [selSprite stopAllActions];
        }
        else if(...) 
        {
            ...
            [selSprite runAction:walkMarshallCar];
        }
}

If you don't see it right away: if the touch location is inside the selRect, you call stopAllActions on the selected (new) sprite and do nothing else. Only if the touch location is not within that rectangle you'll run the animation action.

I think the "in rectangle" check is superfluous since you've already called stopAllActions anyway a few lines above.

Allow me a few general remarks about your code:

The method "selectSpriteForTouch" tells me that you're selecting a new sprite. The function does that. But it does not advertise playing an animation. You might want to refactor this out to a seperate "playAnimationOnSelectedSprite" method.

You wrote 20.0 and 40.0 several times. This means you're actually passing a double (8 bytes floating point data type) to a CGPoint which takes floats (4 bytes floating point). Strictly speaking use either 20.0f with the suffixed "f" to denote it as a floating point data type, or use integers since you don't use the floating point part.

Why you put (SpriteX) in brackets is not clear to me, if you want to enhance readability you'll achieve more by adding spaces after commas and operands.

In Objective-C, use YES and NO macros instead of TRUE and FALSE.

The bool variable _MoveableSpritetouch seems superfluous, unless needed someplace else. In any case you should move the following if(_MoveableSpritetouch==TRUE) block to where you set the _MoveableSpritetouch variable to TRUE because it just makes your code harder to read by setting a variable, leaving the code block you were in ( if(selSprite != newSprite) ) just to jump into another block of code ( if(_MoveableSpritetouch==TRUE) ) that you already know you're going to run anyway.


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];
        }

I have added [selSprite stopAllActions]; and it started working correctly because in the touch ended method i was pausing the actions but not resuming them so when i touch the sprite for the second time it was not playing animation because the action was paused.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜