垃圾收集是否会影响这个画布蛇游戏的帧速率?

时间:2018-02-12 15:29:23

标签: javascript canvas garbage-collection

JSFiddle demo (~200 lines. WASD to move, snake speed is set to very slow)

每当我让我的代码运行一段时间,我就可以观察到帧速率稳步下降。

我相信渲染蛇的代码会导致fps丢失:它会使用ctx.clearRect清除整个画布。然后它采用一维数组表示蛇所采用的转弯的x和y坐标并创建一条路径。然后我打电话给ctx.stroke。最好只绘制蛇的新部分,而不是清理画布并改造整条蛇的路径并在每个框架上重绘蛇,对吧?

Snake.prototype.render = function() {

// this.env.canvas.fgContext is the context for the foreground canvas.
// There is a background canvas for a chess background pattern.
this.env.canvas.fgContext.strokeStyle = this.color;
this.env.canvas.fgContext.lineWidth   = this.env.tileSize;
this.env.canvas.fgContext.lineCap = "square";
this.env.canvas.fgContext.beginPath();
this.env.canvas.fgContext.moveTo(this.env.leftWidthGap + (this.positions[0]-0.5)*this.env.tileSize,
                                 this.env.topHeightGap + (this.positions[1]-0.5)*this.env.tileSize);

for(var i = 2; i < this.positions.length; i += 2)
   this.env.canvas.fgContext.lineTo(this.env.leftWidthGap + (this.positions[i]-0.5)*this.env.tileSize,
                                 this.env.topHeightGap + (this.positions[i+1]-0.5)*this.env.tileSize);
this.env.canvas.fgContext.stroke();
}

此外,移动蛇的“头部”和“尾部”的代码似乎会对帧速率产生负面影响,因为删除它(以及删除渲染代码)会导致帧率丢失:

Snake.prototype.moveHead = function(delta) {
this.idx    = this.positions.length - (this.input.isCurrentY ? 1 : 2),
this.newPos = this.positions[this.idx] + this.speed * delta * this.input.currentDir;

if(this.input.currentKeyCode === this.input.futureKeyCode || Math.trunc(this.positions[this.idx]) === Math.trunc(this.newPos)) { this.positions[this.idx] = this.newPos; return; }
this.positions[this.idx] = Math.round(this.positions[this.idx]);
this.deltaChange = Math.abs(this.newPos - this.positions[this.idx]);
this.input.assignFutureToCurrent();
this.inputStack.push(this.input.currentDir)
this.inputStack.push(this.input.isCurrentY);
this.positions.push(this.positions[this.positions.length-2]);
this.positions.push(this.positions[this.positions.length-2]);
this.positions[this.positions.length - (this.input.isCurrentY ? 1 : 2)] += this.deltaChange * this.input.currentDir;
}
Snake.prototype.moveTail = function(delta) {
this.idx = this.inputStack[1] ? 1 : 0;
this.positions[this.idx] += this.speed * delta * this.inputStack[0];

if((this.inputStack[0] < 0 && this.positions[this.idx] < this.positions[this.idx+2]) ||
    this.inputStack[0] > 0 && this.positions[this.idx] > this.positions[this.idx+2]) {
    this.deltaChange = Math.abs(this.positions[this.idx] - this.positions[this.idx+2]);
    this.positions = this.positions.slice(2),
    this.inputStack = this.inputStack.slice(2);
    this.positions[this.inputStack[1] ? 1 : 0] += this.deltaChange * this.inputStack[0];
}
}

在游戏循环的每一帧上都会调用这些函数,如有必要,我可以详细说明。问题是所有数组的推送和切片?记忆在这里漏了吗?

0 个答案:

没有答案