Godot Version
4.3.stable
Question
So im making a game with grid-based top down movement, since i want to change the grid size during the gameplay ive implemented all of the tilemap logic inside a script using set_cell and various other methods of the tilemap layer class.
After doing the logic to create a base 8 by 5 grid and some basic methods (add/remove column/row) ive decided to make some sprites instead of using the good old godot sprite and ive made two of them that i want position in a checkered pattern. So ive got atlas coords 1,0 being the first sprite and atlas coords 2,0 being the other one (0,0 is empty).
After that i had to implement a way for the game to choose the right tile from the tileset.
For the base grid ive used this code.
func _ready():
first_column = 0
last_column = 7
first_row = 0
last_row = 5
var counter = 1
#create base grid
for y in 5:
for x in 8:
if counter % 2 == 0:
set_cell(Vector2i(x,y), 0, Vector2i(2,0))
else:
set_cell(Vector2i(x,y), 0, Vector2i(1,0))
counter += 1
counter += 1
So to decide what tile to use i divide the counter by 2 and depending on if it has a remainder or not i choose the tile.
But for the methods that create new columns/rows it was different and this approach didnt work so after some brainstorming and thinking ive made those 2 utility methods.
func get_neighbor_cells_atlas_coords(cell : Vector2i) -> Array[int]:
var neighbor_cells_atlas_coords : Array[int] = []
#get_surrounding_cells returns an array of Vector2i like this [rightcell, downcell, leftcell, upcell
for item in get_surrounding_cells(cell):
neighbor_cells_atlas_coords.append(get_cell_atlas_coords(item).x)
return neighbor_cells_atlas_coords
func choose_atlas_coords(cell : Vector2i) -> Vector2i:
var neighbor_cells_atlas_coords = get_neighbor_cells_atlas_coords(cell)
if (neighbor_cells_atlas_coords[0] == -1 or neighbor_cells_atlas_coords[0] == 2) and (neighbor_cells_atlas_coords[1] == -1 or neighbor_cells_atlas_coords[1] == 2) and (neighbor_cells_atlas_coords[2] == -1 or neighbor_cells_atlas_coords[2] == 2) and (neighbor_cells_atlas_coords[3] == -1 or neighbor_cells_atlas_coords[3] == 2):
return Vector2i(1,0)
else:
return Vector2i(2,0)
With those i check the neighbors and see what tile they use and decide depending on that and it works but as you can see the choose_atlas_coords is kinda convoluted. Do you know how i could optimize it?
Also those are the column/row methods
func new_left():
for cell in get_used_cells():
if cell.x == first_column:
set_cell(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_LEFT_SIDE), 0, choose_atlas_coords(Vector2i(cell.x -1, cell.y)))
first_column -= 1
func new_right():
for cell in get_used_cells():
if cell.x == last_column:
set_cell(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_RIGHT_SIDE), 0, choose_atlas_coords(Vector2i(cell.x +1, cell.y)))
last_column += 1
func new_up():
for cell in get_used_cells():
if cell.y == first_row:
set_cell(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_TOP_SIDE), 0, choose_atlas_coords(Vector2i(cell.x, cell.y +1)))
first_row -= 1
func new_down():
for cell in get_used_cells():
if cell.y == last_row:
set_cell(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_BOTTOM_SIDE), 0, choose_atlas_coords(Vector2i(cell.x, cell.y -1)))
last_row += 1