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