Problem with Area2D collisions

Godot Version

4.3

Question

So i have problem, i have movement, where i move from 1 tile to 1 tile. But thats totally ignores collisions with bodies and tilemaps. Also i have problem that when i move, for example, right and i click fast up or down, right with move delay(0.75), but up or down without delay and instant. Please help, code provided


@onready var camera = $Node2D/Camera2D2

var tile_size = 32
var inputs = {
	"right": Vector2.RIGHT,
	"left": Vector2.LEFT,
	"up": Vector2.UP,
	"down": Vector2.DOWN
}
var hold = {
	"right": false,
	"left": false,
	"up": false,
	"down": false
}
var moving = {
	"right": false,
	"left": false,
	"up": false,
	"down": false
}
const MOVE_DELAY: float = 0.75 # Зменшено затримку для більш швидкого руху

func _ready():
	position = position.snapped(Vector2.ONE * tile_size)
	position += Vector2.ONE * tile_size / 2

func _unhandled_input(event):
	for dir in inputs.keys():
		if event.is_action_pressed(dir):
			hold[dir] = true
			if not moving[dir]:  # Якщо не рухається, почати рух
				move(dir)
		if event.is_action_released(dir):
			hold[dir] = false

func move(dir):
	if moving[dir]:  # Якщо вже рухаємося, то не починати рух знову
		return
	if not moving[dir]:
		moving[dir] = true
		while hold[dir]:  # Поки кнопка затиснута
			# Перевірка, чи не рухаємося в протилежному напрямку
			if (hold["right"] and hold["left"]) or (hold["up"] and hold["down"]) or (hold["right"] and hold["up"]) or (hold["right"] and hold["down"]) or (hold["left"] and hold["down"]) or (hold["left"] and hold["up"]):
				break  # Якщо затиснуті дві протилежні кнопки, зупиняємо рух
			position += inputs[dir] * tile_size
		await get_tree().create_timer(MOVE_DELAY).timeout
		moving[dir] = false
type or paste code here

I’m not sure if I understood your idea correctly, but I think the same can be achieved much easier with the following piece of code. This prevents the player from making a move faster than every 0.75 seconds.

const MOVE_DELAY: float = 0.75
const TILESET_SIZE: int = 32
var is_moving: bool = false

func _ready():
	position = position.snapped(Vector2.ONE * TILESET_SIZE)
	position += Vector2.ONE * TILESET_SIZE/ 2

func _process(delta: float) -> void:
	if is_moving:
		return
	var movement_direction: Vector2 = Vector2.ZERO
	if Input.is_action_pressed("up"):
		movement_direction += Vector2.UP
	if Input.is_action_pressed("down"):
		movement_direction += Vector2.DOWN
	if Input.is_action_pressed("right"):
		movement_direction += Vector2.RIGHT
	if Input.is_action_pressed("left"):
		movement_direction += Vector2.LEFT
	
	if movement_direction != Vector2.ZERO:
		is_moving = true
		position += movement_direction * TILESET_SIZE
		await get_tree().create_timer(MOVE_DELAY).timeout
		is_moving = false

You code didn’t work because it always got stuck within the while loop that it could never exit. In general, while loops are rather dangerous to use and I would advise against them unless you really know what you’re doing.

Let me know if that works for you.