2011-08-27 7 views
0

Laissez-moi l'expliquer en profondeur, quand jamais la condition devient vraie, je fais beaucoup de choses, comme imprévu, un sélecteur, détruire un corps de balle appelant une animation (s'il vous plaît se référer code ci-dessous) etc. Cela fonctionne correctement la plupart du temps. Mais parfois, quand la balle est vraiment proche du trou (juste en touchant le trou mais pas assez pour rendre la condition ci-dessus vraie), ou a été lancée vers le trou à une vitesse vraiment rapide, l'application s'est terminée. J'ai vérifié, en commentant de nombreuses actions qui ont été effectuées dans cette section, mais n'a rien d'utile, l'application continue de se terminer quand des efforts ont été faits pour le faire se terminer.Cocos2d problème de fin de jeu quand un sprite en mouvement va à l'intérieur de la boîte de délimitation d'un sprite animant encore (une balle entrer dans un trou)

if(CGRectContainsPoint([hole1 boundingBox], ball1.position)) 
{ 
    ballBody->SetLinearVelocity(b2Vec2(0.0f,0.0f)); 
    ballBody->SetAngularVelocity(0.0f); 

    [self unschedule:@selector(tick:)]; 
    self.isTouchEnabled = NO; 

    [self removeChild:ball1 cleanup:YES]; 
    world->DestroyBody(ballBody); 

    // create the sprite sheet 
    CCSpriteSheet *spriteSheet; 

    GolfBallsAppDelegate *appDelegate = (GolfBallsAppDelegate *)[[UIApplication sharedApplication] delegate]; 
    if([appDelegate.ballValue isEqualToString:@"cricketball"]) 
    { 
     spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"cricket_ball_strip.png"]; 
    } 
    else if([appDelegate.ballValue isEqualToString:@"ironball"]) 
    { 
     spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"iron_ball_strip.png"]; 
    } 
    else if([appDelegate.ballValue isEqualToString:@"golfball"]) 
    { 
     spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"golf_ball_strip.png"]; 
    } 
    else if([appDelegate.ballValue isEqualToString:@"soccerball"]) 
    { 
     spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"soccer_ball_strip.png"]; 
    } 
    else if([appDelegate.ballValue isEqualToString:@"basketball"]) 
    { 
     spriteSheet = [CCSpriteSheet spriteSheetWithFile:@"basket_ball_strip.png"]; 
    } 

    spriteSheet.position = ccp(hole1.position.x,60); 
    [self addChild:spriteSheet]; 

    float frameWidth = 96; 
    float frameHeight = 84; 

    CCSprite *sprite = [CCSprite spriteWithTexture:spriteSheet.texture rect:CGRectMake(0, 0, frameWidth, frameHeight)]; 

    [spriteSheet addChild:sprite]; 

    //if(animation) 
    { 
     // create the animation 
     CCAnimation *spriteAnimation = [CCAnimation animationWithName:@"potting" delay:0.1f]; 

     int frameCount = 0; 
     for (int x = 0; x < 6; x++) 
     { 
      // create an animation frame 
      CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:spriteSheet.texture rect:CGRectMake(x*frameWidth,0*frameHeight,frameWidth,frameHeight) offset:ccp(0,0)]; 
      [spriteAnimation addFrame:frame]; 

      frameCount++; 

      // stop looping after we've added 14 frames 
      if (frameCount == 6) 
      { 
       //[self removeChild:spriteSheet cleanup:YES]; 
       break; 
      } 
     } 

     // create the action 
     CCAnimate *spriteAction = [CCAnimate actionWithAnimation:spriteAnimation]; 
     //CCRepeatForever *repeat = [CCRepeatForever actionWithAction:spriteAction]; 

     // run the action 
     [sprite runAction:spriteAction]; 
     //[sprite runAction:repeat]; 
    } 
    [self schedule:@selector(loading) interval:0.5]; 
    [self schedule:@selector(holeFinish) interval:1]; 
    //[self removeChild:spriteSheet cleanup:YES]; 
} 

Toute suggestion sera très appréciée.

EDIT: Ce que j'ai trouvé est, problème avec les lignes suivantes [self removeChild:ball1 cleanup:YES]; world->DestroyBody(ballBody); (MAI être). mais comme cela ne se produit pas toujours, comme je l'ai mentionné, c'est ridicule.

+0

Je vous recommande de le configurer de sorte que vous puissiez répéter le même mouvement de la balle exactement de sorte qu'elle se bloque à chaque fois, puis commencez à commenter des parties de code. Cela vous donnera au moins le point où il se bloque, sinon il est assez difficile de deviner ce qui se passe. – iforce2d

+0

oh oui je l'ai fait, mais ça n'a pas aidé, en fait quand la balle est lancée, vite alors ce problème se produit. – rptwsthi

+0

alors, quand le problème se produit, quel est le message de trace/pile – iforce2d

Répondre

2

Je pense que votre problème sera que vous essayez de supprimer un corps lorsque le b2World est «verrouillé», (lorsque le monde est occupé à travailler sur les collisions).

Essayez signalant l'objet comme prêt pour la suppression et le supprimer au début de votre prochaine boucle:

Remplacer:

[self removeChild:ball1 cleanup:YES]; 
world->DestroyBody(ballBody); 

avec

ball1.isDead = YES; 

Et au début de votre prochaine boucle de jeu:

for (Ball b in balls) 
{ 
    if (b.isDead) 
     world->DestroyBody(b.ballBody); 
} 
+0

Mais comme vous pouvez le voir, j'utilise une animation d'empotage de la balle, donc je pense que ça ira mal si je ne retire pas la balle. Une suggestion pour cela? – rptwsthi

+0

Je ne suggère pas que vous ne retirez pas la balle, mais ne l'enlevez pas dans le même cadre. Retirez-le au début de l'image suivante lorsque le monde n'est pas verrouillé. À 60 fps, ce n'est que 0.016 secondes plus tard –

+0

que se passe-t-il si je ne détruis pas la balle? – rptwsthi

Questions connexes