我正在使用 Electron.js 使用 JavaScript 开发游戏。我使用 HTML
<canvas>
元素和 2d
上下文作为渲染器。在某些时候,我注意到游戏运行速度非常慢(低于 30 FPS)。
每一帧,一段代码由
requestAnimationFrame()
运行。我通过探查器运行它,结果表明我的代码很好(每帧大约需要 2 毫秒) 并且页面重绘所需的时间比我预期的要长得多(有时每次绘制超过 30 毫秒)。
由于游戏渲染器太复杂,我无法提供完整的示例,但这是我的一些代码:
// Set up the canvas
let r = document.getElementById("render");
let ctx = r.getContext("2d", {
alpha:0,
willReadFrequently:true
});
// Set up offscreen canvas
let offR = new OffscreenCanvas(1920, 1080);
let offCtx = offR.getContext("2d", {
willReadFrequently: true
});
// Set canvas size
r.width = 1920;
r.height = 1080;
function drawVoxes() {
for(let vx of voxes) {
// If not empty, draw its texture
if(vx.value != 0) {
offCtx.drawImage( dataobj.textures.tiles[vx.value - 1], vx.rX, vx.rY, vx.width, vx.height );
}
}
}
function renderFrame() {
// fpsTicker.tick();
// Clear canvases
ctx.clearRect(0, 0, r.width, r.height);
offCtx.clearRect(0, 0, r.width, r.height);
// Draw background
ctx.drawImage(buf, 0, 0);
// Draw grid
drawVoxes();
// Apply to the main canvas
ctx.drawImage(offR, 0, 0);
// Set up for the next frame
requestAnimationFrame(renderFrame);
}
requestAnimationFrame(renderFrame);
buf
是一个 OffscreenCanvas
对象,voxes
是自定义辅助对象的数组,dataobj
是一个存储所有地图数据的对象。我希望这个例子足以让你理解。
为什么会出现这种情况?正常吗?我能做些什么来减少绘画时间?
编辑:屏幕上唯一的元素是用于渲染的单个
<canvas>
。
禁用
willReadFrequently
解决了问题,并且绘画不再需要 30 毫秒。