mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-04 06:09:46 +03:00
114 lines
2.4 KiB
GDScript
114 lines
2.4 KiB
GDScript
extends Area2D
|
|
|
|
signal attack_finished
|
|
|
|
enum States { IDLE, ATTACK }
|
|
var state = null
|
|
|
|
enum AttackInputStates { IDLE, LISTENING, REGISTERED }
|
|
var attack_input_state = AttackInputStates.IDLE
|
|
var ready_for_next_attack = false
|
|
const MAX_COMBO_COUNT = 3
|
|
var combo_count = 0
|
|
|
|
var attack_current = {}
|
|
var combo = [{
|
|
"damage": 1,
|
|
"animation": "attack_fast",
|
|
"effect": null
|
|
},
|
|
{
|
|
"damage": 1,
|
|
"animation": "attack_fast",
|
|
"effect": null
|
|
},
|
|
{
|
|
"damage": 3,
|
|
"animation": "attack_medium",
|
|
"effect": null
|
|
}]
|
|
|
|
var hit_objects = []
|
|
|
|
func _ready():
|
|
# warning-ignore:return_value_discarded
|
|
$AnimationPlayer.connect("animation_finished", self, "_on_animation_finished")
|
|
# warning-ignore:return_value_discarded
|
|
self.connect("body_entered", self, "_on_body_entered")
|
|
_change_state(States.IDLE)
|
|
|
|
|
|
func _change_state(new_state):
|
|
match state:
|
|
States.ATTACK:
|
|
hit_objects = []
|
|
attack_input_state = AttackInputStates.LISTENING
|
|
ready_for_next_attack = false
|
|
|
|
match new_state:
|
|
States.IDLE:
|
|
combo_count = 0
|
|
$AnimationPlayer.stop()
|
|
visible = false
|
|
monitoring = false
|
|
States.ATTACK:
|
|
attack_current = combo[combo_count -1]
|
|
$AnimationPlayer.play(attack_current["animation"])
|
|
visible = true
|
|
monitoring = true
|
|
state = new_state
|
|
|
|
|
|
func _unhandled_input(event):
|
|
if not state == States.ATTACK:
|
|
return
|
|
if attack_input_state != AttackInputStates.LISTENING:
|
|
return
|
|
if event.is_action_pressed("attack"):
|
|
attack_input_state = AttackInputStates.REGISTERED
|
|
|
|
|
|
func _physics_process(_delta):
|
|
if attack_input_state == AttackInputStates.REGISTERED and ready_for_next_attack:
|
|
attack()
|
|
|
|
|
|
func attack():
|
|
combo_count += 1
|
|
_change_state(States.ATTACK)
|
|
|
|
|
|
# Use with AnimationPlayer func track.
|
|
func set_attack_input_listening():
|
|
attack_input_state = AttackInputStates.LISTENING
|
|
|
|
|
|
# Use with AnimationPlayer func track.
|
|
func set_ready_for_next_attack():
|
|
ready_for_next_attack = true
|
|
|
|
|
|
func _on_body_entered(body):
|
|
if not body.has_node("Health"):
|
|
return
|
|
if body.get_rid().get_id() in hit_objects:
|
|
return
|
|
hit_objects.append(body.get_rid().get_id())
|
|
body.take_damage(self, attack_current["damage"], attack_current["effect"])
|
|
|
|
|
|
func _on_animation_finished(_name):
|
|
if not attack_current:
|
|
return
|
|
|
|
if attack_input_state == AttackInputStates.REGISTERED and combo_count < MAX_COMBO_COUNT:
|
|
attack()
|
|
else:
|
|
_change_state(States.IDLE)
|
|
emit_signal("attack_finished")
|
|
|
|
|
|
func _on_StateMachine_state_changed(current_state):
|
|
if current_state.name == "Attack":
|
|
attack()
|