Trouble with Moving Area2D Collisions attached to the Player

Godot Version

4.3

Question

I am making an arcade style game similar to flappy bird but you have to steal bagels of incoming people. Right now I have 4 area2D collisions set-up for the player (Bad, Okay, Good, Perfect) for scoring purposes. Right now when I playtest it, it feels like the collisions are being detected below the visual colliders.

These colliders are connected to the player who has the basic physics movement Godot provides. Is there a physics component I need to add for the area2D colliders to be registering exactly what it is shown on the screen? Below is scripts:

Player Script:

extends CharacterBody2D
class_name Player

@export var speed = 300.0
@export var jumpForce = -400

var isFreeze: bool = false

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		if not isFreeze:
			velocity += get_gravity() * delta

	# Handle jump.
	if Input.is_action_just_pressed("Jump"):
		velocity.y = jumpForce

	# Get the input direction and handle the movement/deceleration.
	# Runner Direction & Movement.
	var direction = 1
	velocity.x = direction * speed
	

	move_and_slide()
	
	if isFreeze:
		velocity.y = 0

Collect Script:

extends Area2D

@onready var game_manager: GameManager = %"Game Manager"


#Collision Bools
var isBad: bool = false
var isOkay: bool = false
var isGood: bool = false
var isPerfect: bool = false

func _process(delta: float) -> void:
	if isBad:
		game_manager.bad_score()
		print("BAD")
		queue_free()
		isBad = false
	if isOkay:
		game_manager.okay_score()
		print("OKAY")
		queue_free()
		isOkay = false
	if isGood:
		game_manager.good_score()
		print("GOOD")
		queue_free()
		isGood = false
	if isPerfect:
		game_manager.perfect_score()
		print("PERFECT")
		queue_free()
		isPerfect = false

func _on_area_entered(area: Area2D) -> void:
	if area.is_in_group("Bad"):
		if Input.is_action_just_pressed("Jump"):
			isBad = true
	if area.is_in_group("Okay"):
		if Input.is_action_just_pressed("Jump"):
			isOkay = true
	if area.is_in_group("Good"):
		if Input.is_action_just_pressed("Jump"):
			isGood = true
	if area.is_in_group("Perfect"):
		if Input.is_action_just_pressed("Jump"):
			isPerfect = true



func _on_area_exited(area: Area2D) -> void:
	if area.is_in_group("Bad"):
		if Input.is_action_just_pressed("Jump"):
			isBad = false
	if area.is_in_group("Okay"):
		if Input.is_action_just_pressed("Jump"):
			isOkay = false
	if area.is_in_group("Good"):
		if Input.is_action_just_pressed("Jump"):
			isGood = false
	if area.is_in_group("Perfect"):
		if Input.is_action_just_pressed("Jump"):
			isPerfect = false

  1. In my opinion, there is a clear error in the code related to the velocity parameter in the Player script. It uses the delta parameter “out of the box”. It turns out to be a doubling of deltatime. That is, you can’t multiply gravity by delta.
  2. And please send a screenshot of the SceneTree and the part of the scene where Area2d nodes are waiting for their turn for detection, in order to accurately cut off errors in the layout.

Thank you so much for the reply.

  1. So you are saying I should get rid of delta out of the velocity equation? Do you think I need to add anything else to it to make it work right.

image

This is my scene tree. I have tried many different things. The area colliders were all part of the player scene at one point. The collect objects were staticbodys instead of area2D (The switched to Area2D actually helped to trigger the collision at least.

The Bad to Perfect score colliders are below the player using a rectangle collider, one below the other. So what is happening is when I go test it. When the Collect object is inside the Okay collider and the spacebar is pressed to jump and collect. It shows that the Good collider was used instead (The one above the okay collider)

Thank you again for your help

1 Like

YES) That correct function should looks like:

func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		if not isFreeze:
			velocity += get_gravity()

Without delta.