我正试图从画布游戏中挤出最后一点性能;最近我发现清理画布的性能很重,所以我试图找到一种方法来替换每一帧清除整个画布。但是我发现我正在尝试的新方法存在一些问题,即分别清除每个对象的边界框,然后更新它们。
问题是元素在离开画布时会“留下”,图像的某些部分仍然存在。我尝试简化代码以确保问题不在代码的其余部分而且没有快乐。
返回擦拭整个画布的每一帧也是不合适的,特别是因为这种新方法要快得多。这是代码(出于某种原因,它不能用作fiddle)。
var enemyCtx = document.getElementById('enemy').getContext('2d');
var game =
{
w: 800,
h: 500
};
var enemies = [];
window.addEventListener('load', function()
{
for (var i = 0; i < 200; i++)
{
enemies[enemies.length] = new Enemy();
}
update();
}, false);
var buffer = document.createElement('canvas');
buffer.width = 42;
buffer.height = 42;
var bufferCtx = buffer.getContext('2d');
drawEnemy(bufferCtx, 5, 5, 32, 32, 'red');
function update()
{
for (var i = 0; i < enemies.length; i++)
{
enemyCtx.clearRect( enemies[i].x,
enemies[i].y,
enemies[i].x + enemies[i].width,
enemies[i].y + enemies[i].height);
}
for (var i = 0; i < enemies.length; i++)
{
enemies[i].x-=5;
enemyCtx.drawImage(buffer, enemies[i].x-5, enemies[i].y-5);
}
requestAnimationFrame(update);
}
function drawEnemy(ctx, x, y, width, height, colour)
{
ctx.lineWidth = 1;
ctx.strokeStyle = colour;
ctx.strokeRect(x + 0.5, y + 0.5, width, height);
}
function Enemy()
{
this.x = Math.random()*game.w;
this.y = Math.random()*game.h;
this.width = 32;
this.height = 32;
}
(function()
{
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x)
{
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) window.requestAnimationFrame = function(callback, element)
{
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function()
{
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id)
{
clearTimeout(id);
};
}());
&安培; HTML:
<canvas id="enemy" width="800" height="500"></canvas>
你们能给我的任何见解都会非常有用;谢谢!
答案 0 :(得分:1)
对此有了更多的考虑,我想出了一个解决方案;也许这对你们来说可能有些好处。
基本上,图像是留在&#39;在画布上,因为clearRect()方法需要使用实际的画布坐标。因为图像正在离开画布,所以它的坐标将是负值。
function update()
{
for (var i = 0; i < enemies.length; i++)
{
lx = (enemies[i].x > 0) ? enemies[i].x : 0;
ly = (enemies[i].y > 0) ? enemies[i].y : 0;
enemyCtx.clearRect( lx,
ly,
lx + enemies[i].width + 1,
ly + enemies[i].height + 1);
}
// ...
}
宽度的附加值是停止画布绘制图像的最后一个像素列,因为它正在被删除。希望这会有所帮助。