Moving player sprite inside an area and detect collisions to stop movement

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

I’m coding a sprite moving through an environment as the player clicks on the desired location. This part I got working no problem, but I also want the movement to be blocked, that is, the player cannot walk in the sky, for example. So I made an area2D with a collision polygon:

But now I don’t know how to make the player stop and not go further when a collision is detected. First I don’t know what to put where the print is. Another bug is that the collision is only being detected when the feet of the player exit the ground collisionpolygon which I understand is the intended way area_exited signal works… but the bug must be solved.

Here is the code:



extends Node

var cursor_position = null

onready var Feet = $Player/PlayerSprite/Area2D
onready var Player = $Player/PlayerSprite

func _input(event):
	if event is InputEventMouseButton and event.pressed and event.button_index == BUTTON_LEFT:
		cursor_position = event.position
		return cursor_position

func _physics_process(delta):
	var speed = 200
	if cursor_position != null and Player.position != cursor_position:
		var direction_to_event = (cursor_position - Player.position).normalized()
		var movement_vector = direction_to_event * speed * delta
		var new_position = Player.position + movement_vector
		var distance_to_event = Player.position.distance_to(cursor_position)
		
		if movement_vector.length() > distance_to_event:
			Player.position = cursor_position
		else:
			Player.position = new_position

func _on_Area2D_area_exited(area):
	if area == Feet:
		print("collided")

What to code instead of the print?

To solve the bug mentioned above a kind of inverted collision polygon would work, an area with a hole in the middle, but I haven’t found out how to do it, I’m fairly new to coding.

I started looking into move_and_slide and move_and_collide and tried a few iterations, but honestly it left me more confused. All the videos and solutions I’ve found talking about kinematic body are about 2D side scrolling movement, which is not this use case. Would move_and_x be good in this case?

I think the crux of the problem is trying to solve for collisions when the 2 areas are supposed to work inside of one another… But I don’t know at this point how else to do it. Suggestions appreciated.

:bust_in_silhouette: Reply From: godot_dev_

To solve one of your bugs, the bug involving the collision detection occurring only when the feet exit the area, use the area_entered signal instead of the area_exited signal of the Area2D. This way the frame your player enters the sky, the collision will occur.

It doesn’t work, it detects a collision initially and then only when the 2 areas touch again after the feet of the sprite being completely outside

jmn_sts | 2023-05-12 19:50