xRegnarokx Note that z
is perhaps a wrong name to use here. Height
would be much more appropriate as it's not linked to any coordinate system. In Godot's 3d the convention is that a ground plane is in x and z directions and up is in y direction.
Here's a more elaborate "sketch" of how the whole map class could look like. Don't just copy paste this. Might not work. It's just to show the way of thinking/organizing.
class_name Map extends RefCounted
# cell data struct
class Cell:
var terrain: String = "grass"
var height: int = 0
var walkable: bool = true
func _init(iterrain: String, iheight: int, iwalakble: bool = true): # object constructor
terrain = iterrain
height = iheight
walkable = iwalakble
# map size (number of cells)
var _size: Vector2i
# map
var _cells: Array[Cell]
# pyisical cell size
var _cell_size_physical: float = 1.0 # xz size of a cell in world units
var _cell_height_pyhsical: float = 1.0 # height of a cell in world units
# initialize the size of array that holds cell data
func initialize(size: Vector2i):
_size = size
_cells.resize(_size.x * _size.y)
# returns 1D array index from 2D cell coords, depending on map size
# used to access a 1D array as if it was a 2D array
func _get_array_index(pos: Vector2i) -> int:
assert(pos.x >= 0 and pos.x < _size.x and pos.y >= 0 and pos.y < _size.y) # boundary check
return pos.x + pos.y * _size.y
func get_cell(pos: Vector2i) -> Cell:
return _cells[_get_array_index(pos)]
func set_cell(pos: Vector2i, data: Cell) -> void:
var cell = get_cell(pos)
cell.terrain = data.terrain
cell.height = data.height
cell.walkable = data.walkable
# some test utility function
func add_wall(pos: Vector2i) -> void:
set_cell(pos, Cell.new("wall", 1, false))
func add_barrel(pos: Vector2i) -> void:
set_cell(pos, Cell.new("barral", 1, true))
# etc...
Now you can use some generation algorithm to generate an actual maze or map layout into this structure. And when you have that, you can proceed to make a visual representation of it in either 2d using fake ortho perspective or in 3d using actual geometry.
If you prefer visual editing of the map, You can make an actual GridMap with some tiles etc... and write an utility script that interprets what's in the GridMap and populates your data structure.
Alternatively you could implement the same data structure as an extension of a GridMap node, making it more coupled with actual 3D graphics, but the way of thinking about and organizing map data would be exactly the same. You need a "logical" structure that's "underneath" the visual representation.
The movement comes after this, because the movement system needs this for proper functioning. You can't really have a grid based movement system without some data in a grid 😃