4

I hope this isn't too open ended.

I'm wondering if there is a better (more battery-friendly) way of doing this --

I have a small HTML 5 game, drawn in a canvas (let's say 500x500). I have some objects whose positions I update every 50ms or so. My current implementation re-draws the entire canvas every 50ms. I can't imagine that being very good for battery life on mobile platforms.

Is there a better way to do this? This must be a common pattern with games.

EDIT:

as requested, here are some more updates:

Right now, the objects are geometric primitives drawn via arcs and lines. I'm not opposed to making these small png/jpg/gif files instead of that'd help out. These are small graphics -- just 15x15 or so.

As the game progresses, more and more of the screen changes at a time. However, at the start, the screen changes relatively slowly (the objects randomly moved a few pixels every 50ms).

4 Answers 4

7

Nearly every game with continuous animation like this redraws everything every frame; clever updating algorithms are only applicable when a small part of the screen is changing and there is a nice rule to figure out what is overlapping that part.

Here is some general optimization advice:

  • Make sure that as much as possible of your graphics are handled by the GPU and not the CPU. (This may be impossible if the user's browser does not use the GPU for 2D canvas rendering, but you can expect upgrades may change that as HTML5 gaming gains popularity.)

    • This means that you should avoid elaborate clever algorithms in favor of doing as little work as possible in JS code — except that avoiding performing a lot of drawing when it is easy to determine that it will be invisible (e.g. outside the bounds of the screen) is generally worthwhile.

    • If your target platforms support it (generally not the case for current mobile devices), try using WebGL instead of 2D Canvas. You will have to do more detail work, but WebGL allows you to use operations which are much more likely to be provided efficiently by the GPU hardware.

  • If your game becomes idle — that is, nothing is actually animating at the moment — stop redrawing. Stop your update loop until the user interacts with the game or a timeout occurs.

It may be helpful for you to add to your question details of what types of graphics you are drawing (e.g. are you using sprites, or geometric primitives? Are you drawing images rotated/scaled? Does most of the screen change or just a few small objects? Are you blending many layers?) and perhaps even a screenshot or two; then we can suggest what sort of optimizations are suitable for your particular game.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, thanks for the thoughtful answer. I updated the question a bit. There's no rotation or scaling in the images although I like the idea and may incorporate it :). What does blending the layers mean? I'm just drawing a background, then drawing my objects on top of the background every 50 ms. Does that mean 2 layers?
I like your answer so +1 -- I will mark it as the answer if nobody else chimes in, in the next day or so.
By layers, I (sloppily) meant the number of graphics drawn on top of each other.
3

Don't draw a background, make it an image and set the CSS background-image of the canvas.

Using requestAnimationFrame should help with battery life.

http://paulirish.com/2011/requestanimationframe-for-smart-animating/

Only do a redraw if something has actually changed. If you haven't already, introduce the concept of invalidations. (ie, the canvas is valid so nothing redraws until something moves. Anything moving within the window of the canvas causes the canvas to become invalid, thus needing a redraw)

Comments

1

If you want to be battery friendly you can use Crafty. This game engine is using modern CSS3 technology so it doesn't need to update a canvas all the time. Look at this example game here.

1 Comment

canvas is just as modern and way better than updating the DOM all the time... CSS3 is simply not made for most games - apart from maybe chess
0

The way you don't want to redraw entire canvas every frame, it only can be the "Dirty-Check" or "Dirty Matrix" algorithms.

Dirty-check seems more efficient than entire redraw. but I think it depends on your render implementation.

it is not necessary to use it if you are using canvas2D to render. Nearly every game has complex sprites and animation. if you use dirty-check, when a part of sprite or background map need to update, you have to figure out what is overlapping this part. and then clearRect this small area of canvas, and then redraw every sprite or map. etc, what is overlapping. It means your had to run canvas render api more times than normal render implementation because of the overlapping part. And Canvas2d render performance usually does't sounds efficient.

But if you use WebGL, that maybe quite difference. even though I am not family with WebGL, I do knew that maybe more efficient. Dirty-Check should be a good Choice to match your propose.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.