extends CharacterBody2D
enum STATE {ON_IDLE,ON_FOLLOW,ON_ATTACK,ON_HURT,ON_DEATH}
var current_state = STATE.ON_IDLE
var crabGravity = 5000
var crabHealth = 3
@export var crabSpeed = 50
@onready var captainCharacter = $"../Captain"
@onready var crabSprite = $AnimatedSprite2D
func _ready():
current_state = STATE.ON_IDLE
func _physics_process(delta):
velocity.y += crabGravity * delta
if velocity.x <= 0:
crabSprite.flip_h = false
elif velocity.x >= 0:
crabSprite.flip_h = true
else:
current_state = STATE.ON_IDLE
if crabSprite.flip_h == true:
$CollisionShape2D.position.x = -1
$CrabDedectArea/CrabDedectCollision.position.x = 63
$CrabHurtBox/CrabHurtCollision.position.x = -1
elif crabSprite.flip_h == false:
$CollisionShape2D.position.x = 1
$CrabDedectArea/CrabDedectCollision.position.x = -63
$CrabHurtBox/CrabHurtCollision.position.x = 1
if current_state == STATE.ON_IDLE:
crabSprite.play("CrabIdle")
velocity.x = 0
if current_state == STATE.ON_FOLLOW:
crabSprite.play("CrabRun")
var crabDir = global_position.direction_to(captainCharacter.global_position)
velocity = crabSpeed * crabDir
velocity.y += crabGravity * delta
move_and_slide()
if current_state == STATE.ON_ATTACK:
crabSprite.play("CrabAttack")
if current_state == STATE.ON_HURT:
crabSprite.play("CrabHurt")
if current_state == STATE.ON_DEATH and crabSprite.flip_h == true:
crabSprite.play("CrabDeath")
velocity.x = 0
if current_state == STATE.ON_DEATH and crabSprite.flip_h == false:
crabSprite.play("CrabDeath")
velocity.x = 0```
#when my character hits the enemy from the left side the enemy dies but if my character hits from the
1 messages · Page 1 of 1 (latest)
func _on_crab_dedect_area_body_entered(body):
if body.is_in_group("Player"):
current_state = STATE.ON_FOLLOW
func _on_crab_dedect_area_body_exited(body):
if body.is_in_group("Player"):
current_state = STATE.ON_FOLLOW
func _on_crab_hurt_box_area_entered(area):
if area.is_in_group("CaptainHitBox"):
current_state = STATE.ON_HURT
crabHealth -= 1
print(crabHealth)
func _on_crab_hurt_box_area_exited(area):
if area.is_in_group("CaptainHitBox"):
pass
func _on_animated_sprite_2d_animation_finished():
if crabSprite.animation == "CrabHurt":
if crabHealth <= 0:
current_state = STATE.ON_DEATH
else:
current_state = STATE.ON_FOLLOW
if crabSprite.animation == "CrabDeath":
queue_free()
func _on_animated_sprite_2d_animation_changed():
if crabSprite.animation == "CrabHurt" and crabSprite.flip_h == false:
global_position.x += 10
if crabSprite.animation == "CrabHurt" and crabSprite.flip_h == true:
global_position.x -= 10
if crabSprite.animation == "CrabDeath":
$CrabHurtBox/CrabHurtCollision.disabled = true```
I renewed the code a little bit, the video is old but nothing much has changed, only now if I hit from the right side "if crabSprite.animation == "CrabDeath":
$CrabHurtBox/CrabHurtCollision.disabled = true" this condition is realized, otherwise it is the same.
@fair sphinx My first suggestion is to disable sprite flipping logic and see what happens.
My second suggestion is to move the death logic out from your animation finished method to right under crabHealth -= 1
i'll try
if crabSprite.flip_h == true:
$CollisionShape2D.position.x = -1
$CrabDedectArea/CrabDedectCollision.position.x = 63
$CrabHurtBox/CrabHurtCollision.position.x = -1
elif crabSprite.flip_h == false:
$CollisionShape2D.position.x = 1
$CrabDedectArea/CrabDedectCollision.position.x = -63
$CrabHurtBox/CrabHurtCollision.position.x = 1
I deleted these two from the above line of code and it worked, but this time when Crab turns to the right side, the detect area collision stays on the left side $CrabDedectArea/CrabDedectCollision.position.x = -63 $CrabDedectArea/CrabDedectCollision.position.x = 63 i delete this
What about moving the death logic?
how can I do it
Move:
current_state = STATE.ON_DEATH```
to right after crabHealth -= 1
func _on_crab_hurt_box_area_entered(area):
if area.is_in_group("CaptainHitBox"):
current_state = STATE.ON_HURT
crabHealth -= 1
print(crabHealth)
if area.is_in_group("CaptainHitBox") and crabHealth <= 0:
current_state = STATE.ON_DEATH
func _on_crab_hurt_box_area_exited(area):
if area.is_in_group("CaptainHitBox"):
pass
func _on_animated_sprite_2d_animation_finished():
if crabSprite.animation == "CrabHurt":
current_state = STATE.ON_FOLLOW```like this?
If so, it worked, but this time the "current_state = ON.FOLLOW" happens before the hurt animation is completely finished
Yeah, don't worry about the animations for now. We're just trying to isolate the bug. So if that worked, than the bug is probably in your _on_animated_sprite_2d_animation_finished method. Try this:
func _on_animated_sprite_2d_animation_finished():
print(crabSprite.animation)
if crabSprite.animation == "CrabHurt":
if crabHealth <= 0:
current_state = STATE.ON_DEATH
else:
current_state = STATE.ON_FOLLOW
if crabSprite.animation == "CrabDeath":
queue_free()
My guess is that for whatever reason, crabSprite.animation is changing before this function is called.
Kill the crab from the left, and it should print "CrabHurt". Kill the crab from the right, and see if it says something different
right now, whether I kill the crab on the right or on the left, the death animation works fine.
also when I kill the crab it says crabdeath on the console but when I do damage it doesn't say crabhurt :/
Does it not say crabHurt when you hit it on either left or right? Or just right?
No matter where I hit it, it doesn't say crabhurt.
if crabSprite.animation == "CrabHurt" and crabSprite.flip_h == false:
global_position.x += 10
if crabSprite.animation == "CrabHurt" and crabSprite.flip_h == true:
global_position.x -= 10
i delete this
and did work
but this time when I hit the enemy, the enemy is not pushed back.
if current_state == STATE.ON_HURT and crabSprite.flip_h == true:
global_position.x -= 10
crabSprite.play("CrabHurt")
if current_state == STATE.ON_HURT and crabSprite.flip_h == false:
global_position.x += 5
crabSprite.play("CrabHurt")
just now I renewed this code in this way and I think it works fine
problem again. this time the hurt animation doesn't work when I damage from the right side :/
If I delete the two codes here, it works fine but there is no backlash "global_position.x += 5 and global_position.x -= 10" are the codes I deleted
extends CharacterBody2D
enum STATE {ON_IDLE,ON_FOLLOW,ON_ATTACK,ON_HURT,ON_DEATH}
var current_state = STATE.ON_IDLE
var crabGravity = 5000
var crabHealth = 3
@export var crabSpeed = 50
@onready var captainCharacter = $"../Captain"
@onready var crabSprite = $AnimatedSprite2D
func _ready():
current_state = STATE.ON_IDLE
func _physics_process(delta):
velocity.y += crabGravity * delta
if $CrabDedectArea/CrabDedectCollision.disabled == true and $CrabHurtBox/CrabHurtCollision.disabled == true:
current_state = STATE.ON_DEATH
if $CrabDedectArea/CrabDedectCollision.disabled == true:
current_state = STATE.ON_HURT
if velocity.x <= 0:
crabSprite.flip_h = false
elif velocity.x >= 0:
crabSprite.flip_h = true
else:
current_state = STATE.ON_IDLE
if crabSprite.flip_h == true:
$CollisionShape2D.position.x = -1
$CrabHurtBox/CrabHurtCollision.position.x = -1
$CrabDedectArea/CrabDedectCollision.position.x = 65
elif crabSprite.flip_h == false:
$CrabDedectArea/CrabDedectCollision.position.x = -65
$CollisionShape2D.position.x = 1
$CrabHurtBox/CrabHurtCollision.position.x = 1
```
if current_state == STATE.ON_IDLE:
crabSprite.play("CrabIdle")
velocity.x = 0
if current_state == STATE.ON_FOLLOW:
crabSprite.play("CrabRun")
var crabDir = global_position.direction_to(captainCharacter.global_position)
velocity = crabSpeed * crabDir
velocity.y += crabGravity * delta
move_and_slide()
if current_state == STATE.ON_ATTACK:
crabSprite.play("CrabAttack")
if current_state == STATE.ON_HURT and crabSprite.flip_h == true:
crabSprite.play("CrabHurt")
$CrabDedectArea/CrabDedectCollision.disabled = true
elif current_state == STATE.ON_HURT and crabSprite.flip_h == false:
crabSprite.play("CrabHurt")
$CrabDedectArea/CrabDedectCollision.disabled = true
if current_state == STATE.ON_DEATH:
crabSprite.play("CrabDeath")
velocity.x = 0```
func _on_crab_dedect_area_body_entered(body):
if body.is_in_group("Player"):
current_state = STATE.ON_FOLLOW
func _on_crab_dedect_area_body_exited(body):
if body.is_in_group("Player"):
current_state = STATE.ON_FOLLOW
func _on_crab_hurt_box_area_entered(area):
if area.is_in_group("CaptainHitBox"):
current_state = STATE.ON_HURT
crabHealth -= 1
print(crabHealth)
if area.is_in_group("CaptainHitBox") and crabHealth <= 0:
current_state = STATE.ON_DEATH
$CrabDedectArea/CrabDedectCollision.disabled = false
func _on_crab_hurt_box_area_exited(area):
if area.is_in_group("CaptainHitBox"):
pass
func _on_animated_sprite_2d_animation_finished():
print(crabSprite.animation)
if crabSprite.animation == "CrabHurt":
$CrabDedectArea/CrabDedectCollision.disabled = false
if crabHealth<= 0:
current_state = STATE.ON_DEATH
else:
$CrabDedectArea/CrabDedectCollision.disabled = false
current_state = STATE.ON_FOLLOW
if crabSprite.animation == "CrabDeath":
queue_free()
func _on_animated_sprite_2d_animation_changed():
if crabSprite.animation == "CrabHurt":
$CrabDedectArea/CrabDedectCollision.disabled = true
if crabSprite.animation == "CrabDeath":
$CrabHurtBox/CrabHurtCollision.disabled = true
$CrabDedectArea/CrabDedectCollision.disabled = true```
This is the final version of the code. now the hurt animation works successfully when I damage from the right or left, but when "crabHealt<= 0" the crabDeath animation does not work and the crabHurt animation gets stuck/loops
Unfortunately I won't be able to take a close look at this for a while. I do wonder if switching from an AnimatedSprite to AnimationPlayer would make a difference. I think that maybe by the time you receive the animation finished signal, crabSprite.animation is out of sync with what the called function is expecting. AnimationPlayer sends the name of animation as a parameter with the signal so you don't have to worry about sync issues. I could be completely wrong though.
I shouldn't use animatedsprite?
Maybe. I could be totally wrong on this.
If you want to send me your project file, I can try troubleshooting it when I have time. I'm not sure how much more help I can be over chat
How can I send the project file? (I'm new to this, I don't know most things)
Haha no worries. All you have to do is find the folder your project is saved in, right-click -> Send to -> Compressed (zipped). Then upload the zipped folder here or in a private message
should i upload all?