Gruhlum
Gruhlum

Reputation: 77

Moving hexagons with cube coordinates into a square formation

It works for most of it:

working

The problem starts when the height is alot larger than the width (3x9, 3x11, 5x11 etc.)

not working correctly

As you can see the first line is out of place, increasing the height further will repeat this pattern.

Here is the code (Note: my z and y for cube coordinates is swapped):

void SpawnHexGrid(int Width, int Height)
    {
        int yStart = -Height / 2;
        int yEnd = yStart + Height;

        for (int y = yStart; y < yEnd; y++)
        {
            int xStart = -(Width + y) / 2;
            int xEnd = xStart + Width;

            if (Width % 2 == 0)
            {
                if (y % 2 == 0)
                {
                    xStart++;
                }
            }
            else
            {
                if (y % 2 != 0)
                {
                    xStart++;
                }
            }
            Debug.Log("y: " + y + " , Start: " + xStart + " , End: " + xEnd);

            for (int x = xStart; x < xEnd; x++)
            {
                SetHexagon(new Cube(x, y));
            }
        }
    }

Edit:

After changing to @Idle_Mind solution my grid looks like this:

enter image description here

Edit again:

I found a solution, after changing to @Idle_Mind's solution I corrected the tilting by using y again:

int xStart = -Width / 2 - (y / 2);

but this caused a similar problem as before, but this time I realized it had something to do with the way an int is rounded, when y is negative xStart would be 1 lower then expected, so I just add 1 whenever y is negative:

int add = 0;

    if (y < 0)
    {
        add = 1;
    }
    int xStart = -Width / 2 - ((y - add) / 2);

This works like a charm now, thanks everyone.

Upvotes: 1

Views: 340

Answers (2)

Idle_Mind
Idle_Mind

Reputation: 39142

Change your SpawnHexGrid() to:

void SpawnHexGrid(int Width, int Height)
{
    int xStart = -Width / 2;
    int yStart = -Height / 2;
    int yEnd = yStart + Height;

    for (int y = yStart; y < yEnd; y++)
    {
        int xEnd = xStart + Width + (y%2==0 ? 0 : -1);

        for (int x = xStart; x < xEnd; x++)
        {
            SetHexagon(new Cube(x, y));
        }
    }
}

My test rig:

enter image description here

---------- EDIT ----------

I don't understand why you're using the y value as part of your calculation for x. Make the x constant for a whole column as you'd expect for a regular grid. In my code, the shorter rows still start at the SAME x coord as the longer ones; it's the length of them that changes. Then, when you draw, I simply calculate the position for a normal grid, but add half the width of the hexagon for all odd y positions resulting in the offset you need for the hexagons.

For example, here is a 5x5 grid drawn "normally" without offsetting the odd Y rows. It's clear that the starting X coordinate for all rows is the same: enter image description here

So the stored x,y coord are all based on a normal grid, but the drawing code shifts the odd y rows. Here's where I change the X coord, only for drawing, of the odd y rows:

if (pt.Y % 2 != 0)
{
    center.Offset(Width / 2, 0);
}

So, after adding the offset (again, only at drawing time) for odd Y rows, it now looks like:

enter image description here

And here is the grid shown with the internal coord of each hexagon being displayed:

enter image description here

Hope that makes it clear how I approached it.

Upvotes: 2

MikeJ
MikeJ

Reputation: 1379

I believe you're just alternating a different row size for a hexagonal map. If so something like this should work:

class Program
{
    static void Main(string[] args)
    {
        const int Height = 4;
        const int Width = 4;

        for (int y = 0; y < Height; ++y)
        {
            int rowSize = y % 2 > 0 ? Width + 1 : Width;

            for (int x = 0; x < rowSize; ++x)
            {
                Console.WriteLine($"{x}:{y}");
            }
        }

        Console.ReadLine();
    }
}

Upvotes: 1

Related Questions