Hey! I am trying to make an attack function, where if the player presses “E” (“attack”), the character plays an animation. However, whenever I press “E”, it only plays the first frame.
Here is the code (if something is missing, then please let me know):
@onready var animated_sprite = $AnimatedSprite2D
func _physics_process(delta):
attacking = Input.is_action_pressed("attack")
if attacking:
animated_sprite.play("attack")
Do you have other animations that the animated_sprite plays at some point? Also you should call Input.is_action_just_pressed and not is_action_pressed as this will only get called once, while is_action_pressed gets called the whole time you press the button down
Yes, here it is please ignore the random comments, last night was a long night :,D:
extends CharacterBody2D
const SPEED = 100.0
const JUMP_VELOCITY = -250.0
var playerhealth = 100 # Player's health
var playerdamage = 10 # Player's damage
#var enemyattacking = false # Enemy status
var attacking = false # Player status
#@export var enemydamage =
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var animated_sprite = $AnimatedSprite2D
#@onready var enemy = $"../enemy1"
@onready var enemy = get_node("../enemy1") # The path in the tree, not the file system.
func _physics_process(delta):
#print(health)
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var direction = Input.get_axis("left", "right")
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("e-walk")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
attacking = Input.is_action_just_pressed("attack")
#Start the attack animation when the attack button is pressed
if attacking:
animated_sprite.play("attack")
#func _input(event):
#if event.is_action_pressed("attack"):
#animated_sprite.play("attack")
func _on_area_2d_body_entered(body):
if body.name == "enemy1": # If the entered body is an enemy's then:
print("Body entered: ", body.name)
if attacking:
body.enemyhealth -= playerdamage
print("Enemy health: ", body.enemyhealth)
# this allows the player to take damage from the enemy
body.enemyattacking = true
playerhealth -= body.enemydamage
print("Player health: ", playerhealth)
if playerhealth <= 0:
get_tree().reload_current_scene()
func _on_area_2d_body_exited(body):
if body == enemy:
enemy.enemyattacking = false
Well: Do you want the ability to move during your attack? If no:
you would have to do something similar to this:
var is_attacking: bool = false
func _physics_process(delta) -> void:
if not_is_on_floor():
velocity.y += gravity * delta
if is_attacking:
return
...
...
if attacking:
animated_sprite.play("attack")
is_attacking = true
func _on_animation_finished(animation) -> void:
if animation == "attack":
is_attacking = false
And make sure to connect the animation_finished signal of the animated_sprite to the _on_animation_finished() method. Another way to determine when your attack is done is, to use a timer
I might be doing something wrong here. It still doesn’t work… I still kinda new to this, so I am sorry if, I don’t notice/understand something right away.
Code
extends CharacterBody2D
const SPEED = 100.0
const JUMP_VELOCITY = -250.0
var playerhealth = 100 # Player's health
var playerdamage = 10 # Player's damage
#var enemyattacking = false # Enemy status
var attacking = false # Player status
#@export var enemydamage =
var is_attacking: bool = false
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var animated_sprite = $AnimatedSprite2D
#@onready var enemy = $"../enemy1"
@onready var enemy = get_node("../enemy1") # The path in the tree, not the file system.
func _physics_process(delta) -> void:
#print(health)
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var direction = Input.get_axis("left", "right")
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("e-walk")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
attacking = Input.is_action_just_pressed("attack")
#Start the attack animation when the attack button is pressed
if attacking:
animated_sprite.play("attack")
is_attacking = true
func _on_animation_finished(animation) -> void:
if animation == "attack":
is_attacking = false
animated_sprite.animation_finished
#func _input(event):
#if event.is_action_pressed("attack"):
#animated_sprite.play("attack")
func _on_area_2d_body_entered(body):
if body.name == "enemy1": # If the entered body is an enemy's then:
print("Body entered: ", body.name)
if attacking:
body.enemyhealth -= playerdamage
print("Enemy health: ", body.enemyhealth)
# this allows the player to take damage from the enemy
body.enemyattacking = true
playerhealth -= body.enemydamage
print("Player health: ", playerhealth)
if playerhealth <= 0:
get_tree().reload_current_scene()
func _on_area_2d_body_exited(body):
if body == enemy:
enemy.enemyattacking = false
Now the animation plays, but it doesn’t stop. I tried turning off the “animation looping”, but now it only stops at the last frame.
Code
extends CharacterBody2D
const SPEED = 100.0
const JUMP_VELOCITY = -250.0
var playerhealth = 100 # Player's health
var playerdamage = 10 # Player's damage
#var enemyattacking = false # Enemy status
var attacking = false # Player status
#@export var enemydamage =
var is_attacking: bool = false
# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var animated_sprite = $AnimatedSprite2D
#@onready var enemy = $"../enemy1"
@onready var enemy = get_node("../enemy1") # The path in the tree, not the file system.
func _physics_process(delta) -> void:
#print(health)
# Add the gravity.
if not is_on_floor():
velocity.y += gravity * delta
if is_attacking:
return
# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var direction = Input.get_axis("left", "right")
if direction > 0:
animated_sprite.flip_h = false
elif direction < 0:
animated_sprite.flip_h = true
if direction == 0:
animated_sprite.play("idle")
else:
animated_sprite.play("e-walk")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
attacking = Input.is_action_just_pressed("attack")
#Start the attack animation when the attack button is pressed
#if attacking:
#animated_sprite.play("attack")
#is_attacking = true
#func _on_animation_finished(animation) -> void:
#if animation == "attack":
#is_attacking = false
#animated_sprite.animation_finished
func _input(event):
if event.is_action_pressed("attack"):
is_attacking = true
animated_sprite.play("attack")
func _on_area_2d_body_entered(body):
if body.name == "enemy1": # If the entered body is an enemy's then:
print("Body entered: ", body.name)
if attacking:
body.enemyhealth -= playerdamage
print("Enemy health: ", body.enemyhealth)
# this allows the player to take damage from the enemy
body.enemyattacking = true
playerhealth -= body.enemydamage
print("Player health: ", playerhealth)
if playerhealth <= 0:
get_tree().reload_current_scene()
func _on_area_2d_body_exited(body):
if body == enemy:
enemy.enemyattacking = false
you still need the _on_animation_finished() method, since this will allow you to move again. Click on your animated_sprite and go to signals. connect the animation_finished signal to the method.
EDIT: The method has to look like this: