123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- 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():
- $AnimationPlayer.animation_finished.connect(self._on_animation_finished)
- body_entered.connect(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 attack_current.is_empty():
- 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()
|