2011-10-12 7 views
1

Mon problème est que l'animation ne fonctionne pas correctement pendant les mouvements de l'image-objet. Voici le code que je suis en utilisantLes animations ne fonctionnent pas correctement (Cocos2d)

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

Les cadres d'animation pour le mouvement ne jouent pas à chaque fois lors des mouvements parfois, il joue parfois pas. Il joue correctement lorsque vous touchez et déplacez votre sprite pour la première fois, mais si vous touchez une autre image-objet, puis déplacez à nouveau l'image-objet précédente, les animations pour le mouvement ne seront pas lues.

Quelqu'un a-t-il une idée de la raison pour laquelle cela se produit? S'il vous plaît dites-moi le code approprié pour supprimer ce bug. Merci !!!

Répondre

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

J'ai ajouté [selSprite stopAllActions]; et il a commencé à fonctionner correctement car dans la méthode touchée, je mettais les actions en pause mais je ne les reprenais pas, donc lorsque je touchais le sprite pour la deuxième fois, il ne jouait pas d'animation parce que l'action était en pause.

0

Je crois que votre problème est le if/else instruction if:

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

Si vous ne voyez pas tout de suite: si l'emplacement est à l'intérieur du contact selRect, vous appelez stopAllActions sur le sélectionné (nouveau) sprite et ne fais rien d'autre. Seulement si l'emplacement tactile n'est pas dans ce rectangle, vous allez exécuter l'action d'animation.

Je pense que la vérification "en rectangle" est superflue puisque vous avez déjà appelé stopAllActions de quelques lignes au dessus.

Qu'il me soit permis quelques remarques générales sur votre code:

La méthode « selectSpriteForTouch » me dit que vous choisissez un nouveau sprite. La fonction le fait. Mais il ne fait pas de publicité pour jouer une animation. Vous pouvez refactoriser ceci à une méthode "playAnimationOnSelectedSprite" séparée.

Vous avez écrit 20.0 et 40.0 plusieurs fois. Cela signifie que vous passez réellement un double (type de données en virgule flottante de 8 octets) à un CGPoint qui prend des flottants (flottant de 4 octets). Strictement parlant, utilisez soit 20.0f avec le suffixe "f" pour le désigner comme un type de données à virgule flottante, ou utilisez des entiers puisque vous n'utilisez pas la partie à virgule flottante. Pourquoi ne pas mettre (SpriteX) entre crochets n'est pas clair pour moi, si vous voulez améliorer la lisibilité, vous obtiendrez plus en ajoutant des espaces après les virgules et les opérandes.

En Objective-C, utilisez les macros YES et NO au lieu de TRUE et FALSE.

La variable booléenne _MoveableSpritetouch semble superflue, sauf si nécessaire ailleurs. Dans tous les cas, vous devez déplacer le bloc suivant if (_MoveableSpritetouch == TRUE) à l'endroit où vous définissez la variable _MoveableSpritetouch sur TRUE car cela rend votre code plus difficile à lire en définissant une variable, en laissant le bloc de code dans lequel vous étiez (selSprite ! = newSprite)) juste pour sauter dans un autre bloc de code (if (_MoveableSpritetouch == TRUE)) que vous savez déjà que vous allez exécuter quand même.

+0

J'ai modifié le code par [if ((selSprite == MarshallCar) && (! (CGRectContainsPoint (selRect, touchLocation)] maintenant me dire quel est le problème. – Neha

Questions connexes