How would I have an entity interact with a tilemap

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

Hello, I have an entity that isn’t bound by input from the player, instead, it spawns from a tile on the tilemap and changes direction on collision. When the entity is instanced, I would like to have some sort of way to access some data from the tilemap. I have tried making a tilemap singleton but it was causing unwanted behavior.

enter image description here

I want the entity to know about its neighbor tiles specifically, up, down, left, and right.

:bust_in_silhouette: Reply From: Inces

You just want to get built-in tilemap data like tile index ?
All You need to do is to translate entity position to worldtomap ( which You already did since entity is aligned ti tilemap ) and do something like this :

var pos = #translated position here
var neighbours = []
for x in range(-1,1):
     for y in range(-1,1):
          var tile = pos + Vector2(x,y)
          if not neighbours.has(tile) and tile != pos :
                    neighbours.append(tile)
return neighbours

number in range() can be replaced by any number and it will indicate size of a square within You want to get neighbouring tiles. This actually checks for neighbours in 8 directions. IF You don’t want diagonals You can replace whole double for loop with :

for x in [Vector2(1,0), Vector2(-1,0),Vector2(0,1),Vector2(0,-1)]

neighbours will contain array of all tiles surrounding entity. You can iterate thrrough this array to ask tilemap for any data regarding these tiles, like :

for tile in neighbours:
      if get_cell(tile) == -1:
            print("empty")

Hey Inces! Thank you so much for this response, but the problem im having is when the entity is instanced I have no way of updating its position during runtime.

So my structure is like this:

enter image description here

its cropped here but I clicked on a block and it spawned in an entity(its called an orcho)
and added it as a child of tilemap. Am I structuring it badly?

zephy | 2022-01-21 00:22

But You did code collision bouncing behavior somewhere ? I thought entity has a script. I would add a script to entity and make setget variable indicating current tile like this :

var tilepos = Vector2(0,0) setget settilepos

func physics process():
       self.tilepos = $Tilemap.world_to_map(global_position)

settilepos(value):
      if tilepos != value:
            tilepos = value
            #your methods happening on entity approaching new tile here

If You don’t want to script entity You can do it from higher scope, but You need to keep reference to entity when adding it as a child, and get/translate its global position in the same way

Inces | 2022-01-21 13:35

Thank you so much!!! Turns out I needed to use the _init() method since I didnt want the parent(tilemap) to wait for the instanced objects during runtime. Thank you so much for your help!

zephy | 2022-01-22 23:52

Hey, do you have a discord? If you are not busy could you help me out with another problem?

zephy | 2022-01-27 16:29

You are welcome :slight_smile: I don’t have discord, I only have a time to answer forum questions from time to time, so post it in Questions :wink:

Inces | 2022-01-27 18:19

Got it! I was working on my game and it seems that my solution was only for the short term since it caused behavior I didn’t want. the setter function that you have above, I cant use that since my entity doesn’t know the location of tilemap during runtime. I have a feeling that I am doing this the wrong way. enter image description here

In the remote tree the entity’s (orcho’s) are not a child of tilemap. So the problem that I have is during runtime, the orcho’s dont know anything about the tilemap except for the built-in collision that I added to the tilemap.

zephy | 2022-01-28 05:00

But You can use it, all You need is proper reference leading to TileMap, introduced as onready variable. If I see correctly, TileMap is a sibling of entity.
In entity script :

onready var tilemap = get_parent().get_node("TileMap")

Wherever TileMap is in the scenetree You can always input its proper path into reference like this and then in my setter replace $Tilemap with this tilemap variable
By the way, what is the problem with TileMap being parent of entities ? It will propably make future sollutions easier.

Inces | 2022-01-28 14:10

OMG… I finally understand! Thank you so much I got it working!!! When I had it as a child of tilemap there was no real problem I just didn’t know what to do before the step that you just gave me. Ok, its official it works for real this time.

zephy | 2022-01-28 14:48