【问题标题】:html5 <canvas> frameratehtml5 <canvas> 帧率
【发布时间】:2012-03-22 02:08:41
【问题描述】:

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

这是一个非常简单的测试,所以我不喜欢真正制作完整游戏的机会。这是画布元素的标准结果还是有一些技巧可以加快绘图速度,如果您有任何好的链接,请告诉我?画布在这一点上只是一个玩具还是可以用于现实世界的应用程序。

编辑代码如下:

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();

【问题讨论】:

  • 你能把代码贴出来吗?
  • 我读到断开操作与 DOM 的连接会使事情真的快得多,我认为他们制作了一个画布元素而不将其连接到 DOM 树中的任何位置并对其进行 blitted画完的时候就结束了。但我不能 100% 确定 - 我只是快速浏览了这篇文章,然后决定这不是我目前正在搜索的内容。
  • 我和你有同样的问题(和同样的目的,构建基于 HTML Canvas 的游戏以将它们部署在 iOS 和 Android 平板电脑和手机上)查看我的测试(A Sky and Clouds,基本上是一堆圆圈在移动)gubatron.com/html5/sky.html 我在桌面上获得了很棒的 FPS,但我在 Galaxy Tab 上能获得的最好的是 10-12FPS。尝试了很多东西,唯一有帮助的是减少绘制的圆圈数量。这让我想到,也许我应该在画布的一小部分上工作,分辨率要低得多,然后将其放大,这样会飞吗?
  • 我放弃了为手机制作基于画布的游戏并重新开始制作应用程序。以较低的分辨率绘图会提高速度,但会降低质量。我认为任何需要每帧都重新绘制的东西在移动设备上是行不通的。

标签: javascript html canvas


【解决方案1】:

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

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

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

希望这会有所帮助!

【讨论】:

  • 我应该澄清一下,在将它应用到您的代码之后,我在 chrome 和 firefox 中获得了 60fps。这个 60fps 是有意的,因为它将帧更新与 UI 更新同步。有关原因的正确技术解释,请参阅nczonline.net/blog/2011/05/03/…
【解决方案2】:

它很大程度上依赖于 JavaScript 引擎。 V8 (Chrome) 和 Carakan (Opera) 可能是两个最快的生产质量引擎。 TraceMonkey (Firefox) 和 SquirrelFish (Safari) 远远落后,KJS 排在后面。随着硬件加速进入主流,这种情况将会改变。

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

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

【讨论】:

  • js1k 让我认为画布已经为主流做好了准备。仔细观察,似乎有些性能非常好,而另一些则没有做类似的事情。我使用 console.prolfile() 分析了我的代码。大约 90% 的时间都花在了绘画上。使用堆肥我可能会获得一些额外的性能,但我必须编写一个管理器来确定屏幕的哪些区域需要重绘。这会增加很多复杂性
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

    它在 Firefox、Safari、Chrome 和 iPad 上运行良好。然而,iPhone 3G/3GS 的速度非常慢。我的旧 Android 手机也是如此。

    很抱歉,我确实缺少具体数字。

    【讨论】:

      【解决方案5】:

      Chrome 是迄今为止我看到的唯一高帧率结果的浏览器。

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

      到目前为止,我已经看到 IE9、Chrome 7 和 Firefox 4 都将支持某种形式的硬件加速。

      【讨论】:

      • 我知道浏览器越来越好,但移动设备呢?这是我想要瞄准的主要目标之一。如果我必须等待 3 到 5 年才能让相当数量的人能够运行它,那么做某事毫无意义。
      • 嗯,你期待什么?您必须在 iPhone 上添加 GeForce 卡才能加快速度(我必须说,我很想看到这张照片)。顺便说一句:Chrome 和 iPhone 使用相同的渲染引擎。您看到的只是计算能力的差异。
      【解决方案6】:

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

      你有可以分享的示例代码吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-12
        • 1970-01-01
        • 2014-06-18
        • 1970-01-01
        • 2013-03-11
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多