Godot Version
v4.2.2.stable.official [15073afe3]
Question
I have an issue where my 2d platformer player character does not interact nicely with walls when jumping against them.
Please consult this video:
Here is the code for the player character:
Click here to view
extends CharacterBody2D
@onready var animated_sprite_2d = $AnimatedSprite2D
@onready var gun_position = $GunPosition
@onready var guns = $GunPosition/SelectWeapon/Guns
@onready var player_bullet_marker = $GunPosition/SelectWeapon/Guns/PlayerBulletMarker
@onready var bullet_raycast = $GunPosition/SelectWeapon/Guns/PlayerBulletMarker/BulletRaycast
@export var speed : int = 300
@export var max_horizontal_speed = 300
@export var GRAVITY : int = 800
@export var jump_impulse : int = -300
@export var jump_horizontal_speed : int = 300
@export var max_jump_horizontal_speed : int = 300
@export var multi_jump_stacks : int = 2
var shooting : bool = false
enum State { Idle, Falling, Run, Jump, StandShoot, RunShoot, JumpShoot }
var current_state : State
func _physics_process(delta):
character_facing()
player_falling(delta)
player_idle()
player_stand_shoot()
player_run()
player_jump()
player_run_shoot()
player_jump_shoot()
move_and_slide()
player_animations()
func player_falling(delta):
if !is_on_floor():
velocity.y += GRAVITY * delta
if shooting == true:
current_state = State.JumpShoot
func player_idle():
if is_on_floor() and velocity.x == 0:
current_state = State.Idle
if !is_on_floor() and shooting == true:
current_state = State.JumpShoot
func player_run():
var direction = input_movement()
if direction:
velocity.x += direction * speed
velocity.x = clamp(velocity.x, -max_horizontal_speed, max_horizontal_speed)
else:
velocity.x = 0
if direction != 0 and is_on_floor():
current_state = State.Run
if shooting == true and is_on_floor():
current_state = State.RunShoot
func player_jump():
if is_on_floor() and Input.is_action_just_pressed("jump"):
multi_jump_stacks = 3
velocity.y = jump_impulse
current_state = State.Jump
if !is_on_floor() and current_state == State.Jump:
var direction = input_movement()
velocity.x += direction * jump_horizontal_speed
velocity.x = clamp(velocity.x, -max_jump_horizontal_speed, max_jump_horizontal_speed)
if !is_on_floor() and multi_jump_stacks > 0 and Input.is_action_just_pressed("jump"):
multi_jump_stacks -= 1
velocity.y = jump_impulse
print("Jumps remaining: ", multi_jump_stacks)
func player_stand_shoot():
if shooting == true and input_movement() == 0 and is_on_floor():
current_state = State.StandShoot
func player_run_shoot():
var direction = input_movement()
if direction:
velocity.x += direction * speed
velocity.x = clamp(velocity.x, -max_horizontal_speed, max_horizontal_speed)
if direction != 0 and is_on_floor() and shooting == true:
current_state = State.RunShoot
if direction == 0 and is_on_floor() and shooting == true:
current_state = State.StandShoot
func player_jump_shoot():
if is_on_floor() and Input.is_action_just_pressed("jump") and shooting == true:
velocity.y = jump_impulse
current_state = State.JumpShoot
elif !is_on_floor() and current_state == State.Jump and shooting == true:
current_state = State.JumpShoot
elif !is_on_floor() and current_state == State.JumpShoot and shooting == false:
current_state = State.Jump
if !is_on_floor() and current_state == State.JumpShoot:
var direction = input_movement()
velocity.x += direction * jump_horizontal_speed
velocity.x = clamp(velocity.x, -max_jump_horizontal_speed, max_jump_horizontal_speed)
func input_movement():
var direction : float = Input.get_axis("move_left", "move_right")
return direction
func character_facing():
var direction = input_movement()
if direction > 0:
animated_sprite_2d.flip_h = false
gun_position.position.x = 20
guns.scale.x = -0.255
player_bullet_marker.position.x = -36
bullet_raycast.target_position = Vector2(-1000, 0)
if direction < 0:
animated_sprite_2d.flip_h = true
gun_position.position.x = -20
guns.scale.x = 0.255
player_bullet_marker.position.x = -39
bullet_raycast.target_position = Vector2(-1000, 0)
func player_animations():
if current_state == State.Idle:
animated_sprite_2d.play("idle")
elif current_state == State.Run:
animated_sprite_2d.play("run")
elif current_state == State.Jump:
animated_sprite_2d.play("jump")
elif current_state == State.StandShoot:
animated_sprite_2d.play("stand_shoot")
elif current_state == State.RunShoot:
animated_sprite_2d.play("run_shoot")
elif current_state == State.JumpShoot:
animated_sprite_2d.play("jump_shoot")
elif current_state == State.Falling:
animated_sprite_2d.play("falling")
func _on_base_weapon_pressing_shoot():
shooting = true
func _on_select_weapon_releasing_shoot():
shooting = false