Godot Version
Godot Engine v4.3.stable.official.77dcf97d8
Question
This is my first time trying to make a game, and I have no prior experience with any script, I’m trying to make a 2D platformer (Mario/Metroid/Megaman (other “M” names) style).
I can only get my idle and walk animations to work, and I don’t know how to fix it. I’m trying to add a “roll” and a faster “run” animation, plus I want to add a timer to the idle animation if no inputs have been made. Sorry about the spaghetti. Can someone help?
extends CharacterBody2D
@export var walk_speed = 75.0
@export var run_speed = 150.0
@export_range(0, 1) var acceleration = 0.1
@export_range(0, 1) var deceleration = 0.1
@export var jump_force = -300.0
@export_range(0, 1) var decelerate_on_jump_release = 0.5
@export var roll_speed = 1000.0
@export var roll_max_distance = 60.0
@export var roll_curve : Curve
@export var roll_cooldown = 1.0
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
var is_rolling = false
var roll_start_position = 0
var roll_direction = 0
var roll_timer = 0
func _physics_process(delta: float) → void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
animated_sprite_2d.play(“p_jump”)
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_force
if Input.is_action_just_released("jump") and velocity.y < 0:
velocity.y *= decelerate_on_jump_release
# Run
var speed
if Input.is_action_pressed("run"):
speed = run_speed
animated_sprite_2d.play("p_run_fast")
else:
speed = walk_speed
# Get the input direction: -1, 0, 1
var direction := Input.get_axis("move_left", "move_right")
if direction:
velocity.x = direction * speed
animated_sprite_2d.play("p_run_walk")
animated_sprite_2d.flip_h = direction < 0
else:
velocity.x = move_toward(velocity.x, 0, speed)
animated_sprite_2d.play("p_idle")
# Roll activation
if Input.is_action_just_pressed("roll") and direction and not is_rolling and roll_timer <= 0:
is_rolling = true
roll_start_position = position.x
roll_direction = direction
roll_timer = roll_cooldown
animated_sprite_2d.play("p_roll")
# Preform Roll
if is_rolling:
var current_distance = abs(position.x - roll_start_position)
if current_distance >= roll_max_distance or is_on_wall():
is_rolling = false
else:
velocity.x = roll_direction * roll_speed * roll_curve.sample(current_distance / roll_max_distance)
velocity.y = 0
# Roll Timer
if roll_timer > 0:
roll_timer -= delta
# Apply movement
if direction:
velocity.x = move_toward(velocity.x, direction * speed, speed * acceleration)
else:
velocity.x = move_toward(velocity.x, 0, walk_speed * deceleration)