Godot engine 4.2.2

Godot version

4.2.2

Question

I am making a two 2D game that requires the player to be able to run in both directions, jump and fly, so far I have developed running and jumping, but when I press to run to the left it leaves a large empty space and then it stops. Please run help to solve this problem and finish programming the functions to fly.

extends CharacterBody2D

@export var speed = 300
var saltar = 400
var is_facing_right= true
var gravity = ProjectSettings.get_setting(“physics/2d/default_gravity”)
@onready var sprite = $Animplayer/Sprite
@onready var Animplayer = $Animplayer/AnimationPlayer

movimientos del player

func _physics_process(delta):
move_x()
jump(delta)
flip()
move_and_slide()
update_animations()

velocity.x = 0

animaciones

func update_animations():

if not is_on_floor():
	if velocity.y < 0:
		$AnimationPlayer.play("Saltar")
	else:
		$AnimationPlayer.play("Caer")
	return

if velocity.x:
	$AnimationPlayer.play("Correr")
else:
	$AnimationPlayer.play("De pie")

voltear player

func flip():
if (is_facing_right and velocity.x < 0) or (not is_facing_right and velocity.x > 0):
scale.x *= -1
is_facing_right = not is_facing_right

movimiento derecha

func move_x():
var input_axis = Input.get_axis(“Izquierda”,“Derecha”)
velocity.x = input_axis * speed

saltar

func jump(delta):
if Input.is_action_just_pressed(“Saltar”)and is_on_floor():
velocity.y = -saltar

if not is_on_floor():
	velocity.y += gravity * delta

I’m guessing the sudden jump to the left is because you are doing

velocity.x = input_axis * speed

Instead of

velocity.x input_axis * speed * delta

There are a few ways you could simplify this. Godot has a built in function to flip a sprite when needed, so the func flip() can be omitted. For the rest of it, you could use a state system, which can set things like which animations for what is happening at the time like jumping, standing still, running etc. It also means that if you want to add additional states, etc. falling, then they are easier to implement.

I’ve put together a simple script for your player character that you could use. I’ve commented it as best I can, but if you have any questions I’ll do my best to help. This script assumes you are using a Character2D and it is what the script is attached to.

extends CharacterBody2D

const SPEED = 800.0
const JUMP_VELOCITY = -400.0

# The enum below contains the states that we can be in
enum {IDLE, RUN, JUMP}

# Set the starting state
var state  = IDLE

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


func _ready() -> void:
	# Although we set the variable above
	# We actually need the set_state function
	# to do the work
	set_state(state)

func set_state(new_state) -> void:
	state = new_state
	
	match state:
		IDLE:
			# play the idle animation
			#$AnimationPlayer.play("idle")
			pass
		
		RUN:
			# play the running animation
			#$AnimationPlayer.play("run")
			pass
		
		JUMP:
			# play jump animation
			#$AnimationPlayer.play("jump")
			pass


func get_input():
	
	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY
		set_state(JUMP)

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	# This is template code put in by Godot for Character2D
	var direction := Input.get_axis("ui_left", "ui_right")
	
	if direction:
		velocity.x = direction * SPEED
	else:
		# If there is no direction being pressed
		# Decelrate the movement to 0 in the next line 
		# velocity.x = move_toward(velocity.x, 0, SPEED)
		# Alternatively stop immediately in the next line
		velocity.x = 0
		
	
	# Godot has a built in function to flip the sprite
	# Depending on your sprite you may need to switch these round
	# If we are going right
	if velocity.x > 0:
		$Sprite2D.flip_h = true
	# If we are going left
	if velocity.x < 0:
		$Sprite2D.flip_h = false
	
	# IDLE state transitions to RUN when moving
	if state == IDLE and velocity.x != 0:
		set_state(RUN)
		
	# Transition to IDLE when not moving
	# If we are using deceleration above then there is a slight delay
	# as we slow to a stop
	if state == RUN and velocity.x == 0:
		set_state(IDLE)

func _physics_process(delta: float) -> void:
	
	get_input()
	
	# Add the effect of gravity
	# We do this here and not in get_input as
	# it's dealt with by physics
	if not is_on_floor():
		velocity.y += gravity * delta
	
	# Process the input velocities
	move_and_slide()
	
	# Because jumping is affected by physics
	# Putting this in get_input would report being on
	# the floor straight after jumping rather
	# than when we are on the floor
	if state == JUMP and is_on_floor():
			set_state(IDLE)
1 Like

Thank you very much, if it works I hope you can continue helping me with any questions I have and without a doubt at the end of my game I will show you how it turned out.

I’m not an expert, but I’ll do my best to help.

1 Like