BenjaTK / Gaea

Procedural generation add-on for Godot 4.
https://benjatk.github.io/Gaea/
MIT License
1.11k stars 55 forks source link

Handle Hexagon-based tilemaps #141

Open jamesnunn opened 3 months ago

jamesnunn commented 3 months ago

I've tried using Gaea with my hex map but encountering some strange behaviour when using the chunking tools. It seems the actor position is calculated with square tiles in mind and there are multiple other places in the code where hexes aren't handled (e.g. grid_2d.gd SURROUNDING).

I'd be willing to contribute but this is my first time with Godot (but an experienced developer otherwise) so if you have pointers to parts of the code I'd need to focus on that will help me grok from there onwards I will give it a shot.

BenjaTK commented 3 months ago

Oh that's a good point, hadn't thought about that. Maybe we can add a tile_shape property in ChunkLoader and an enum for that, then check what type is selected when calculating.

jamesnunn commented 3 months ago

The map generation seems fine, it was just the chunk loading that wasn't behaving nicely. Would it only be the chunk loader calcs that need attention?

BenjaTK commented 3 months ago

Yup

jamesnunn commented 3 months ago

image

Does this look like anything obvious to you why there is a void around the centre tile 0,0 where the actor is (actually the actor is offset by 1,1 because I'm using mouse coords without correcting position, 0,0 is the top left green tile of the 2x2 block)? I got the chunk loader working but those ones refuse to render.

jamesnunn commented 3 months ago

Never mind, it was the load_on_ready flag set to true

BenjaTK commented 3 months ago

So setting load_on_ready to true fixed it? Or the other way? I feel like it should be the first one.

jamesnunn commented 3 months ago

Yes but I hadn't actually got as far as implementing it all the way through the various chunkloader calls and signals yet so there was some weirdness going on that I can't explain.

cullumi commented 1 month ago

@monotonehell over in the Discord suggested the following as a starting place for at least fixing the issue with the actor's position.

### in generate_2d.gd

## Returns the map coordinates of the cell containing the given [param global_position].
func global_to_map(pos: Vector2) -> Vector2i:
    return $"Ground-TileMapLayer".local_to_map(pos)

## Returns the global position of the cell at the given [param map_position].
func map_to_global(map_position: Vector2i) -> Vector2:
    return $"Ground-TileMapLayer".map_to_local(map_position)

Passing in the appropriate layers would make it so we're always transforming our position appropriately without having to bake up our own implementation. In fact, we could totally use a composition-based approach that could wrap TileMapLayers or just our own personal implementation however we want. A field for a "TileSettings" object or something like that.