游戏计时器 html,Html5游戏中的setInterval与setTimeout

在一些特殊的场景中我们可能会需要使用计时器,n秒后执行一段逻辑,或者循环执行一段逻辑。

这个时候我们可能首先想到的会是setInterval()或者setTimeout()两个方法。但是使用这两个方法可能会为我们的工程带来隐患。

记录如下代码片段:

setTimeout(()=>{

console.log("1")

},0)

console.log("2")

//打印结果

//2

//1

可能会有部分人和我会有同样的疑惑,为什么会先打印2。若有此疑问的同学还需要学习一下js的任务队列和调用栈。

setTimeout传入方法在什么时候执行会变得难以捉摸。所以为解决setTimeout所带来的隐患,需要自己实现相同功能的方法。

这里不考虑浏览器兼容的问题,用requestAnimationFrame来解决setTimeout的问题。

class Timer{

constructor(){

this.lastTime = 0;  //最后一次更新的时间

this.timeIndex = 0;

this.timeOutArr = [];   //setTimeout 实例的数组

}

update(timestamp){

if(this.lastTime == 0){

this.lastTime = timestamp;

}

let interval = timestamp - this.lastTime;   //上一帧到当前帧的时间间隔

this.lastTime = timestamp;  //更新时间

this.refreshTime(interval); //刷新setTimeout 的时间

}

refreshTime(interval){

let length = this.timeOutArr.length;

for(let i = length - 1;i>=0;i--){

let timeOut = this.timeOutArr[i];

timeOut.time -= interval;   //timeOut实例的剩余时间

if(timeOut.time <= 16){      //timeOut剩余时间不足1帧 可以立即执行

timeOut.func.call(timeOut.thisObj)     //调用回调方法

this.timeOutArr.splice(i,1) //移出回调方法

}

}

}

/**

* time秒后回调

* @param fun 要执行的回调方法

* @param thisObj 执行方法的作用域 避免出错

* @param time 在time秒后执行回调

*/

setTimeout(fun,thisObj,time){

let obj = {

function(){ //外汇常见问题 www.kaifx.cn/lists/question/

func:fun,

thisObj:thisObj,

time:time

}

this.timeOutArr.push(obj);

this.timeIndex++;

}

}

let timer = new Timer();

function update(timestamp){

timer.update(timestamp);

requestAnimationFrame(update)

}

requestAnimationFrame(update)

function test(){

console.time('timer timeout用时')

timer.setTimeout(()=>{

console.timeEnd('timer timeout用时') //获取setTimeout从创建到执行的时间

},this,2000)

console.time('window timeout用时')

setTimeout(() => {

console.timeEnd('window timeout用时')

}, 2000);

//打印结果

//windows timeout用时: 2001.82373046875ms

//timer timeout用时: 2004.0400390625ms

}

test();这里简单做了一个timer类,并实现了setTimeout的方法,每一帧都去刷新timer,并记录最后的刷新时间。

对实现的setTimeout方法和window的setTimeout做了个简单的比较,两者从创建到执行所用时间相差不大,经过多次测试window的setTimeout也没有我想象中那么准确。

总结:游戏项目中避免使用window的setTimeout和setInterval方法,若有需要应使用requestAnimationFrame去实现相关方法,将回调控制在了每帧的刷新中。

ps:类似的H5引擎,egret也有自己实现setTimeout方法,想必一方面也是因为浏览器setTimeout存在不确定的因素吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值