Edit : I finally found the problem : I was erasing elements from the array as I was looping through it, which made the for loop broken as it would skip the value right after the erased value. Otherwise the code and system work properly. To fix it, I made a deep copy of the array and I erased elements from the copy while still looping through the original
I'm trying to modify my flood fill algorithm (grid-based game) so that it removes the cell that the player can't see (blocked by a collision tile or another player). Currently, this algorithm returns an array containing every cell that is within a certain range of the player
The solution that I tried is to add a raycast in my code that is casted on every cell before returning the array, checking for collisions between the starting cell of the algorithm and the current cell in the for loop.
The raycast doesn't work properly though, as is_colliding
method from the raycast apparently doesn't return the expected result, and the cells seem to be removed randomly. I tried to call force_update_transform
and force_raycast_update
but it doesn't fix the problem.
How can I fix this ? I tried using the debugger to make collisions visible but the raycast isn't being drawn as I loop through the array so unfortunately I can't see where its actual cast position is on the screen. It just seems to be colliding randomly (it's supposed to collide with tiles on the tilemap, I tried adjusting the collision shaped too but it doesn't fix it)
Maybe there is another solution that I can add in my algorithm to remove the right cells ?
This is the code in my flood fill function (it's placed at the end right before the function returns the array containing the cells)
if tilemap.get_occupied_cells().has(starting_cell):
var current_actor = tilemap.get_occupied_cells()[starting_cell]
raycast.add_exception(current_actor)
raycast.position = tilemap.map_to_world(starting_cell)
raycast.enabled = true
raycast.exclude_parent = false
raycast.collide_with_areas = true
raycast.collide_with_bodies = true
for cell in array:
raycast.position = tilemap.map_to_world(starting_cell) + raycast_offset
raycast.cast_to = tilemap.map_to_world(cell) - raycast.position + raycast_offset
raycast.force_update_transform()
raycast.force_raycast_update()
if raycast.is_colliding():
print(raycast.get_collider().name)
array.erase(cell)
The problem was in the for loop : erasing elements from the array as you loop through it will cause problems. I edited the post accordingly.