html5 <canvas> framerate </canvas>

时间:2010-09-10 12:13:26

标签: javascript html5 canvas

我正在考虑使用javascript为游戏逻辑制作游戏,并使用HTML5画布元素为游戏设置动画。我的目标是编写适用于浏览器和更新智能手机的东西。所以我写了一个快速程序,在屏幕上移动100个圆圈,并向我显示帧速率。我对结果感到非常失望: Chrome:~90 FPS Firefox:~25 FPS iPhone:~11 FPS

这是一个非常简单的测试,因此我不喜欢实际制作完整游戏的机会。这是canvas元素的标准结果还是有一些技巧可以让绘图更快,如果你有任何好的链接让我知道?帆布在这一点上只是一个玩具,还是可以用于现实世界的应用。

修改以下是代码:

var ctx;
var width;
var height;
var delta;
var lastTime;
var frames;
var totalTime;
var updateTime;
var updateFrames;
var creats = new Array();

function init() {
    var canvas =document.getElementById('main');
    width = canvas.width;
    height = canvas.height; 
    ctx = canvas.getContext('2d');
    for(var i=0; i < 100; ++i) {
        addCreature();
    }
    lastTime = (new Date()).getTime();
    frames = 0;
    totalTime = 0;
    updateTime = 0;
    updateFrames =0;
    setInterval(update, 10);
}


function addCreature() {
    var c = new Creature(Math.random()*100,Math.random()*200);
    creats.push(c);
}

function update() {
    var now = (new Date()).getTime();
    delta = now-lastTime;
    lastTime = now;
    totalTime+=delta;
    frames++;
    updateTime+=delta;
    updateFrames++;
    if(updateTime > 1000) {
        document.getElementById('fps').innerHTML = "FPS AVG: " + (1000*frames/totalTime) + " CUR: " + (1000*updateFrames/updateTime);
        updateTime = 0;
        updateFrames =0;
    }

    for(var i=0; i < creats.length; ++i) {
        creats[i].move();
    }

    draw();
}

function draw() {
    ctx.clearRect(0,0,width,height);
    creats.forEach(drawCreat);
}

function drawCreat(c,i,a) {
    if (!onScreen(c)) {
        return;
    }
    ctx.fillStyle = "#00A308";
    ctx.beginPath();
    ctx.arc(c.x, c.y, 10, 0, Math.PI*2, true); 
    ctx.closePath();
    ctx.fill();
}

function onScreen(o) {
    return o.x >= 0 && o.y >= 0 && o.x <= width && o.y <=height;
}

function Creature(x1,y) {
    this.x = x1;
    this.y = y;

    this.dx = Math.random()*2;
    this.dy = Math.random()*2;

    this.move = function() {
        this.x+=this.dx;
        this.y+=this.dy;
        if(this.x < 0 || this.x > width) {
            this.dx*=-1;
        }
        if(this.y < 0 || this.y > height) {
            this.dy*=-1;
        }
    }

}

init();

6 个答案:

答案 0 :(得分:6)

为了提高动画效率,并使帧速率与UI更新同步,Mozilla创建了一个mozRequestAnimationFrame() function,旨在消除setTimeout()和setInterval()的低效率。此技术后来仅被Webkit用于Chrome。

2011年2月Paul Irish posted a shim创建了requestAnimFrame(),之后不久Joe Lambert extended it通过恢复“超时”和“间隔”延迟来减慢动画刻度。

无论如何,我已经使用过两者,并且在Chrome和Firefox中看到了非常好的结果。如果支持requestAnimationFrame()不可用,则垫片也会回退到setTimeout()。 Paul和Joe的代码都在线at github

希望这有帮助!

答案 1 :(得分:5)

它在很大程度上依赖于JavaScript引擎。 V8(Chrome)和Carakan(Opera)可能是生产质量最快的两款发动机。 TraceMonkey(火狐)和SquirrelFish(Safari)远远落后,KJS带来了后方。随着硬件加速进入主流,这将发生变化。

至于具体的优化,我们可能不得不看一些代码。请记住,画布支持合成,因此您实际上只需要重绘已更改的区域。也许您应该在没有画布的情况下重新运行基准测试,以便了解绘图操作是否真的是限制因素。

如果您想了解现在可以做些什么,请查看:
js1k
Bespin
Canvas-stein

答案 2 :(得分:2)

弧形是数学密集型绘制。您可以使用drawImage甚至putImageData而不是每帧绘制路径来显着提高性能。

图像可以是从URL加载的文件,也可以是通过在用户不可见的单独画布上绘制的图像(未连接到DOM)。无论哪种方式,您都可以节省大量的处理器时间。

答案 3 :(得分:1)

我写了一个简单的弹跳球,如果点击它就会给你点数。

它适用于Firefox,Safari,Chrome和iPad。然而,iPhone 3G / 3GS的速度非常慢。我的旧款Android手机也是如此。

我很抱歉,但我确实没有具体的数字。

答案 4 :(得分:0)

Chrome是迄今为止我见过的唯一高浏览器结果的浏览器。

您可能还想尝试最新的IE9预览版。这应该为您提供一个关于下一代浏览器(HTML5的硬件加速)如何处理您的代码的良好基准。

到目前为止,我已经看到IE9,Chrome 7和Firefox 4都会采用某种形式的硬件加速。

答案 5 :(得分:0)

Canvas绘图需要进行大量优化。

您是否有可以共享的示例代码?