如何加快画布上的绘图?

Ear*_*ray 3 javascript jquery html5-canvas

我尝试编写一个等距的瓷砖游戏引擎,并且对此代码的速度有问题:

$(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
});
Run Code Online (Sandbox Code Playgroud)

如果我将Location.width和Location.height设置为较低的数字,那么它运行速度很快(50 fps)但在这个例子中(Location.width = 60,Location.height = 120)帧速率是10 fps而我需要50 fps,你有任何sugestions如何加速这个脚本?

jjm*_*tes 5

1)在我看来,即使它们不在视野中,你也在绘制每个瓷砖.使用"剪裁".您需要在调用之前计算磁贴是否在视图中context.drawImage().

2)如果您的风景是静止的,请尽可能预先计算.然而,创建一个巨大的图像也不是一个好主意,你宁愿预先计算一些大块(即512x512).

3)在某些浏览器中,据说你可以获得更好的帧速率,而不是使用'setTimeout()'你使用requestAnimationFrame(我也发现这篇文章非常有趣).

4)调整大小/缩放可能会影响性能(特别是在较旧的浏览器或硬件中).如果你的图块已经是32x64,你可以使用只有3个参数的drawImage(),避免调整大小(如果你需要缩放以实现缩放效果或类似效果,则不适用).