#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)

fair sphinx
#
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```
#
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.

wide dew
#

@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

fair sphinx
# wide dew <@1055189968374468739> My first suggestion is to disable sprite flipping logic a...

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

wide dew
fair sphinx
wide dew
#

Move:

            current_state = STATE.ON_DEATH```
to right after crabHealth -= 1
fair sphinx
# wide dew Move: ```if crabHealth <= 0: current_state = STATE.ON_DEATH``` to ri...
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

wide dew
#

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

fair sphinx
#

also when I kill the crab it says crabdeath on the console but when I do damage it doesn't say crabhurt :/

wide dew
fair sphinx
fair sphinx
#

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 :/

fair sphinx
fair sphinx
#
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

wide dew
# fair sphinx This is the final version of the code. now the hurt animation works successfully...

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.

fair sphinx
wide dew
#

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

fair sphinx
#

How can I send the project file? (I'm new to this, I don't know most things)

wide dew