2010-05-21 6 views
1

J'essaie de jouer des animations en séquence, mais j'ai des problèmes pour les lire car une boucle for itère dans la liste des objets d'un tableau.Lecture d'animations en séquence dans objecive c

il se déplace à travers le réseau, mais il ne joue pas chacun joue juste le dernier ...

-(void) startGame { 
    gramma.animationDuration = 0.5; 

    // Repeat forever 
    gramma.animationRepeatCount = 1; 
    int r = arc4random() % 4; 
    [colorChoices addObject:[NSNumber numberWithInt:r]]; 

    int anInt = [[colorChoices objectAtIndex:0] integerValue]; 
    NSLog(@"%d", anInt); 
    for (int i = 0; i < colorChoices.count; i++) { 

     [self StrikeFrog:[[colorChoices objectAtIndex:i] integerValue]]; 
     //NSLog(@"%d", [[colorChoices objectAtIndex:i] integerValue]); 
     sleep(1); 

    } 
} 

se déplace à travers tout le cycle vraiment rapide et sommeil ne fait rien pour permettre pour jouer chaque animation ... des suggestions?

Répondre

0

Utilisez un NSTimer pour que la boucle d'exécution ait le temps de traiter. Le dessin ne commence qu'après le retour de startGame.

Edit:

-(void) myTimerMethod:(NSTimer *)inTimer { 
    if (mPosition < [colorChoices count]) { 
    [self StrikeFrog:[[colorChoices objectAtIndex:mPosition] integerValue]]; 
    mPosition += 1; 
    } else { 
    [inTimer invalidate]; 
    } 
} 

Pour le lancer:

mPosition = 0; 
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(myTimerMethod:) userInfo:nil repeats:YES]; 

Si vous devez être en mesure d'arrêter le retardateur à mi-, conserver une référence à ce que vous pouvez annuler au besoin.

+0

Hmm comment ferais-je cela? J'ai vu quelques exemples de NSTimer mais je n'ai pas encore appris à l'utiliser correctement. Bien que cela fasse beaucoup de sens. Parce que c'était seulement la dernière animation de la séquence que je trouvais un peu agaçante. La minuterie doit-elle fonctionner à l'intérieur de la boucle ou comme une sorte de minuterie globale? – Ohmnastrum

+0

J'ai cherché de la documentation, alors je pense que vous vouliez remplacer la boucle for par une minuterie, puis l'invalider quand une condition est remplie? – Ohmnastrum

+0

Cela semble excellent! Je n'ai pas mon mac sur moi pour le moment mais je vais certainement l'essayer ^^ – Ohmnastrum

0

Je soupçonne que je sais ce qui ne va pas, mais que je ne connais pas le «bon» problème, selon la façon dont vous voulez être. Ce qui se passe est simple - l'objectif C n'appelle pas les fonctions, il transmet les messages. Quand vous faites [self StrikeFrog] un message est placé sur une file d'attente à exécuter dès que la file d'attente peut être drainée; vous recevez probablement tous les messages à la fin parce que StrikeFrog ne reçoit pas d'appel avant le sommeil - il est appelé chaque fois que le fil de la file d'attente est débloqué. Dans une application à un seul thread, par exemple, l'effet net serait de dormir pendant (colorChoices.count) secondes puis d'exécuter tous les événements StrikeFrog après avoir quitté la boucle for, car c'est la première fois que la file d'attente d'événements peut envoyer vos événements En d'autres termes, tous les «appels de fonction» dans Obj C sont asynchrones, quel que soit le nombre de threads utilisés.

Je suggérerais soit de passer au niveau inférieur avec C ou de niveau supérieur avec CoreAnimation. Si aucun de ceux-ci ne vous convient, vous pouvez essayer NSObject performSelector:withObject:afterDelay: de mettre en file d'attente tout un tas d'événements qui seront exécutés après un certain délai. Cette méthode a beaucoup de problèmes que vous auriez à travailler, alors, faites attention.

+0

La suggestion de drawnonward est meilleure que performSelector - la minuterie vous permet de vous éloigner de la file d'attente des événements et de revenir plus tard pour placer l'événement suivant dans la file d'attente. – Matt