引入概念:requestAnimationFrame
帧
更新和渲染的抽离
经过上一节的操作,我们已经得到了一只演员鸟
众所周知,现在的游戏玩家都鬼的很,游戏没个高帧率他都不玩。
一般人游戏30帧就感觉比较流畅,可是这群游戏玩家,非要60帧才看着舒服
一、概念解释,什么是帧
帧率表示视频、游戏每秒钟刷新画面的次数
60帧即每秒钟刷新60次画面
一般电影的帧率是23.97frame/s,而游戏,低于45帧,会感到明显卡顿
为什么电影只需要24帧就比较流畅呢?
是因为摄影机记录的是1/24秒的所有光线信息,可以理解电影是无数张快门时间是1/24秒的照片同步播放组成的
而游戏计算出来的只有那一瞬间的画面,没有一个时间段内的光线信息,所以需要更高的帧率
因此我们就知道了我们的游戏需要高帧率的重要性了
二、requestAnimationFrame
理解了什么是帧就得出来,一个游戏60帧,每帧的时间是,1/60,约等于16.667ms;
我们大可以把setInterval
的延时改成16.667
但是,众所周知,浏览器提供的延时函数都不靠谱,我们无法通过它得到稳定了60帧画面
隆重的介绍 requestAnimationFrame
requestAnimationFrame详解
被誉为神器的requestAnimationFrame
这个是一个浏览器给我们提供的API
借助这个API我们可以在浏览器这个平台很好的控制每秒60帧的帧率
接下来我们将数据更新和渲染更新拆分为两个函数
/**
* 计算Bird的位置(数据更新)
*/
function update() {
// 计算新的top
if (pos.top !== clickPos.top) {
const dis = clickPos.top - pos.top; // 计算差值
const dir = dis > 0 ? 1 : -1; // 计算在top上移动的方向 1 正向移动 或 -1 反向移动;
// 如果速度过快,本次移动直接过头了(即差值<速度),就直接移动到指定top
if (Math.abs(dis) < speed) {
pos.top = clickPos.top;
} else {
pos.top = pos.top + dir * speed; // 计算新的top,新的位置 = 之前的位置 + 方向 * 速度
}
}
// 用相同的方式计算left
if (pos.left !== clickPos.left) {
const dis = clickPos.left - pos.left;
const dir = dis > 0 ? 1 : -1;
if (Math.abs(dis) < speed) {
pos.left = clickPos.left;
} else {
pos.left = pos.left + dir * speed;
}
}
}
/**
* 更新显示对象位置(渲染)
*/
function render() {
bird.style.top = pos.top + "px";
bird.style.left = pos.left + "px";
}
然后用requestAnimationFrame
来创建一个主循环,在主循环中依次调用这两个函数
function loop() {
requestAnimationFrame(loop); // 循环调用requestAnimationFrame
update(); // 先数据更新
render(); // 后渲染更新
}
loop();
再次运行案例,我们得到了更流畅,性能更高的Bird了