1
\$\begingroup\$

My current solution is to clear the entire canvas and redraw all sprites on every requestFrame(). This works but feels inefficient:

  1. I only need to clear the part of the canvas made invalid by animations.
  2. I only need to redraw objects that intersect the invalid part of the canvas.

I can track invalidated sections, and during requestFrame() I can find out which objects intersect an invalid section and redraw only them, but I'm not sure if that's an improvement or a step back. If I have 100 sprites and 10 of them are moving, that means I need to do 10 searches through all 100 sprites. Tall order for every request frame.

I can also put every sprite on its own canvas and remove sprite interaction from the equation, but I haven't been able to find insight into how many canvases is too many.

This seems like a problem that's been solved already, but I haven't found any resources on the topic.

\$\endgroup\$
  • \$\begingroup\$ These kinds of algorithms were common back in prehistoric java mobile games, you might have some luck finding resources how they were done. \$\endgroup\$ – wondra Feb 28 '16 at 1:00
  • 1
    \$\begingroup\$ The technique you're asking about is called "dirty rectangles". I haven't implemented this but this SO link is one place to start: stackoverflow.com/questions/76651/dirty-rectangles \$\endgroup\$ – NoobsArePeople2 Feb 28 '16 at 6:13
  • \$\begingroup\$ Thanks, @NoobsArePeople2. Knowing the name of what I was describing will help me continue my research. \$\endgroup\$ – Mark Feb 28 '16 at 13:23
  • \$\begingroup\$ I made some benchmarking tests in Firefox once, and noticed that calling drawImage outside of the canvas bounds is extremely fast. So it's not that much of a problem unless you have a really large amounts of sprites so that the function call overhead alone eats too many CPU cycles. I didn't test it in all major rendering engines, though. \$\endgroup\$ – Philipp Mar 1 '16 at 18:26
3
\$\begingroup\$

The first thing you should do is figure out if you actually have a problem.

Is the way you're clearing the canvas now slow? Are you dropping frames because of how you clear the canvas? Regardless of how it looks (for now), remove the call that clears the canvas and measure again. Are your paint cycles a lot faster now?

Basically, I wouldn't worry about this until you know it is a problem. The technique you're looking for is dirty rectangle updating, but it is computationally more expensive and until you know what it saves you it's hard to make the proper engineering decision here.

\$\endgroup\$
  • 1
    \$\begingroup\$ True that : measure first. Moreover : 1) Javascript's overhead is especially high (vs the same draw load in C++ for instance) and 2) both context2D and webGL are using the GPU to draw, so good luck beating a GPU with a dirty rect algorithm made in JS. \$\endgroup\$ – GameAlchemist Mar 1 '16 at 20:57
  • \$\begingroup\$ That makes sense, d-hayes. I was thinking this was a problem with a common one-size-fits-all solution, but it sounds like it can go either way. Your advice makes good sense. \$\endgroup\$ – Mark Mar 1 '16 at 23:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.