Hello, I am trying to implement a double jump into my game and I am unsure of how to implement a different animation for it, what would I type to get that outcome.
extends CharacterBody2D
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
const SPEED = 975.0
@export var jump_velocity : float = -1300.0
var isAttacking: bool = false;
var AttackPoints = 3;
#double jump
var jump_count = 0
var max_jumps = 2
func _physics_process(delta: float) -> void:
if isAttacking:
return
# add animation
if velocity.x > 1 or velocity.x <-1:
$AnimatedSprite2D.play("Run")
else:
animated_sprite_2d.animation = "Idle"
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
$AnimatedSprite2D.play("Jump")
if is_on_floor():
jump_count = 0
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor() and jump_count < max_jumps:
velocity.y = jump_velocity
jump_count += 1
# Get the input direction and handle the movement/deceleration.
var direction := Input.get_axis("left", "right")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
#attack
if Input.is_action_just_pressed("attack") and not isAttacking and is_on_floor() && AttackPoints == 3:
$AttackResetTimer.start();
$AnimatedSprite2D.play("Attack_1")
isAttacking = true;
$AttackArea/CollisionShape2D.disabled = false;
AttackPoints = AttackPoints - 1;
elif Input.is_action_pressed("attack") and not isAttacking and is_on_floor() && AttackPoints == 2:
$AttackResetTimer.start();
$AnimatedSprite2D.play("Attack_2");
isAttacking = true;
$AttackArea/CollisionShape2D.disabled = false;
AttackPoints = AttackPoints - 1;
elif Input.is_action_pressed("attack") and not isAttacking and is_on_floor() && AttackPoints == 1:
$AttackResetTimer.start();
$AnimatedSprite2D.play("Attack_3");
isAttacking = true;
$AttackArea/CollisionShape2D.disabled = false;
AttackPoints = AttackPoints - 1;
if Input.is_action_just_pressed("attack") and not isAttacking and not is_on_floor():
$AttackResetTimer.start();
$AnimatedSprite2D.play("Jump Attack");
isAttacking = true;
$AttackArea/CollisionShape2D.disabled = false;
#Direction
if direction == 1:
animated_sprite_2d.flip_h = false
$AttackArea/CollisionShape2D.position.x = 175
$CollisionShape2D.position.x = 110
elif direction == -1:
$AttackArea/CollisionShape2D.position.x = -50
animated_sprite_2d.flip_h = true
$CollisionShape2D.position.x = 15
if isAttacking:
velocity = Vector2.ZERO
func _on_animated_sprite_2d_animation_finished() -> void:
if isAttacking:
isAttacking = false;
$AttackArea/CollisionShape2D.disabled = true
func _on_attack_reset_timer_timeout() -> void:
AttackPoints = 3;
I recommend that you make the tutorials in the docs, and also godot creates a default characterbody script when you create it in the editor, that should be your base.
there are random brackets all over the code (;)
this ends the entirety of _physics_process early.
you need to run move_and_slide() to make your character collide with the world.
also gravity is not applied.
use a state machine for the different states of the character, ESPECIALLY because you are using an AnimatedSprite, that NEEDS a state machine.
otherwise use a Sprite2D with AnimationPlayer and AnimationTree.
create a reference to these nodes. don’t use $. doing $node_name is equivalent to doing get_node("node_name"). it’s also messy and makes the code difficult to read.
do AttackPoints -= 1
this is never going to run because of the first line.
find all the expressions that do the same and combine them.
that return should be after setting velocity to ZERO, IF it’s actually needed.
this runs every time an animation finishes, not just on attack animation. meaning you are disabling the collision shape every time an animation finishes.
start by cleaning up your code.
I would say you are using the same animation for jumping as for falling.
use a state machine, when jumping go into the jump state, if double jumping go into the double jump state. and upon landing, if you are on the jump state, change back to idle.
and if the jump animation is supposed to play once and transition, use a timer and change the state to falling, and when it lands, if it’s on falling state, change to idle.
idle could do more than just standing, it can be movement as well, until it stops touching the ground or jumps, or attacks.
It’s also etiquette to not be unnecessarily rude when people are asking questions especially when you’re not going to answer their question. If someone is going to a forum to ask questions, they’re obviously looking for a more personalized answer. And its beneficial to no one to be condescending to someone who is trying to learn while also being wrong about multiple things in the process, the only beneficial thing from their response was to link to a tutorial because on principle if you can’t help, linking to a resource that might is a good thing and the suggestion to clean up my code because what looks clear to me as a beginner who’s learning doesn’t necessarily mean that it is to others despite people who have looked over it being able to understand it easily
Most of @jesusemora’s remarks are on point though. The code snippet you posted has quite a few fundamental problems. Implementing a double jump before first addressing those would not make much sense.