Sprite Jitters on wall and ceiling

Godot Version

Godot 4.2.1

Question

Trying to make a platformer where you can reverse gravity at will by pressing G (This works).

The problem is when the sprite is upside down and goes to one of the upper corners, it jitters on collision with the wall (This does not happen when the sprite is right side up).

The collision mask is a square. Below is the code for the sprite.

Please what am I doing wrong?

Thank you very much.

Code:

extends CharacterBody2D


const SPEED = 400.0
var JUMP_VELOCITY = -900.0
@onready var sprite_2d = $Sprite2D

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")


func _physics_process(delta):

	if is_on_ceiling() && is_on_wall():
		velocity.x = 0
	
	# Animation
	if (velocity.x > 1 || velocity.x < -1):
		sprite_2d.animation = "running"
		
	else:
		sprite_2d.animation = "default"
	
	# Player is in mid air
	if not (is_on_ceiling() || is_on_floor()) : 
		velocity.y += gravity * delta
		sprite_2d.animation = "jumping"
		
	if is_on_floor() && gravity > 0: # normal gravity, standing on floor
		velocity.y = 0
	elif is_on_ceiling() && gravity < 0: # upside down gravity, standing on ceiling
		velocity.y = 0
	elif is_on_ceiling() && gravity > 0: # right side up bumping head
		velocity.y += gravity * delta # fall
	elif is_on_floor() && gravity < 0: # upside down bumping head with floor
		velocity.y += gravity * delta # fall
		
	# Handle jump.
	if Input.is_action_just_pressed("jump"): # and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Handle jump.
	if Input.is_action_just_pressed("gravity (Upside Down)"): # and is_on_floor():
		velocity.y = JUMP_VELOCITY
		gravity = -gravity #
		JUMP_VELOCITY = -JUMP_VELOCITY #
		if gravity < 0: #
			sprite_2d.flip_v = true #
		else: #
			sprite_2d.flip_v = false #
	

		
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction = Input.get_axis("left", "right")
	if direction:
		if is_on_ceiling() && is_on_wall():
			velocity.x = 0
		else:
			velocity.x = direction * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, 12)

	move_and_slide()
	

	if velocity.x != 0:	
		var isLeft = velocity.x < 0
		sprite_2d.flip_h = isLeft

Hi, I pasted your code into a test project and I do not see any jittering. Can you post a video of what it looks like?

Here is the link to the video (I’m a new user so it doesn’t let me put the video clips directly here): Upside_Down_Character_Jittering.mp4 - Google Drive

BTW, when walking upside down going into the left corner, holding the left key down and it jitters. The same thing
happens when walking upside down going into the right corner, holding the right key down and it also jitters.

Oh, it’s jittering from the animation. I deleted the animation code because I didn’t have one.

Here is the issue:

	if is_on_floor() && gravity > 0: # normal gravity, standing on floor
		velocity.y = 0
	elif is_on_ceiling() && gravity < 0: # upside down gravity, standing on ceiling
		velocity.y = 0
	elif is_on_ceiling() && gravity > 0: # right side up bumping head
		velocity.y += gravity * delta # fall
	elif is_on_floor() && gravity < 0: # upside down bumping head with floor
		velocity.y += gravity * delta # fall

You need to apply gravity every frame if you want the is_on_ceiling() and is_on_floor() check to work. If velocity is 0 then it’s not moving into the ceiling or ground. So don’t selectively apply gravity. Replace it with this:

	velocity.y += gravity * delta

and the jittering should go away.

2 Likes

Thank you so much! That did it.
I am new to Godot and I misunderstood the purpose of is_on_X functions.

Thanks again.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.