我正在尝试使用HTML5画布制作Pong克隆。我想在比赛场地中间画一条虚线,就像原来的乒乓球一样。我这样做是通过扩展CanvasRenderingContext2D
对象,如David Geary's优秀书中所示:
CanvasRenderingContext2D.prototype.dashedLine = function (x1, y1, x2, y2, dashLength) {
dashLength = dashLength === undefined ? 5 : dashLength;
var deltaX = x2 - x1;
var deltaY = y2 - y1;
var numDashes = Math.floor(
Math.sqrt(deltaX * deltaX + deltaY * deltaY) / dashLength);
for (var i=0; i < numDashes; ++i) {
context[ i % 2 === 0 ? 'moveTo' : 'lineTo' ]
(x1 + (deltaX / numDashes) * i, y1 + (deltaY / numDashes) * i);
}
然后我有一个render()
函数实际上在画布上进行所有渲染元素的调用。其中包括我的renderBackground()
函数,它为背景着色并绘制虚线:
function render() {
ctx.clearRect(0, 0, cWidth, cHeight);
renderBackground();
// Rest removed for brevity
}
function renderBackground() {
ctx.lineWidth = 5;
ctx.strokeStyle = '#FFFFFF';
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, cWidth, cHeight);
ctx.dashedLine(0, 0, 0, cHeight, 10);
ctx.stroke()
}
然后在最后我有一个名为animLoop()
的函数实际调用render()
函数并使用requestAnimationFrame()
来获得更流畅的动画:
function animLoop() {
render();
requestAnimationFrame(animLoop);
}
window.requestAnimationFrame = (function() {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
}
);
})();
如果我让我的游戏运行超过30秒,它就会开始急剧减速到无法播放的程度,浏览器的CPU使用率在Firefox和Chrome上都会徘徊134%左右。只有当我渲染虚线时才会出现缓慢的情况。我不确定会发生什么,但下面我还通过Chrome Inspectors探查器运行了我的代码并获取以下内容:
我的renderBackground()
功能仅占用了0.46%的CPU时间。此外,我不确定(program)
应该表示什么。关于什么可能导致缓慢的任何想法?
此外,您可以在我的Github repo上查看到目前为止的完整代码。
答案 0 :(得分:2)
每次调用ctx.dashedLine
时,您都会在默认路径上累积lineTo的所有调用,并且自应用程序启动以来,调用笔划将描述路径中的所有行。因为您正在运行动画,所以在每帧调用笔划时,路径将快速绘制很多行。
在ctx.beginPath()
之前添加ctx.dashedLine
以解决问题。
function renderBackground() {
ctx.lineWidth = 5;
ctx.strokeStyle = '#FFFFFF';
ctx.fillStyle = '#000000';
ctx.fillRect(0, 0, cWidth, cHeight);
ctx.beginPath(); // <-- add it here
ctx.dashedLine(0, 0, 0, cHeight, 10);
ctx.stroke();
}
使用路径绘图时,您使用的是虚拟“笔”或“指针”。因此,您将创建一个带有开始路径的虚拟路径,绘制线条并最终描绘这些线条。在下一帧中,您将开始一条新的虚拟路径,在路径中绘制新线并再次击球。这样性能保持稳定。