开发者

html5 <canvas> framerate

开发者 https://www.devze.com 2023-01-15 08:54 出处:网络
I was thinking of making a game using javascript for the game logic and the HTML5 canvas element to animate the drawing. My goal is to write something that works in browsers and on newer smartphones.

I was thinking of making a game using javascript for the game logic and the HTML5 canvas element to animate the drawing. My goal is to write something that works in browsers and on newer smartphones. So I wrote up a quick program that moves 100 circles around on the screen and shows me the frame rate. I was fairly disappointed with the results: Chrome: ~90 FPS Firefox: ~ 25 FPS iPhone: ~11 FPS

This was a pretty simple test so I don't like my chances when it comes to actually making a complete game. Is this the standard result from the canvas element or are there some tricks to make drawing faster, if you have any good links let me know? Is canvas just a toy at this point or can it be used for real world applications.

Edit Here's the code:

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


In order to make animations more efficient, and to synchronize your framerate with the UI updates, Mozilla created a mozRequestAnimationFrame() function that is designed to remove the inefficiencies of setTimeout() and setInterval(). This technique has since been adopted by Webkit for Chrome only.

In Feb 2011 Paul Irish posted a shim that created requestAnimFrame(), and shortly afterwards Joe Lambert extended it by restoring the "timeout" and "interval" delay to slow down animation ticks.

Anyway, I've used both and have seen very good results in Chrome and Firefox. The shim also fallsback to setTimeout() if support requestAnimationFrame() is unavailable. Both Paul and Joe's code is online at github.

Hope this helps!


It's largely dependent on the JavaScript engine. V8 (Chrome) and Carakan (Opera) are probably the two fastest production-quality engines. TraceMonkey (Firefox) and SquirrelFish (Safari) are far behind, with KJS bringing up the rear. This will change as hardware acceleration enters the mainstream.

As for specific optimizations, we'd probably have to see some code. Remember that the canvas supports compositing, so you really only need to redraw areas that changed. Perhaps you should re-run your benchmark without the canvas so you know if the drawing operations really were the limiting factor.

If you want to see what can be done now, check out:
js1k
Bespin
Canvas-stein


Arcs are math-intensive to draw. You can dramatically improve performance by using drawImage or even putImageData instead of drawing the path each frame.

The image can be a file loaded from a URL or it can be an image created by drawing on a separate canvas not visible to the user (not connected to the DOM). Either way, you'll save a ton of processor time.


I have written a simple bouncing ball which gives you points if you click it.

It works fine in Firefox, Safari, Chrome and on the iPad. However, the iPhone 3G/3GS were horribly slow with it. Same goes for my older Android phone.

I am sorry but I do lack specific numbers.


Chrome is the only browser thus far that I've seen high framerate results with.

You might also want to try the latest Preview of IE9. That should give you a decent benchmark of how the next generation of browsers (with hardware acceleration for HTML5) will handle your code.

So far, I've seen that IE9, Chrome 7, and Firefox 4 will all sport some form of hardware acceleration.


There's loads of optimizations to be done with Canvas drawing.

Do you have example code you could share?

0

精彩评论

暂无评论...
验证码 换一张
取 消