23 Stimmen

Gibt es eine bessere Möglichkeit, eine Spielschleife auf dem iPhone zu erstellen, als NSTimer zu verwenden?

Ich programmiere gerade ein Spiel für das iPhone. Derzeit verwende ich NSTimer, um die Aktualisierung/Rendering des Spiels auszulösen. Das Problem dabei ist, dass (nach Profiling) Ich scheine eine Menge Zeit zwischen Updates/Renderer zu verlieren und dies scheint vor allem mit dem Zeitintervall zu tun, die ich in NSTimer stecken.

Meine Frage ist also: Was ist die beste Alternative zu NSTimer?

Bitte eine Alternative pro Antwort.

18voto

zoul Punkte 99332

Sie können eine bessere Leistung mit Threads erhalten, versuchen Sie etwas wie dies:

- (void) gameLoop
{
    while (running)
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [self renderFrame];
        [pool release];
    }
}

- (void) startLoop
{
    running = YES;
#ifdef THREADED_ANIMATION
    [NSThread detachNewThreadSelector:@selector(gameLoop)
    toTarget:self withObject:nil];
#else
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0f/60
    target:self selector:@selector(renderFrame) userInfo:nil repeats:YES];
#endif
}

- (void) stopLoop
{
    [timer invalidate];
    running = NO;
}

In der renderFrame Methode Sie bereiten den Framebuffer vor, zeichnen den Frame und präsentieren den Framebuffer auf dem Bildschirm. (P.S. Es gibt eine großartige Artikel über verschiedene Arten von Spielschleifen und ihre Vor- und Nachteile).

4voto

Galghamon Punkte 1982

Ich kenne mich mit dem iPhone nicht besonders aus, aber vielleicht kann ich trotzdem helfen: Anstatt einfach eine feste Verzögerung am Ende der Schleife einzubauen, können Sie folgendes verwenden:

  • Legen Sie ein Aktualisierungsintervall fest, mit dem Sie zufrieden sind und das größer ist als ein einziger Durchlauf durch Ihre Hauptschleife.
  • Nehmen Sie zu Beginn der Schleife einen aktuellen Zeitstempel in der Ihnen zur Verfügung stehenden Auflösung und speichern Sie ihn.
  • Am Ende der Schleife nehmen Sie einen weiteren Zeitstempel und ermitteln die seit dem letzten Zeitstempel verstrichene Zeit (initialisieren Sie dies vor der Schleife).
  • sleep/delay für die Differenz zwischen Ihrer idealen Frame-Zeit und der bereits verstrichenen Zeit für den Frame.
  • Beim nächsten Bild können Sie sogar versuchen, Ungenauigkeiten im Schlafintervall durch einen Vergleich mit dem Zeitstempel zu Beginn der vorherigen Schleife auszugleichen. Speichern Sie die Differenz und addieren/subtrahieren Sie sie vom Schlafintervall am Ende dieser Schleife (Schlaf/Verzögerung kann zu lang ODER zu kurz werden).

Vielleicht sollten Sie einen Warnmechanismus einrichten, der Sie darauf hinweist, wenn Ihr Timing zu knapp bemessen ist (d.h. wenn Ihre Schlafzeit nach dem Kompensieren weniger als 0 beträgt, was bedeuten würde, dass Sie mehr Zeit für die Verarbeitung benötigen, als Ihre Framerate erlaubt). Die Folge ist, dass sich Ihr Spiel verlangsamt. Wenn Sie dies feststellen, sollten Sie das Rendering eine Zeit lang vereinfachen, bis Sie wieder genügend freie Kapazitäten haben.

0voto

scriba Punkte 97

Benutzen Sie CADisplayLink, Sie finden die Anleitung im OpenGL ES Template Projekt, das in XCODE zur Verfügung gestellt wird (erstellen Sie ein Projekt ausgehend von diesem Template und schauen Sie sich die EAGLView Klasse an, dieses Beispiel basiert auf Open GL, aber Sie können CADisplayLink nur für andere Arten von Spielen benutzen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X