How to keep track of tiles with Character on it without changing the ground tile?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By UserWaitingForGodot

I have a TileMap with an enum called Cells {DIRT, WALL, OUTER, PAWN} and I use set_cellv() to generate a random map using this cell types. As a child of the TileMap I have a Player (Pawn) and some enemies thas can move on the grid and aren’t supposed to move to a cell where there’s already another pawn. My collision detection system (a simple match statement for the target cell type) makes it easy to detect the collision if the cell type of the cell where these pawns are standing is Cells.PAWN, however if I do this, the pawn will be standing on an empty cell as I have no tile sprite with ID:4. Is there a way to store the position of the pawns in the TileMap class (for easier collision detection) without changing the cell type the pawn is standing on? (the only can stand on Cells.DIRT)

:bust_in_silhouette: Reply From: tuon

You can use a dictionary to map occupied tile map cells to the entity (pawn or enemy) that is occupying them. You could also store the cell coordinates on the pawn and enemy too.

var occupied_cells := {}
var pawn_tile_map_coordinates: Vector2
# determine/set coordinates variable above
occupied_cells[pawn_tile_map_coordinates] = pawn_node

Then you can check the occupied cells dictionary to see if a cell an enemy wants to move it is occupied or not.

var potential_new_enemy_tile_map_coordinates: Vector2
# set coordinates above
if !potential_new_enemy_tile_map_coordinates in occupied_cells:
  move enemy

What does the in keyword really mean/do?
Does it run in a loop through all the array?
Isn’t that a bit inefficient?

Thank you for your time :slight_smile:

UserWaitingForGodot | 2020-08-13 11:47

The “in” keyword is pretty much the same as calling the “has” method on an array or dictionary. While for a big enough array it could be inefficient, for dictionaries it’s very fast. So I suggest using a dictionary unless you know that the array’s will be small.

tuon | 2020-08-13 16:23

:bust_in_silhouette: Reply From: GameSpy

Stack tilemaps on top of each other. I always use multiple tilemaps in Godot. It’s not hard to code for multiple tilemaps. Last time I did a tilemap stack was to simulate height in my topdown game. The first tilemap had the floor tiles and the one on top the player, the enemies, the coins and the walls.

This is the solution I am using right now, thank you!
Currently I do have 2 TileMap instances in my game scene: one called simply “TileMap” which I use to place the tiles and set random textures for the dirt and walls; and another called “ColGrid” which only stores the info about occupied cells and empty cells, besides it contains a function that pawns call to check if their target cell is occupied or not.

I don’t know if you do it like this or not, every piece of advice from more experienced users is kindly appreciated :)

UserWaitingForGodot | 2020-08-13 11:53