2017-02-03 10 views
-2

Я пишу карточную игру, поэтому мне нужно настроить базовый игровой цикл, используя window.requestAnimationFrame. Мне нужно сделать fps установленным до 30 кадров в секунду, и поскольку это медленная карточная игра, мне просто нужен простой игровой цикл. Мой игровой цикл выглядит следующим образом.Простой игровой цикл 30fps в javascript с использованием requestAnimationFrame?

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

      update(progress) 
      draw() 

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

Как я могу сделать так, чтобы значение fps было равным 30fps? Я ценю любую помощь! Благодаря!

+0

Пожалуйста, взгляните на эту тему: http://stackoverflow.com/questions/19764018/controlling-fps-with-requestanimationframe – mrmnmly

+0

Почему это должно быть 30 кадров в секунду?Трюк с 'requestAnimationFrame' заключается в том, что он всегда дает лучшую частоту кадров любому монитору, поэтому ограничение до 30 кадров в секунду кажется странным. –

+0

@ EmilS.Jørgensen ok спасибо! оказывается, что приведенный выше код в порядке. Он дает 60 кадров в секунду в моей системе, и я думаю, что это нормально для игр. – kofhearts

ответ

0

кадров: кадров в секунду

1000/30 = 30 кадров в секунду

пытаются основной

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

Вы должны держать simulating и drawing отдельно.

Ниже приведен пример, где я делаю simulation каждую миллисекунду (1000 раз в секунду). Каждое симуляция отменяет предыдущий запрос для кадра анимации.

Если обновление браузера «галочкой», у него будет drawn наше обновление (с шагом нашего счетчика).

через 1 секунду я останавливаюсь, и мы должны увидеть приблизительно ваши частоты обновления мониторов, как наш count.

//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);

Edit - Почему разделение задач

рисунок на холсте является дорогостоящей операцией, которую вы обычно не хотите работать на каждом кадре, если вы можете избежать ,

В основном требуется только перерисовать, когда что-то меняется.

В моем примере ниже я создать большое количество коробок, моделировать их и сделать их:

//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);

Обратите внимание, как моделировать их в путь быстрее, чем рисовать их.

Как правило, у вас есть только 1000/60 ~ 16 миллисекунд между каждым фреймом, поэтому, если мы сможем сэкономить миллисекунды, то мы с радостью сделаем это и сконцентрируем время вычисления таких кадров на больших операциях (например, или обнаружение столкновения или все, что было бы тяжело в вашей игре).

Таким образом, мы также можем запустить наше моделирование с другой скоростью, чем коэффициент вытягивания, что удобно при работе с асинхронными задачами.

+1

Можете ли вы подробнее рассказать о том, почему симуляция и рисование должны храниться отдельно, а не вместе, как в моем примере выше? Благодаря! – kofhearts

 Смежные вопросы

  • Нет связанных вопросов^_^