Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | alb.ots |
Hi Folks,
I’m designing a simple map navigation system for a game which is based on clickable locations. Basically, you have a map, some locations within the map and a path between locations. Assuming the player cursor is on location A, you click on location B and it will move the cursor through the path until it arrives at location B. Furthermore, since the map is designed as a TileMap, I wanted to limit the movement to cells (so it is a grid movement).
I created a new map scene with the following organization:
The reason I put Navigation2D under TileMap and define a Polygon for it (instead of using the polygons from the tileset within the tilemap) is that I sort of need to limit the size of the polygon within each cell of the TileMap to make grid movement easier.
An example instance of this scene is as below
Each instance will have several locations defined (the YSorts are all specific location scenes that inherit from a base Location scene). The way this looks is as below
I hid some objects from the scene to make it easier to see. I left two locations, City and Ruins, and as a test, I was charting the path between the City and the Ruins. If I have the Map transform at (0, 0), it works perfectly, see below:
Each round sprite is a tile within the tilemap. I’m also displaying the navigation polygon, and red crosses are debug sprites I generate at each position of the path, in addition to the line of the path. My procedure to generate the grid movement path is to, given the path between the current position and the destination position, for each position in the path I calculate the tilemap position, then recalculate the world (local position), and then center the location position by adding half the tile size to each local position within the path. The code is as below:
A signal handler responds to a signal from each children location when it is clicked within a region around it, receiving the local position of the location; current_tilemap_position stores the cursor position in the tilemap. There is bunch of debug code which I’ll show the output for after the explanation. Here is the signal handler:
func _on_location_selected(location_position) -> void:
var current_position = map_to_world(current_tilemap_position)
current_position = compute_position_centered_on_tile(current_position)
var location_tilemap_position = world_to_map(location_position)
print("Navigation: ")
print(" -> From: {0}: {1} | global: {2}".format({"0":current_tilemap_position, "1":current_position, "2":to_global(current_position)}))
print(" -> To: {0}: {1} | global: {2}".format({"0":location_tilemap_position, "1":location_position, "2":to_global(location_position)}))
var raw_path = nav_2d.get_simple_path(current_position, location_position)
print(" -> raw_path: ", raw_path)
if raw_path:
var path = compute_centered_path(raw_path)
print(" -> centered_path: ", path)
current_tilemap_position = location_tilemap_position
myline2d.points = path
myline2d.width = 3
for pos in path:
gen_debug_sprite(pos)
The other two functions are:
func compute_position_centered_on_tile(pos: Vector2) -> Vector2:
pos.x += cell_size.x/2
pos.y += cell_size.y/2
return pos
func compute_centered_path(path: PoolVector2Array) -> PoolVector2Array:
var centered_path: PoolVector2Array = []
for pos in path:
var centered_pos = map_to_world(world_to_map(pos))
centered_pos = compute_position_centered_on_tile(centered_pos)
centered_path.append(centered_pos)
return centered_path
This works fine when the position of Map is at (0, 0), with the output below:
However, since I’m dealing with local position (on both map_to_world and get_simple_path) I wanted to test what happens when I move the Map to not be at (0, 0). It totally broke my paths! This is the result when Map is at (50, 50)
and the output is:
Now the weird thing is, even though get_simple_path
is getting as input the positions (528, 240) and (1296, 176), its output starts at (570, 240) and goes to (1338, 218). I can’t figure it out what is happening here, since per the documentation, get_simple_path
should operate over local paths, so the output should be fine. Furthermore, this dislocation seens to be proportional to how much I moved Map, since for moves less than (10, 10) the output is still correct. Can you folks help me here?