Grid Movement, not working

Godot Version

4.2.1

Question

I want to make a grid-based puzzle game. I already wrote the movement script but it doesent work.

extends Node2D

@onready var tile_map = $"../TileMap"

func move(dir: Vector2):
	var current_tile: Vector2i = tile_map.local_to_map(global_position)
	print(current_tile.x, current_tile.y)
	var target_tile: Vector2i = Vector2i(
		current_tile.x + dir.x,
		current_tile.y + dir.y,
	)
	var tile_data: TileData = tile_map.get_cell_tile_data(0, target_tile)
	if tile_data.get_custom_data("walkable") == false:
		return
		
	global_position = tile_map.map_to_local(target_tile)
		
	
#func _on_level_swipe_down():
#	move(Vector2.DOWN)
#	
#func _on_level_swipe_left():
#	move(Vector2.LEFT)
#
#func _on_level_swipe_right():
#	move(Vector2.RIGHT)
#
#func _on_level_swipe_up():
#	move(Vector2.UP)

func _process(delta):
	if Input.is_action_just_pressed("ui_up"):
		move(Vector2.UP)
	elif Input.is_action_just_pressed("ui_down"):
		move(Vector2.DOWN)
	elif Input.is_action_just_pressed("ui_right"):
		move(Vector2.RIGHT)
	elif Input.is_action_just_pressed("ui_left"):
		move(Vector2.LEFT)

And this is what my game looks like:


This happens if i move

The documentation says that TileMap.local_to_map() uses local position, but you’re using global_position. This will cause problems, if the TileMap’s position or scale is changed from the default values.

If the movable object is a child of the TileMap, you can use

var current_tile: Vector2i = tile_map.local_to_map(position)
...
position = tile_map.map_to_local(target_tile)

and if not, you can do as the documentation suggests and use Node2D.to_local().

var local_position: Vector2 = tile_map.to_local(global_position)
var current_tile: Vector2i = tile_map.local_to_map(local_position)
...
global_position = tile_map.to_global(tile_map.map_to_local(target_tile))

Also, I suggest using Vector2i type for dir, and then you can get target_tile easily with a single line.

var target_tile: Vector2i = current_tile + dir