2009-04-09 6 views
2

Je dois exécuter ma boucle de jeu avec un timing très précis. J'essaie d'utiliser NSTimer pour faire cela, et j'obtiens des résultats corrects, mais il y a un peu de dérive. Lorsque NSTimer se déclenche, l'événement suivant commence à compter lorsque le gestionnaire termine ou commence-t-il à compter immédiatement. Si le premier est raisonnable pour moi d'utiliser setFireDate pour essayer de compenser le prochain tir de la minuterie - quand j'ai essayé, cela semblait pire.Utilisation de NSTimer pour obtenir des timings précis

Mon minuteur est réglé pour se déclencher toutes les 44ms et je voudrais l'empêcher de dériver de plus de 20ms. Si c'est le cas, j'aimerais le corriger pour le prochain incendie. Est-ce une chose raisonnable à faire avec NSTimer?

+0

20ms sur 44ms ne dérivent pas, ce qui est inexact. NSTImer devrait être beaucoup plus fiable que cela. –

+0

Je pense que ce que j'essayais de dire, c'est que je veux que la boucle de ma boucle ne dérive pas. D'après ce que je peux dire, le chronomètre commence son prochain chronométrage au moment où le gestionnaire sort, donc le temps semble être la valeur de la minuterie + le temps d'activité du jeu. – Ian1971

+0

Il n'est certainement pas censé dériver comme ça d'après la documentation (et j'ai trouvé que c'était vrai dans le passé quand j'ai écrit un simple tracker de souris). S'il dérive, vous devriez déposer un rapport de bug avec Apple. –

Répondre

4

Vous pouvez essayer de créer un thread et de planifier votre minuteur sur la boucle d'exécution de ce thread. Avoir cette minuterie comme seule chose sur cette boucle d'exécution devrait limiter le nombre de choses qui peuvent interférer avec elle.

Si cela ne fonctionne pas, eh bien, vous l'aurez déjà sur un thread, donc vous pouvez aussi bien passer à une boucle usleep().

+0

Je vais essayer ça.Il me faudra un certain temps avant de pouvoir faire un rapport si – Ian1971

+1

J'ai fini par utiliser [NSThread sleepForTimeInterval] et mach_absolute_time. Le moment est maintenant choisi. – Ian1971

5

Je ne pense pas que NSTimer vous donnera un timing "très" précis. Il se déclenche sur la boucle d'exécution, donc s'il est dans votre thread principal, il sera retardé par tout, des mises à jour de l'interface utilisateur à la gestion des événements.

+0

quand je dis très précis, je veux dire que je ne veux pas qu'il dérive de plus de 20 ms. ma minuterie tire toutes les 44ms, quand elle dérive, je voudrais corriger le tir suivant. En fait, je pense que je vais mettre à jour la question avec cette info – Ian1971

+1

Le document pour NSTimer dit que le timing est toujours basé sur l'intervalle d'origine à partir de quand il a commencé. Cela signifie qu'il ne devrait pas "dériver", mais il peut avoir "gigue". Le doc revendique également une résolution efficace de 50 - 100 ms. –

+0

Hmm ce n'est probablement pas une résolution assez précise pour moi. J'ai réussi à réduire la variance en ajustant la date de feu en fonction du temps écoulé depuis le dernier feu. Peut-être que j'ai besoin de regarder dans le temps de sommeil() mentionné par Peter Hosey. – Ian1971

1

également garder à l'esprit que la documentation NSTimer déclare:

En raison des différentes sources d'entrée d'une boucle d'exécution typique gère, la résolution effective de l'intervalle de temps une minuterie est limitée à le l'ordre de 50-100 millisecondes. Si un temps de mise à feu de minuterie se produit alors que la boucle d'exécution est dans un mode qui ne surveillance de la minuterie ou pendant une longue callout, la minuterie ne se déclenche pas avant la prochaine fois que la boucle d'exécution vérifie la minuterie . Par conséquent, l'heure réelle à que la minuterie déclenche peut être être une période de temps significative après le temps d'allumage programmé.

Questions connexes