简体   繁体   English

定时事件和requestAnimationFrame游戏循环

[英]Timed events and requestAnimationFrame game loop

I'm working on a game in JavaScript, and I have a game loop setup with requestAnimationFrame : 我正在使用JavaScript开发游戏,并且使用requestAnimationFrame设置了游戏循环:

loop: function () {

    game.updateSomething();

    if (game.running) {
        game.tick++;
        requestAnimationFrame(game.loop);
    }
},

My game has a working loop and I am able to move objects around, that's all good, however if I want to limit an action inside this loop to every second for example, how can I achieve this? 我的游戏有一个工作循环,我可以移动对象,这一切都很好,但是,例如,如果我想将此循环内的动作限制为每秒,那么如何实现呢? Do I have to take note of the time for every tick with new Date() , then compare it to the time I calculated on the previous loop generation, and test the difference? 我是否需要使用new Date()记下每个刻度的时间,然后将其与上一次循环生成的时间进行比较,并测试差异? Like this: 像这样:

latest: null,

loop: function () {

    var last = this.latest;
    this.latest = new Date().getTime();
    var every = 200;

    if (Math.floor(last/every) != Math.floor(this.latest/every)) {
        console.log('do something');
        game.updateSomething();
    };

    if (game.running) {
        game.tick++;
        requestAnimationFrame(game.loop);
    }
},

This seems really messy, even if I wrap this up in a function that returns true when the floored time is different on that tick, it just doesn't feel right... I tried googling but I couldn't find anything that addressed this specifically. 这看起来真的很混乱,即使我将其包装在一个函数中,当该时间间隔的下限时间不同时返回true时,也感觉不对...我尝试使用谷歌搜索,但找不到任何可解决此问题的方法特别。

How do other JavaScript games handle something that needs to happen on a regular interval, that also resides in the main game loop? 其他JavaScript游戏如何处理需要定期发生且又驻留在主游戏循环中的内容?

From MDN : MDN

The callback method is passed a single argument, a DOMHighResTimeStamp, which indicates the time, in miliseconds but with a minimal precision of 10 µs, at which the repaint is scheduled to occur. 回调方法被传递给单个参数DOMHighResTimeStamp,该参数以毫秒为单位指示时间,以毫秒为单位,但最小精度为10 µs,在该时间点计划进行重新绘制。

The said time stamp could be used to measure time between raf calls, just what you need: 所说的时间戳可用于测量raf两次呼叫之间的时间,正是您所需要的:

var last = sec = dev = 0,
    every = 1000;

var cycle = function (stamp) {
    if (stamp - last >= every - dev) {
        last = stamp;
        sec++;
        dev = last - sec * every;
        console.log(sec+" sec, deviation: " + dev);
    }
    requestAnimationFrame(cycle);
};

requestAnimationFrame(cycle);

Console output: 控制台输出:

[13:09:55.790] "1 sec, deviation: 14"
[13:09:56.786] "2 sec, deviation: 12"
[13:09:57.782] "3 sec, deviation: 10"
[13:09:58.779] "4 sec, deviation: 9.000000000000455"
[13:09:59.777] "5 sec, deviation: 7"
[13:10:00.776] "6 sec, deviation: 6"
[13:10:01.773] "7 sec, deviation: 4"
[13:10:02.773] "8 sec, deviation: 3"
[13:10:03.773] "9 sec, deviation: 1"
[13:10:04.787] "10 sec, deviation: 15"
[13:10:05.786] "11 sec, deviation: 13"

Example fiddle . 小提琴的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM