2
\$\begingroup\$

I am playing around with the HTML5 canvas and have begun implementing a tile engine.

However, it's currently very inefficient: I have a 100x100 2D array and my code loops through the whole thing every frame. (Very bad, I know.) I'd like to optimise the rendering loop by using a viewport or camera to determine which parts of the area are view.

Here is an example. I haven’t added the camera offset yet because I’m not sure how:

for (var y = 0; y < state.map_data.length; y++) {
    col = state.map_data[y];
    for (var x = 0; x < col.length; x++) {
        color = (state.map_data[y][x]==1)?'#fff':'#000';            
        self._draw({
            type:'rec',
            x: x * state.tile_width,
            y: y * state.tile_height,
            width: state.tile_width,
            height: state.tile_height,
            fill: color,
            visible: true
        },self.ctx);
    };
};

Here is a link to the game as it is.

How can I make this more efficient?

\$\endgroup\$
  • \$\begingroup\$ Have you considered spatial partitioning e.g. with a quadtree? \$\endgroup\$ – Anko Mar 7 '13 at 0:10
  • \$\begingroup\$ You don't need spatial partitioning to cull a uniform grid. \$\endgroup\$ – MarkR Mar 7 '13 at 16:34
  • \$\begingroup\$ Thanks @Anko I haven't hear of the quadtree but it i some I would look into \$\endgroup\$ – ianmac Mar 7 '13 at 19:10
4
\$\begingroup\$

From my understanding you just read the camera bounds and use that as your index reference of your tile grid. Draw from the first tile in the top left corner of your current screen, relative to the cameras position, to the last tile of your bottom right corner index. This way you only draw tiles that are within camera bounds.

For example the first would be something like so:

int indexX = topleftXBound/ tileSize;
int indexY = topleftYBound/ tileSize;

Then calculate the right bottom bound. You can use these indexes to determine what starting point and limit you should use for your forloop. Instead of drawing 100x100 tiles. You only a few in comparison.

You could represent your camera as a simple rectangle that you move around. Have the center, the width and height.

\$\endgroup\$
  • \$\begingroup\$ Erm, yes. Calculate the minimum and maximum x and y coordinates visible, and only draw the tiles within those limits. \$\endgroup\$ – MarkR Mar 7 '13 at 16:35
  • \$\begingroup\$ Thanks @Sidar That help quite a lot I can't seem to post the code but you got me think i the right way \$\endgroup\$ – ianmac Mar 7 '13 at 19:07

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.