2017-02-03 3 views
-2

Ich schreibe ein Kartenspiel, also muss ich eine grundlegende Spielschleife mit window.requestAnimationFrame einrichten. Ich muss die fps auf 30fps setzen und da es ein langsames Kartenspiel ist, brauche ich nur eine einfache Spielschleife. Meine Spielschleife ist wie folgt.Eine einfache 30fps Spielschleife in Javascript mit requestAnimationFrame?

function loop(timestamp) { 
      var progress = timestamp - lastRender 

      update(progress) 
      draw() 

      lastRender = timestamp 
      window.requestAnimationFrame(loop) 
     } 
     var lastRender = 0 
     window.requestAnimationFrame(loop) 

Wie kann ich es so machen, dass die fps auf 30fps eingestellt ist? Ich schätze jede Hilfe! Vielen Dank!

+0

Bitte werfen Sie einen Blick auf diesen Thread: http://StackOverflow.com/Questions/19764018/Controlling-FPs-With-RequestAnimationframe – mrmnmly

+0

Warum muss es 30 fps sein?Der Trick mit 'requestAnimationFrame' besteht darin, dass es immer die bestmögliche Bildwiederholfrequenz für jeden Monitor bietet, so dass die Beschränkung auf 30 fps seltsam erscheint. –

+0

@ EmilS.Jørgensen ok danke! Es stellt sich heraus, dass der obige Code in Ordnung ist. Es gibt 60 fps in meinem System und ich denke, das ist gut für Spiele. – kofhearts

Antwort

0

fps: Bild pro Sekunde

1000/30 = 30 fps

versuchen Grund

`function animate() { 
    setTimeout(function() { 
    requestAnimationFrame(animate); 
    }, 1000/30); 
}` 
-1

sollten Sie halten simulating und drawing getrennt.

Unten ist ein Beispiel wo ich eine simulation jede Millisekunde (1000 mal in einer Sekunde) mache. Jede Simulation löscht die vorherige Anforderung eines Animationsrahmens.

Wenn die Aktualisierung des Browsers "angekreuzt" ist, wird es drawn unser Update (inkrementiert unseren Zähler) haben.

nach 1 Sekunde stoppe ich und wir sollten ungefähr Ihre Bildwiederholfrequenz als unsere count sehen.

//counter 
 
var count = 0; 
 
//draw function 
 
function draw() { 
 
    count++; 
 
    } 
 
    //Animation frame handle 
 
var animationFramHandle; 
 
//Run every millisecond 
 
var interval = setInterval(function() { 
 
    //Cancel requestAnimationFrame 
 
    cancelAnimationFrame(animationFramHandle); 
 
    //request new requestAnimationFrame 
 
    animationFramHandle = requestAnimationFrame(draw); 
 
}, 1); 
 
//Wait 1 second 
 
setTimeout(function() { 
 
    //Stop simulation 
 
    clearInterval(interval); 
 
    cancelAnimationFrame(animationFramHandle); 
 
    console.log("ticks in a second:", count); 
 
}, 1000);

Bearbeiten - Warum Trennung von Bedenken

auf der Leinwand Zeichnung ist eine teuere Operation, die Sie normalerweise nicht in jedem Frame ausgeführt werden möchten, wenn Sie es vermeiden können .

Im Grunde nur für ein Neuzeichnen aufrufen, wenn sich etwas ändert.

In meinem Beispiel unten ich eine große Menge von Boxen erstellen, simulieren sie und ziehen sie:

//DOM elements 
 
var canvas = document.createElement("canvas"); 
 
canvas.width = 400; 
 
canvas.height = 400; 
 
document.body.appendChild(canvas); 
 
var ctx = canvas.getContext("2d"); 
 
ctx.fillStyle = "rgba(0,0,0,0.1)"; 
 
var drawNode = document.createElement("p"); 
 
document.body.appendChild(drawNode); 
 
//Variables 
 
var simulations = 0; 
 
var simulationTime = 0; 
 
var requestAnimationFrameHandle; 
 
//Boxes to simulate and draw 
 
var boxes = []; 
 
while (boxes.length < 10000) { 
 
    boxes.push({ 
 
     x: Math.random() * canvas.width, 
 
     y: Math.random() * canvas.height, 
 
     s: 5 
 
    }); 
 
} 
 
//Draw function 
 
function draw() { 
 
    var t = Date.now(); 
 
    //Clear 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    //Draw 
 
    for (var bIndex = 0; bIndex < boxes.length; bIndex++) { 
 
     var box = boxes[bIndex]; 
 
     ctx.fillRect(box.x, box.y, box.s, box.s); 
 
    } 
 
    //Log 
 
    drawNode.innerHTML = ("New draw after " + simulations + " simulations<br>Drawing took " + (Date.now() - t) + " ms<br>Simulation time is " + simulationTime + " ms"); 
 
    simulations = 0; 
 
} 
 
//Simulate function 
 
function simulate(force) { 
 
    if (force === void 0) { force = false; } 
 
    simulations++; 
 
    if (Math.random() * 1000 > 800) { 
 
     var t = Date.now(); 
 
     for (var bIndex = 0; bIndex < boxes.length; bIndex++) { 
 
      var box = boxes[bIndex]; 
 
      box.x = Math.abs(box.x + (Math.random() * 3 - 1)) % canvas.width; 
 
      box.y = Math.abs(box.y + (Math.random() * 3 - 1)) % canvas.height; 
 
     } 
 
     simulationTime = Date.now() - t; 
 
     cancelAnimationFrame(requestAnimationFrameHandle); 
 
     requestAnimationFrameHandle = requestAnimationFrame(draw); 
 
    } 
 
} 
 
setInterval(simulate, 1000/120);

Beachten Sie, wie als sie ist viel schneller zu simulieren sie zeichnen. Als Faustregel gilt, dass Sie nur 1000/60 ~ 16 Millisekunden zwischen jedem Frame haben. Wenn wir also die Millisekunden einer Ziehung ersparen könnten, würden wir dies gerne tun und eine solche Frame-Berechnungszeit auf größere Operationen konzentrieren (wie Pfadfindung) oder Kollisionserkennung oder was auch immer in Ihrem Spiel schwer sein würde).

Auf diese Weise können wir unsere Simulation auch mit einer anderen Rate als der Ziehgeschwindigkeit ausführen, was praktisch ist, wenn mit asynchronen Aufgaben gearbeitet wird.

+1

Kannst du ein bisschen mehr darüber machen, warum Simulieren und Zeichnen eher getrennt bleiben sollten als zusammen in meinem Beispiel? Vielen Dank! – kofhearts

Verwandte Themen