2010-06-28 16 views
6

Ich habe eine Funktion, die das nächste Bild in einer Animation von verschiedenen Objekten auf der X- und Y-Achse berechnet [Ich nenne es frameRender()] und eine Funktion, die das resultierende Bild auf die Objekte anwendet [Ich nenne das frameDisplay()]. Die Objekte bewegen sich nicht nur von Punkt A nach B, sie bewegen sich ständig und erhalten immer neue Zielkoordinaten. Ich benutze ein setInterval() mit einem 1000/frameRate Intervall, aber das scheint überhaupt nicht zu funktionieren, da Browser keine genauen Timings haben.Wie kann ich eine JavaScript-Animation in allen Browsern auf allen Systemen mit derselben Geschwindigkeit wiedergeben?

Die Frage ist: Wie kann ich sicherstellen, dass die Animation eine konstante Bildrate hat und auf allen Systemen mit der gleichen Geschwindigkeit auf allen Browsern läuft? Ich habe alles ausprobiert und kann nicht einmal bei verschiedenen Browsern ein genaues Ergebnis erzielen (ich teste Firefox und Chrome, Chrome zeigt normalerweise viel schneller an).

Das Ergebnis sollte sein: Wenn es langsam spielt, sollte das Animationsintervall zunächst abnehmen und dann versuchen, einige Frames zu überspringen [durch Überspringen frameDisplay()], wenn es das DOM langsam anzeigt, bis es richtig abgespielt wird. Wenn es schnell abgespielt wird, sollte das Animationsintervall zunehmen, sodass die Animation mit der richtigen Geschwindigkeit abgespielt wird.

Aber wie halten Sie Konsistenz in all dem, da Sie nicht immer sicher sein können, wenn die Browser langsam werden oder wenn sie schnell arbeiten. Zum Beispiel, wenn es eine riesige Spitze von Bewegungen gibt, und wir das Intervall verringern, um die Bildrate stabil zu halten, und plötzlich die meisten sich bewegenden Objekte stoppen oder sich nicht viel bewegen, wird es plötzlich sehr schnell funktionieren!

Irgendwelche Ideen?

Antwort

3

Die Antwort is here, ein großartiger Artikel von Glenn Fiedler, braucht ein wenig zwicken, um es in Javascript zu konvertieren, aber die Prinzipien sind die gleichen. Grundsätzlich müssen Sie einen Akkumulator verwenden, der Delta-Timings addiert, und darauf basierende Schritte ausführen. Keine Notwendigkeit, irgendwelche Physik Mathe oder irgendetwas zu ändern, die Lösung ist Plug n Play. Es hat auch einen coolen Interpolator, der das Stottern entfernt und auch superglatte Bewegungen ermöglicht (für Replays usw.). Es ist fantastisch, arbeitet für die Physik und sollte an jeder schrittbasierten Bewegung arbeiten. Im Grunde ist alles, was Sie für genaues Timing Spiel Bewegung brauchen.

7

Die Frage ist: Wie kann ich sicherstellen, dass die Animation eine konstante Bildrate hat und auf allen Systemen mit der gleichen Geschwindigkeit auf allen Browsern läuft?

Sie können nichts über die Framerate machen. Das einzige, was Sie steuern können, ist, wie Ihre Anwendungsaktualisierungen basierend auf der Zeit abgelaufen sind. Dies gilt auch außerhalb von Browsern und ein häufiges Thema in der Spieleentwicklung.

Die beste Sache zu tun ist, das Delta (gelesen: Zeitunterschied) zwischen Updates zu verfolgen.

(function() { 
    function getTime() { 
     return new Date().getTime(); 
    } 
    var last = getTime(); 

    function update(delta) { 
     // Update your application state on delta (ms of time passed) 
    } 

    (function loop() { 
     update(last = getTime()-last); 
     render(); 
     setTimeout(loop, 20); // 20 = attempt 50fps 
    }()); 
}()); 

Beachten Sie die Verwendung von setTimeout hier. Dies verhindert, dass loop() nicht mehr synchron ist. setInterval wird auch dann feuern, wenn ein vorheriger Anruf nicht beendet wurde.

+0

Also im Grunde meinst du ich sollte die Frame-Rendering-Mathematik ändern, um eine Delta-Variable zu enthalten, so kann ich zum Beispiel das Objekt mehr oder weniger X Y Pixel basierend auf der vergangenen Zeit übergeben? – stagas

+0

@stagas - genau. Wenn also ein Update innerhalb von 50ms und das andere bei 450ms ist, sollte Ihre Anwendung immer noch auf der "500ms-Marke" stehen, wenn Sie verstehen, was ich meine. – Matt

+0

Cool, versuchen Sie es sofort danke – stagas

2

Sie können Ihre Animation mit der Systemzeit synchronisieren.

Aktuelle Systemzeit in Variable speichern. Auf allen Frames, die Sie dann neu zeichnen möchten, überprüfen Sie, ob die aktuelle Zeit - Ihre Variable einige Delta-Zeit entspricht. Verkleinere dann deine Animation. else warte diesen unterschied

Verwandte Themen