我尝试编写一个等距瓷砖游戏引擎,并且对此代码的速度有问题:
$(function() {
var canvas = document.getElementById('GameCanvas');
var context = document.getElementById('GameCanvas').getContext('2d');
var imgObj = new Image();
imgObj.src = 'img/sand_surface.png';
var Game = {
tileScaleX: 64,
tileScaleY: 32,
FPSLimit: 50, // max allowed framerate
realFPS: 0, // real framerate
init: function() {
this.cycle(); // main animation loop
},
cycle: function() {
this.debug(); // print framerate
startTime = new Date; // start fps time
this.clear(); // celar canvas
this.draw(); // draw frame
endTime = new Date; // end fps time
setTimeout(function() {
endTimeWithSleep = new Date; // end fps time with sleep
this.realFPS = 1000 / (endTimeWithSleep - startTime);
this.cycle(); // repeat animation loop
}.bind(this), (1000 / this.FPSLimit) - (endTime - startTime));
},
debug: function() {
$('.DebugScreen').html('<b>FPS:</b> ' + Math.round(this.realFPS*1)/1);
},
clear: function() {
canvas.width = canvas.width; // clear canvas
},
draw: function() {
Location.drawSurface(); // draw tiles
},
}
var Location = {
width: 60,
height: 120,
drawSurface: function() {
for (y = 0; y < this.height; y++) {
for (x = 0; x < this.width; x++) {
if ((y % 2) == 0) {
rowLeftPadding = 0;
} else {
rowLeftPadding = Game.tileScaleX / 2;
}
context.drawImage(imgObj, (x * Game.tileScaleX + rowLeftPadding), y * (Game.tileScaleY / 2), Game.tileScaleX, Game.tileScaleY);
}
}
},
}
Game.init(); // start game
});
如果我将Location.width和Location.height设置为较低的数字,那么它会快速运行(50 fps),但在此示例中(Location.width = 60
,Location.height = 120
)帧速率为10 fps,我需要50 fps,你有什么方法可以加快这个脚本的速度吗?
答案 0 :(得分:5)
1)我觉得你正在绘制每一块瓷砖,即使它们不在视野中。使用“剪裁”。在调用context.drawImage()
之前,您需要计算图块是否在视图中。
2)如果您的风景是静态的,请尽可能预先计算。然而,创建一个巨大的图像也不是一个好主意,你宁愿预先计算一些大块(即512x512)。
3)在某些浏览器中,如果不使用'setTimeout()'而使用requestAnimationFrame(我也发现this article非常有趣),可以说你可以获得更好的帧速率。
4)调整大小/缩放可能会影响性能(特别是在较旧的浏览器或硬件中)。如果你的图块已经是32x64,你可以使用只有3个参数的drawImage(),避免调整大小(如果你需要缩放以实现缩放效果或类似效果,则不适用)。
答案 1 :(得分:0)
在我的代码中弄乱你的代码后,我发布的代码在45-50之间。一个建议是不使用jQuery,也不要修改元素的html
来显示fps。我还将您的演示修改为最大100帧,并且大约达到70帧/秒。
您还可以尝试缓存已调整大小的图像并使用它,您应该会看到性能提升。在下面的演示中,我将调整大小的图像缓存在临时画布上,然后使用它。
Live Demo (我不想为图片实现onload
,所以如果它的白色屏幕再次点击运行了)
答案 2 :(得分:0)
除了@jjmontes优秀的答案外,您还应该在游戏中使用多个画布元素,并且只更新画布中已更改的部分。现在你每次都清理并重新绘制所有内容。