Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | amaou310 |
Hello Godot community. I am making 2D platformer.
I have made an enemy which has four different states (Idle, Chase, Attack, Death)
Enemy has PlayerDetector Area2D and Hitbox Area2D. Once Player entered PlayerDetector Area2D, Enemy will be in Chase State. As soon as Player exited PlayerDetector Area2D, Enemy will return to Idle State. If player entered Hitbox Area2D, Enemy will be in Attack State. What I would like to do is, when one enemy is in Attack State, change all other duplicated enemies to Idle State. How could I achieve this? I would appreciate if you could kindly teach me.
What I have tried so far:
① Disable Player’s PlayerDetector Area2D, so enemy will no longer be in Chase State.
But this caused a problem that all of the enemies will be in Idle State, as soon as Player’s playerDetector Area2D is disabled, since it will trigger Enemy’s PlayerDetector Area2D exited function.
② send a signal has_player == true
and enable enemy’s Chase State only if has_player == false
. This funnily worked only if duplicated enemies are in Idle State. If enemies are already in Chase State, they would not return to Idle State.
Enemy Script:
extends KinematicBody2D
var max_hp = 100
var current_hp= max_hp
var defense = 0
var speed = 100
var chase_speed = 170
var gravity = 800
var direction = 1
var velocity = Vector2.ZERO
var has_player = false
var has_trigger = false
onready var _animation_player: AnimationPlayer = $Position2D/CatSkin/AnimationPlayer
onready var sprite = get_node("Position2D/CatSkin")
onready var flashTimer = $flashTimer
onready var player = get_node("../Player")
onready var EnemyCollision = $EnemyCollision
onready var label = $Label
onready var bullet = get_node("../Bullet02")
signal button_mashing_start()
enum state {IDLE, CHASE, GRAB, FINISH, DEATH}
var enemy_state = state.IDLE
func _ready():
enemy_state = state.IDLE
$Position2D/CatSkin/AnimationPlayer.connect("animation_finisehd", self, "on_animation_finished")
Autoload.connect("button_mashing_cleared", self, "button_mashing_cleared_signal_recieved")
Autoload.connect("button_mashing_failed", self, "button_mashing_failed_signal_recieved")
Autoload.connect("has_triggered", self, "has_triggered_signal_recieved")
current_hp = max_hp
pass
func _physics_process(delta):
match enemy_state:
state.IDLE:
label.text="IDLE"
_animation_player.play("Cat Idle")
if velocity.x>0:
$Position2D.scale.x=1
elif velocity.x<0:
$Position2D.scale.x=-1
velocity.y += gravity * delta
velocity.x = speed * direction
if EnemyCollision.is_colliding():
velocity += EnemyCollision.get_push_vector() * delta * 100
velocity = move_and_slide(velocity, Vector2.UP)
if is_on_wall() or not $Position2D/FloorRay.is_colliding() and is_on_floor():
direction = direction * -1
flip()
velocity.y += gravity * delta
velocity.x = speed * direction
state.CHASE:
label.text="CHASE"
_animation_player.play("Cat Chase")
if velocity.x>0:
$Position2D.scale.x=1
elif velocity.x<0:
$Position2D.scale.x=-1
velocity = Vector2(sign(player.global_position.x - global_position.x), 0).normalized()
if not is_on_floor():
velocity.y += gravity * delta
if EnemyCollision.is_colliding():
velocity += EnemyCollision.get_push_vector() * delta * 100
velocity = move_and_slide(velocity * chase_speed)
state.GRAB:
label.text="GRAB01"
_animation_player.play("Cat Grab Attack")
velocity.y = 0
velocity.x = 0 * direction
velocity = move_and_slide(velocity, Vector2.UP)
emit_signal("button_mashing_start")
state.FINISH:
label.text="GRAB02"
_animation_player.play("Cat Grab Attack 02")
velocity.y = 0
velocity.x = 0 * direction
velocity = move_and_slide(velocity, Vector2.UP)
state.DEATH:
label.text="DEATH"
_animation_player.play("Cat Death")
has_player = true
velocity.x = 0 * direction
velocity = move_and_slide(velocity, Vector2.UP)
Autoload.emit_signal("screen_shake")
$HitboxCat/CollisionShape2D.set_deferred("disabled", true)
$HitboxCat/CollisionShape2D2.set_deferred("disabled", true)
$HurtboxCat/CollisionShape2D.set_deferred("disabled", true)
$HurtboxCat/CollisionShape2D2.set_deferred("disabled", true)
func _on_DeathSound_finished():
queue_free()
func _on_AnimationPlayer_animation_finished(anim_name):
print("Grab02 End!")
Autoload.emit_signal("grab_finished", self)
enemy_state = state.CHASE
has_player = false
func flip(): #Flip Sprite
if direction>0:
$Position2D.scale.x=1
elif direction<0:
$Position2D.scale.x=-1
func _on_HurtboxCat_area_entered(area):
if area.name == "Bullet02":
print("I got hit!")
$HitSound.play()
var base_damage = area.damage
self.current_hp -= base_damage
if self.current_hp <= 0:
print("IM DEAD!")
enemy_state = state.DEATH
$DeathSound.play()
func _on_HitboxCat_area_entered(area):
if area.name == "HurtboxPlayer":
enemy_state = state.GRAB
print("Grab01!")
pass
func _on_PlayerDetector_area_entered(area: Area2D): #Player Search Area. Chase when Player entered
if area.name == "PlayerDetector":
if has_player == false:
print("found you !")
enemy_state = state.CHASE
else:
enemy_state = state.IDLE
func _on_PlayerDetector_area_exited(area: Area2D): #Player Search Area. Stop Chase when Player exited
if area.name == "PlayerDetector":
if has_player == false:
print("lost you !")
enemy_state = state.IDLE
func has_triggered_signal_recieved():
has_player = true
print("has_player=false")