Javascript requestAnimationFrame游戏循环运行无画面显示问题如何修复
问题根因与修复方案
错误原因
你的写法存在核心逻辑错误:setTimeout(window.requestAnimationFrame(eachFrame), 1000 / fps) 中,window.requestAnimationFrame(eachFrame) 会被立即执行,而非作为回调延迟触发。这就导致你的渲染循环会以远高于预期的速度疯狂执行:清屏→更新位置→渲染→立刻触发下一次循环清屏,渲染出的内容存在时间过短,人眼完全无法捕捉,最终表现就是屏幕全白。
另外你混淆了API的用法:requestAnimationFrame 本身会跟随浏览器的刷新频率(通常为60次/秒)调度回调,不需要额外嵌套setTimeout,这种套写本身就是错误用法。
修复方案
方案1:默认使用浏览器原生帧率(推荐,无闪烁)
直接移除多余的setTimeout包裹即可,原生requestAnimationFrame的调度机制本身就能避免setInterval导致的闪烁问题:
function eachFrame(){ ctx.clearRect(0,0,canvas.width,canvas.height); player.motion(); player.render(); window.requestAnimationFrame(eachFrame); }; window.requestAnimationFrame(eachFrame);
方案2:需要自定义固定帧率
如果你确实需要限制渲染帧率,可通过时间差控制帧执行时机:
let lastRenderTime = 0; const expectedFps = 30; // 替换为你需要的帧率 const frameInterval = 1000 / expectedFps; function eachFrame(currentTime){ // 距离上一次渲染的间隔达到预期帧间隔时才执行渲染 if (currentTime - lastRenderTime >= frameInterval) { lastRenderTime = currentTime - ((currentTime - lastRenderTime) % frameInterval); ctx.clearRect(0,0,canvas.width,canvas.height); player.motion(); player.render(); } window.requestAnimationFrame(eachFrame); }; window.requestAnimationFrame(eachFrame);
补充说明
你注释ctx.clearRect后能看到移动轨迹,是因为没有清屏操作的情况下,每次渲染的内容都会叠加保留在画布上,就算循环执行速度再快,内容也会累计,因此可以看到移动效果,但也会产生轨迹残留。
内容的提问来源于stack exchange,提问作者Stephen Witwick
相关产品推荐
相关产品推荐

