I am developing an TBS (turn based strategy) game. I have created a simple canvas renderer to render hexagonial map. I already implemented scrolling on the map. My current problem is that I want to make it like in the civilizations games that you can scroll around the world. But I am kind of stuck on how to implement that. I had the idea of checking if a tile was rendered and if there is still space to the left render next sibling and so on, but this would turn out into long loops. My map array (2d) holds all the tiles and every tile has a member which holds all the siblings. How would you solve this?

example map available on civ.minerjs.com

This is a screenshot from the example. You can check it out on http://civ.minerjs.com. The code is also available to browse on the site using developer tools. Thanks for reading!


1 Answer 1


Hex grids can be treated as square grids with an offset every other column/row (depending on orientation), which means your map can be a 2D array instead of a linked graph of hex cells, then you just need method calls to find the siblings that wrap up a little math to handle converting hex grid coords to square grid coords.. For instance.. given your orientation, East and West are easy... NE/NW/SE/SW need to look at if they are on an even or odd row to decide if the neighbor hex is directly above or below, or offset to to the east or west. But given the next part of my answer, that will only really matter for things that are moving on the map, not for drawing the map.

Considering that there are fixed size steps for each row/column, using a 2D array as the backing store and a bit of math it should not be hard to pre-determine how many cells you can display on a canvas of given size... that makes your draw loop deterministic and MUCH faster than walking a linked graph of hex cells. you may be scanning a 2D map array, but drawing the hex cells with the correct offsets based if the row is even or odd.

Basically what it boils down to is if you store your map in a 2D array, it is wasteful to also store sibling links.. the sibling coords for hex grids are too easy to compute at runtime

As far as wrapping to be able to scroll around the world (I'm assuming in the east/west direction only) all you are doing looping from startpos to startpos+CellCountWidth(canvasWidth) [ which may extend beyond the end of the array] and just wrap the position if it goes over the edge (if xpos >= arraysize { xpos -= arraysize; }) [x is east west, Y is your row counter the way I'm looking at the coords]

  • \$\begingroup\$ I want to enable scrolling in all directions. I store the siblings because they don't change and its a waste to calculate them every time the render/update loop is called. But thanks for the detailed answer. I already had something similar in mind like you proposed in the last paragraph. \$\endgroup\$
    – Luketep
    Sep 23, 2014 at 14:36
  • \$\begingroup\$ you only need to calc siblings when you are considering moves from one hex to another.. during the render, its all precomputed offsets (I'm working on an odd row, add offset to X, Y offsets are the same for each row because of how the hexes overlap) \$\endgroup\$
    – Ascendion
    Sep 23, 2014 at 22:26
  • \$\begingroup\$ you're right. Somehow I had a twist in my head :) \$\endgroup\$
    – Luketep
    Sep 24, 2014 at 9:08

You must log in to answer this question.

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