Godot Version
4.6.2
Question
As practice, I’ve been challenging myself to try and create a very basic 2D tile-based map where the coordinates of a map are stored in either a 2D array or dictionary.
I want to do all this without using Godot’s built-in TileMap/TileMapLayer features.
As an example, I’m trying to create a grid that would correspond to 49 x 54 in size in pixels, and a cell_size of 422 x 212. My final goal is to use a chess-set image over it, with the visuals and data logic separated.
This is what I mean. This grid would actually be created purely in code, with the visual logic being entirely separate.
My issue is I’m having trouble wrapping my head around on how I would translate a 2D array/dictionary into an “invisible” grid? And I can’t find any resources tackling this topic that aren’t from 8 years ago.
Here’s the start of my code, through there isn’t much
class_name GridManager
extends Node2D
enum {
EMPTY, PASSABLE
}
var tile_size: float = 49.0
#Tile size and cell size in pixels, stored in dictionary
var grid: Dictionary = {
"tile_size": Vector2i(49, 54),
"cell_size": Vector2i(422, 212),
}
func get_world_position(x: float, y: float) -> Vector2:
return Vector2(x, y) * tile_size
func is_cell_vacant(pos: Vector2, target_pos: Vector2) -> bool:
pass
I would advice against using a dictionary just for storing two often used variables. Just use variables:
var tile_size := Vector2i(49, 54)
var cell_size := Vector2i(422, 212)
The easiest way to use dictionary for the grid is just to use the cell position as a key. Here, I’m assuming that an int is good enough to tell what the cell contains. But that could be String or float or Dictionary or whatever.
var grid: Dictionary[Vecto2i, int]
for y in 212:
for x in 422:
grid[Vector2i(x, y)] = <cell content, whatever it is>
If you are willing to convert your tiles to TextureRects, a GridContainer might be a good solution for you.
Thanks for this, its helping me on the right track.
What I want to do is, through the player script, determine if each tile is walkable or not. I suppose in my case right now, all the tiles in this grid would be walkable.
So essentially I want to convert the coordinates stored in the dictionary or 2D array (depending on what I go with, leaning towards dictionary) into data to create the walk area for the player.
I was thinking of using a boolean that determines if the player can move or not. Would this be sound?
Is the movement going to be like on a chess board, player moves from cell to cell? If yes, then bool per cell will be fine.
Continuing on with Dizzy_Caterpillars logic…
A cell is going to be an important object in this game no matter which way you take it.
This is a perfect candidate for a class.
class_name Cell
var walkable:bool = true
var what_is_on_me:ChessPiece = null
var address:Vector2
var index:int
# you will know what kinds of things to build out the class
and then it is
grid[Vector2i(x, y)] = Cell.new()
This is really putting me on the right track, thank you! Do you mind explaining a little on how I could use the address and index variables?
The address is the row,col coordinate in the tile grid; top left cell being at 0,0, then 0,1 and on.
The index is an integer corresponding to the linear set of cells; top left cell being 0, then 1 and on.
Neither are absolutely necessary. I just remember that every time I do a grid I end up using at least one of those systems to locate cells.