Merlin Merlin - 2 months ago 8x
Javascript Question

How would I set up a hexagonal-shaped map using Javascript and hex tiles?

I've got the basic math done for a standard "square" hexagon map, however I would like to convert this to a hex-shaped map in full, one that appears as a hexagon made out of hexagons. For Javascript however, I am unsure of how to do this using the code I've built already - here's what I have so far:

function CreateHexGrid()
for (x = 0; x < mapWidth; x++)
tileArray[x] = [];

for (y = 0; y < mapWidth; y++)
var hex = new hexTile(game, 0, 0);
var point = calculateGrid(x,y);
hex.x = point.x;
hex.y = point.y;
hex.tileColor = returnRandomHex();

tileArray[x][y] = hex;


function calculateGrid(x, y)
var point = new PIXI.Point(x,y);

var offset = 0;

if (point.y % 2 != 0)
offset = 90 / 2;

var x = offset + point.x * 95;
var y = point.y * 100 * 0.75;

point.x = x;
point.y = y;

return point;

This is my end goal:


I have attempted to convert code from an apparent C/++/# example initially found on RedBlobGames, however it gave me a very strange rectangular trapezoid shape once I actually got the coordinates in:

for (int q = -map_radius; q <= map_radius; q++) {
int r1 = max(-map_radius, -q - map_radius);
int r2 = min(map_radius, -q + map_radius);
for (int r = r1; r <= r2; r++) {
map.insert(Hex(q, r, -q-r));

I would rather do this without having to tell it to 'not draw' various offset sections outside the wanted shape - what I'd consider an "edited" map after the fact of it being drawn.

This is my converted version for Javascript following examples provided by RBG and StackExchange so far:

for (q = 0; q < mapRadius; q++)
for (r = 0; r < mapRadius; r++)
var point = calculateGrid(-q-r, r);
var hex = new hexTile(game, point.x, point.y);

When I follow the examples provided for a hexagonal map, this is the result that I am getting:

enter image description here

What can I do to fix this?


A simple code to compute the positions of each cell for such an hexagonal arrangement.

function hexGrid(edgeLength){
    var len = 2*edgeLength - 1,
        vx = Math.sin(Math.PI/6), vy = Math.cos(Math.PI/6),
        tl = edgeLength - 1, br = 3*edgeLength - 2,
        positions = [];

    for(var y = 0; y < len; ++y){
        for(var x = 0; x < len; ++x){
            //you may want to remove this condition
            //if you don't understand the code
            if(x+y < tl || x+y >= br) continue; 
                x: vx*y + x,
                y: vy*y
    return positions;

It expects the length of the outer edge for your grid, and returns an array of positions for the cells.

This is just the basic Math to arrange the cells, since this seems to be your core problem. You'll have to scale and translate/offset the points according to your needs, but that's up to you.

A sandbox to play a bit around: