Loot for 2d platformer behaves weirdly

Godot Version

4.7

Question

I want to have a treasure chest with loot flying out of it and landing on the floor. Some of the loot behaves correctly, yet some of it shoots upwards into the ceiling.
Can you see why it happens and how to prevent that?

That´s the treasure chest:

extends StaticBody2D

@onready var animated_sprite_2d: AnimatedSprite2D = %AnimatedSprite2D
@onready var area_2d: Area2D = %Area2D
var opened := false
#@export var key_needed := false
@export var content_gems_value := 5
const COLLECTIBLE_GEM = preload(“uid://bdygysy38m0h5”)

func _ready() → void:
set_meta(“treasure”, 0)
area_2d.body_entered.connect(func(body: Node2D):
if body is PlayerOLD and opened == false:
animated_sprite_2d.play(“2”)
await animated_sprite_2d.animation_finished
if animated_sprite_2d.animation_finished:
animated_sprite_2d.play(“3”)
remove_meta(“treasure”)
opened = true
spread_contents()
)
area_2d.body_exited.connect(func(body: Node2D): if body is PlayerOLD: remove_meta(“treasure”))

func spread_contents():
for gem in content_gems_value:
var gem_instance := COLLECTIBLE_GEM.instantiate()
get_tree().current_scene.add_child(gem_instance)
gem_instance.velocity.y = 0.0
gem_instance.global_position = global_position + Vector2(0.0, - 15.0)

And that´s the gem:

class_name CollectibleVariant extends CharacterBody2D

@onready var area_2d: Area2D = %Area2D

@export_enum("Gem", "Health") var type : String = "Gem"
@export var value := 1
var gravitiy := 20.0
var jump_force_y := 10.0
var jump_force_x := 5.0

func _ready() -> void:
	slide_on_ceiling = false
	floor_stop_on_slope = false
	var direction := randi_range(-1, 1)
	velocity = Vector2.ZERO
	velocity = Vector2(direction * jump_force_x, -jump_force_y)
	velocity.y = clamp(velocity.y - jump_force_y, 0.0, -jump_force_y)
	await get_tree().create_timer(0.1).timeout
	area_2d.body_entered.connect(func(body: Node2D):
		if body is PlayerOLD:
			#queue_free()
			pass
		)

func _physics_process(delta: float) -> void:
	velocity.y += gravitiy * delta
	var collision := move_and_collide(velocity * delta)
	if is_on_ceiling():
		set_physics_process(false)
	if is_on_floor():
		set_physics_process(false)

Just an idea: In the CollectibleVariant._physics_processyou disable the physics process once you hit the ceiling. It stops moving, doesn’t it? First try not doing that and if that’s going bad, what you want to do instead is give it a negative velocity.y so it falls down again and disable it only once it hits the floor.