Merlin
Merlin

Reputation: 978

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;
            gameContainer.add(hex);
            hex.tileColor = returnRandomHex();
            hex.switchSprite(hex.tileColor);

            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:

Hexagon

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);
        gameContainer.add(hex);
    }
}

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?

Upvotes: 3

Views: 2802

Answers (2)

Thomas
Thomas

Reputation: 12637

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; 
            positions.push({
                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: https://jsfiddle.net/36bjmtax/1/

Upvotes: 2

Adder
Adder

Reputation: 5868

If you use a different method for coordinates then you get a diamond shaped area which is close to your goals. The coordinates would start with (0,0,0) which each coordinate having a sum of zero. In x direction, add (1,0,-1) in the y-ish direction add (0,1,-1). Then from painting, exclude those with x+y < 3 and x+y > 11. Or talking in z-values, paint only -11 < z and z < -3.

How about this for the second method of painting:

int map_side = 4;
for (int q = 0; q < map_side; q++) {
    for (int r = 0; r < map_side; r++) {
        if( -map_side >= -q-r && -q-r > -3*map_side)
            map.insert(Hex(q, r, -q-r));
    }
}

Sorry for the sloppy code, its not easy to code blind without off by one errors. For the translation of coordinate systems you can use:

function hexToXY(hex) {
    var xy = new Point(hex.X * 7 + hex.Y * 5, hex.Y * 5);
    return xy;
}

Upvotes: 1

Related Questions