JoeJ said:
Player drags a sprite, but then when he releases it, the program should snap it to the closest hex grid positionI am unsure of how to implement this?
click and drag sprite
pbivens67 said:
I am rendering in the vector and drawing the sprites
So, did you do any changes to the rendering code? I'm still waiting to see what you came up with….
pbivens67 said:
here is a screen shot of my game so far
How do you render this? I guess it's a large bitmap where the map is in one image?
If so, the first step to snap dragged sprites to the grid could be to render a dot in the middle of each hex, so you can tweak your grid spacing to match the map image.
A struct and function to render such dots could look like:
struct HexGridSpacing
{
float cellWidth = 20;
float cellHeight = 12;
float originX = 10;
float originY = 6;
int rows = 30;
int columns = 25;
};
void RenderHexGridDots (const HexGridSpacing &spacing)
{
for (int y=0; y<spacing.columns; y++)
for (int x=0; x<spacing.rows; x++)
{
float dotX = spacing.originX + x * spacing.cellWidth
+ (y&1) * spacing.cellWidth * 0.5f; // shift half a cell on odd rows for the hex effect
float dotY = spacing.originY + y * spacing.cellHeight;
SDL_DrawPixel(dotX, dotY, SDL_BLACK); // idk how to draw a pixel with SDL, so you need to figure this out
}
}
Adding this to the existing code:
HexGridSpacing spacing;
vector <Sprite> sprites;
sprites.push_back(Sprite(1400, 725));
sprites.push_back(Sprite(1205, 725));
//...
{
//...
SDL_Rect rect_eleven;
rect_eleven.x = 1175;
rect_eleven.y = 910;
SDL_BlitSurface(gHelloWorld_five, NULL, gScreenSurface, &rect_eleven);
RenderHexGridDots (spacing);
SDL_UpdateWindowSurface((gWindow));
}
After that the dot grid should appear, and you only need to tweak the default numbers of HexGridSpacing to match the map image.
I have used floating point numbers over integers to ensure we have enough precision.
pbivens67 said:
can you explain your code a little bit
It should draw a grid, but odd rows (red) are one half off:
![](https://uploads.gamedev.net/forums/monthly_2025_02/medium.d75b45ef758a4ea48794dc5e6ccd1fcb.image.webp)
This gives the centers of a hex grid, and if you tweak all the numbers right, it should match the image.
I stubbed out your code and it appears to work so I am not ignoring you I just want input from others
Good site about hexgrids: https://www.redblobgames.com/grids/hexagons/
Reading through this, you will see there are many ways to work with hexgrids, and you'll end up more confused than before the read.
However, seeing the image of your map it's clear which convention you want to use.
First, you want to represent your map data in a regular grid.
Likely you want to define a struct which holdes the data of a single cell, e.g. an index to a sprite which currently sits on that cell, plus another number to indicate a background maybe. For example:
struct Cell
{
int spriteIndex = -1; // -1 if no sprite is there
int background = 0; // 0 = sand, 1 = grass, 2 = rock
int faction = -1; // -1 if not occupied, otherwise 0 for team blue and 1 for team red
int resourceAmount = 0; // maybe the players can extract resources from a cell
// and any other stuff the game needs for each cell
};
After that, say we want a grid for a small map of 4 x 3 cells. We could make this picking one of those 3 options:
void main ()
{
// Cell map[4][3]; // using a 2D array, which makes indexing more convenient than the next options
// Cell map[12]; // using 1D array, but here we need to convert our 2D coordinates to a 1D index ourselves, usually by: cellIndex = y * 4 + x
std::vector<Cell> map(12); // same as 1D array but using a vector
}
Notice i have used magic numbers here, map width and height of 4 and 3.
This is actually bad, because if i decide to make the map larger or smaller, i would need to change all the code which used those magic numbers.
To do better, and reusing the HexGridSpacing struct from before, we should do something like this instead:
void InitializeMap (std::vector<Cell> &cells, const HexGridSpacing &spacing)
{
cells.clear();
cells.resize(spacing.rows * spacing.columns);
}
void main ()
{
HexGridSpacing spacing;
spacing.rows = 4;
spacing.columns = 3;
std::vector<Cell> map;
InitializeMap (map, spacing);
}
So why is this better, although it uses more code and is more complicated?
Why should we introduce a HexGridSpacing data structure just for those two simple numbers of 4 and 3?
Now we have higher complexity, and more things to keep in mind, so why all that fuzz?
The answer is simply this:
As this initial code grows into a full game we will need those two numbers very often. The render the map, to convert 2D coordinates to a 1D cell index, to find adjacent tiles, and many more.
If i would hard code the numbers 3 and 4 everywhere, changing them when needed becomes very tedious and error prone, and at some point practically impossible.
If i would use global variables or defines for those numbers, i can change them. But then all my code depends on the definition of those numbers, so i need to include the file everywhere. This becomes a real problem at a later point, when i want to reuse much of the code for another game.
So, knowing all those mistakes from experience, i have learned the hard way: It's actually better to put my definitions into a data structure which i then pass around to function which need that data. A bit more code initially, but much less in the long run, and it's also obvious which functions require which data, making the code much easier to read and maintain.
oh… i do just notice: I have diverged from the initial topic of hexgrids. Why do i do this? Because i love nitpicking about ‘programming the right way’ oh so much?
No. Actually i have surprisingly low interest in programming. I have never read Bjarnes programming bookis and i do not even know ‘the right way’ with certainty, beyond such beginner topics.
So the reason of diverging from the topic is simply: It is obvious that YOU have still problems with those basics, so this must be addressed and constantly mentioned. You're not that interested in programming either. You just want to make things work, not really caring how they work, and then moving on to the next problem.
But this does not work, and after all those years you know that yourself.
So you must learn it. There is no other way. Even if you would use AI to write code for you, you still need to know the basics to put it together.
And thus i have to ask you: We have just discovered a very nice flaw in your coding: Duplication of code 4 times to render 4 sprites in a vector.
This is the opportunity to learn. The problem is simple. Show your attempts and let's get this out of the way.
Because with flaws like this still present in your coding, it does not yet make any sense to even talk about hex grids.
So yeah, still waiting on your improved sprite rendering code… ; )