Godot Version:
4.2.2 stable
Question:
Hello everyone, nice to meet you. This is my first post here and hopefully not my last.
I am trying to recreate the game mechanics of “Ninja Gaiden” as a way to learn and train.
I am running into a “bug” that I would need help fixing. Coding is unfortunately proving extremely difficult for me and I am at my wits’ end with this one!
Bug:
Player’s “climb” animation can face the wrong direction by jumping against a wall from a wall jump when colliding with the wall while pressing the opposite direction.
It’s probably horrendous so I am sorry about that, but first here is my player’s script:
extends CharacterBody2D
@onready var sprite = $AnimatedSprite2D
@onready var wall_checker = $WallChecker
const SPEED = 100.0
const JUMP_VELOCITY = -310.0
var last_direction = 1
var direction = 1
var prev_velocity = Vector2.ZERO
var gravity: int = 900
var is_sticking = false
var is_crouching: bool = false
var is_attacking: bool
var is_wall_jumping: bool = false
func _ready():
is_attacking = false
func _physics_process(delta):
print(is_near_wall())
if direction != 0:
last_direction = direction
# ADD THE GRAVITY.
if not is_on_floor():
velocity.y += gravity * delta
prev_velocity = velocity
# HANDLE JUMP.
if Input.is_action_just_pressed("jump") and is_on_floor() and not is_attacking:
velocity.y = JUMP_VELOCITY
is_wall_jumping = false
# HANDLE CROUCH.
if not is_attacking:
if Input.is_action_pressed("crouch") and is_on_floor():
is_crouching = true
else:
is_crouching = false
# Get the input direction and handle the movement/deceleration.
var direction = Input.get_axis("move_left", "move_right")
if is_attacking and is_on_floor():
velocity.x = 0 # Stop movement during attack
else:
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
if not is_on_floor() and not is_wall_jumping:
velocity.x = lerp(prev_velocity.x, velocity.x, 0.090 / 2)
if not is_attacking and !is_sticking: # Condition to check if not sticking to a wall
if Input.is_action_just_pressed("attack"): # Check attack input only when not sticking to a wall
is_attacking = true
handle_attack_animation(delta)
set_direction()
handle_sticking()
move_and_slide()
# Update animations
handle_movement_animation(direction)
toggle_flip_sprite(direction)
func set_direction():
direction = 1 if not sprite.flip_h else -1
wall_checker.rotation_degrees = 90 * -direction
func is_near_wall():
return wall_checker.is_colliding()
func handle_sticking():
var direction = Input.get_axis("move_left", "move_right")
if !is_on_floor() and is_on_wall() and wall_checker.is_colliding():
is_sticking = true
velocity.x = 0
velocity.y = 0
sprite.play("climb")
elif !is_on_floor() and is_on_wall() and !wall_checker.is_colliding():
sprite.flip_h = direction < 0
is_sticking = true
velocity.x = 0
velocity.y = 0
sprite.play("climb")
if Input.is_action_just_pressed("jump") and is_on_wall() and wall_checker.is_colliding():
if direction != 0 and direction != last_direction:
sprite.flip_h = direction < 0
is_sticking = false
velocity.y = JUMP_VELOCITY / 1.5
velocity.x = direction * SPEED / 1
is_wall_jumping = true
func handle_movement_animation(dir):
if is_on_floor() and not is_attacking and !is_on_wall():
if velocity.length() == 0:
if is_crouching:
sprite.play("crouch")
else:
sprite.play("stand")
else:
sprite.play("run")
elif not is_on_floor() and not is_attacking and !is_on_wall():
sprite.play("jump")
func toggle_flip_sprite(direction):
if direction != 0 and is_on_floor() and !is_on_wall():
sprite.flip_h = direction < 0
func handle_attack_animation(delta):
if is_attacking and !is_on_wall():
if is_crouching:
sprite.play("crouch_attack")
else:
sprite.play("stand_attack")
if is_attacking and !is_on_floor() and !is_on_wall():
velocity.y += gravity * delta + 11 # Counteract gravity to prevent gaining height when attacking while jumping
func _on_animated_sprite_2d_animation_finished():
is_attacking = false`Preformatted text`
Here is a video in which you can see the issue occuring, which might help you understand more what the issue is:
https://www.youtube.com/watch?v=I5tYyUUE1ig
Steps to reproduce:
- Jump against a wall
- Wall jump from the same wall
- Go against the same wall or another one
- Press the direction opposite to the wall while colliding against it
- Notice the “climb” sprite is in the wrong direction
Notes:
- Issue doesn’t seem to occur when the player is jumping from the floor to the wall
- Player can still turn toward the wall when facing the wrong direction in the “climb” state
- Player cannot go back to the wrong direction once they turned back to correctly face the wall
I hope it’s enough information to help me fix it. Hopefully the code is not so bad that it needs a total overhaul haha… Also, even with help, it’s possible I don’t understand what you are trying to explain to me, so I might ask some questions again. Sorry.
Thank you!