5
\$\begingroup\$

I'm writing a planetary motion simulator with the HTML5 canvas element and I want to put one or more layers of stars in the background. The user can click and drag the screen to navigate around the map as well as zoom in and out. The map is infinite; they could scroll forever in any direction. I'd like to have the background layer move more slowly than the foreground so as to give the illusion of depth.

How should I go about implementing this? Can I load an image file and tile it? Should I create an SVG image? Should I just use the CanvasRenderingContext2D.fill() to create the background? I'm trying to keep the game running as close to 60fps as possible.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Don't know much about HTML5 but if you could stack your layers in groups ( that move together). You can specify their speed per group and move them on update. You could also move backgrounds relatively to the cameras position and use a scalar how far they should shift/move. Im just throwing ideas here. It's best you wait for an actual answer =). \$\endgroup\$
    – Sidar
    Commented Dec 23, 2012 at 1:00

3 Answers 3

1
\$\begingroup\$

You need to test it on your target platforms. Canvas implementations vary hugely in their performance, and a technique which is an optimisation on one may be a pessimisation on another.

If the layers are going to be "sparse" with few objects, I'd recommend just drawing those objects (in order, using painter's algorithm).

However, if there are lots of layers using blending, you may reach an implementation's limit of pixel-pushing. Blending is much more expensive than not blending (as it needs reading as well as writing, even if it's done by the GPU).

I can't really see a problem drawing 100 stars per layer, with 2-3 layers, if the stars are small compared to the total area.

\$\endgroup\$
0
\$\begingroup\$

Canvases are, as far as my knowledge/experience goes, not suited to animate large areas of the screen. For these purposes you should fall back to CSS and JavaScript.

One idea would be to set up a few divs behind the canvas. With CSS you define a repeating background for each one of these divs. With JavaScript you trigger then from your code, or even with default browser events, a drag event (i.e. mousedown, mouseup, mousemove/mouseover and mouseout).

In this event you can then determine the moved distance and direction as a pixel-vector by comparing it to the last determined mouse position (see http://www.quirksmode.org/js/events_properties.html - Mouse position). This vector can then be used to change the background's offset (background-position) at each single div. By applying only a percentage of this movement-vector to the background's position you get a nice parallax-effect. For instance:

  1. layer 33%
  2. layer 66%
  3. layer 99%
\$\endgroup\$
2
  • \$\begingroup\$ Zoom not accounted for and there is no real solution using advised method. Ideally the stars would spread side ways as you zoom in otherwise it would feel unrealistic. Here is one of many samples of star field in Canvas is able to render full screen chiptune.com/starfield/starfield.html \$\endgroup\$
    – John
    Commented Jan 10, 2013 at 16:00
  • \$\begingroup\$ ah sorry, overread the last part mentioning the zoom and misinterpredted the term paralax scrollign then :/ \$\endgroup\$
    – Kailrim
    Commented Jan 12, 2013 at 9:11
0
\$\begingroup\$

If you've not gone too far on the rendering side yet, one simple solution would be to use an actual 3D renderer. This way you don't have to reinvent the wheel and implement the parallax yourself, you can simply throw a classic perspective projection, a camera, and you're good to go.

The last time I checked, three.js seemed to be a quite compelling option but I'm sure there are plenty of other libs that might suit your needs. Going this way will also probably require a WebGL-enabled browser for proper performance, which might or might not be an option depending on what your final goal is (do you want the largest audience possible or are you just experimenting?).

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .