Implement Hiro player hurt and defeat, make Hiro player and AI share animation data

This commit is contained in:
Mario Martínez 2024-09-12 00:32:51 +02:00
parent b909cbd9d7
commit 2f2ebd5426
6 changed files with 1903 additions and 3425 deletions

File diff suppressed because it is too large Load diff

1825
Hiro/hiro_animation.tres Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,8 @@ extends CharacterBody2D
@export var player_character: PlayableCharacter
@export var health = 100
@export var KNOCKBACK_POWER = 50
@export var attack_power = 30
@export var KNOCKBACK_POWER = 40
@export var KNOCKBACK_REPOSITION_POWER = 75
@export var KNOCKBACK_RANDOMNESS = 50
@export var MELEE_RADIUS = 75
@ -17,10 +18,13 @@ var timer = 0
var attacked_from = Vector2.ZERO
var received_damage = 0
var hit_counter = 0
var attack_counter = 0
var attack_counter_limit = 0
var wants_to_melee = false
signal _got_hurt(damage: int, attack_direction: Vector2)
signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
#signal defeated
func _ready():
@ -50,6 +54,7 @@ func _on_player_attack_did_hit(other, attack_power: int, attack_direction: Vecto
func _on_ai_got_hurt(attack_power: int, attack_direction: Vector2):
attacked_from = attack_direction
received_damage = attack_power
$Attackbox/Collider.set_deferred("disabled", true)
state_machine.send_event("been_hurt")
## Thinking state
@ -69,7 +74,7 @@ func do_thinking():
var distance = position.distance_to(player_character.position)
if distance > MELEE_RADIUS:
state_machine.set_expression_property("melee_stage", 0)
# melee attacks here
# range attacks here
else:
state_machine.send_event("wants_tomelee")
@ -131,6 +136,8 @@ func _on_animation_tree_animation_finished(anim_name):
if anim_name.contains("hurt"):
state_machine.send_event("hurt_complete")
elif (anim_name.contains("kick") or anim_name.contains("punch")):
attack_counter = attack_counter + 1
wants_to_melee = wants_to_melee and attack_counter < attack_counter_limit
if wants_to_melee:
var animation_rng = randf_range(0, 1)
anim_tree.set("parameters/melee/blend_position", animation_rng)
@ -185,6 +192,8 @@ func _on_meleebox_body_entered(body):
state_machine.send_event("will_melee")
func _on_melee_state_entered():
attack_counter = 0
attack_counter_limit = randi_range(3, 5)
anim_tree.set("parameters/conditions/melee", true)
state_machine.set_expression_property("melee_stage", 0)
@ -197,3 +206,7 @@ func _on_melee_state_processing(_delta):
func _on_melee_state_exited():
anim_tree.set("parameters/conditions/melee", false)
func _on_attackbox_area_entered(area):
attack_did_hit.emit(area, attack_power, anim_tree.get("parameters/melee/0/blend_position"))

View file

@ -1,23 +1,38 @@
class_name PlayableCharacter
extends CharacterBody2D
@export var health = 100
@export var speed = 100
@export var KNOCKBACK_POWER = 40
@export var KNOCKBACK_RANDOMNESS = 50
var last_dpad: Array[Vector2] = [Vector2.ZERO,Vector2.ZERO]
const FACING_ANGLE_EPSILON = 15
var can_move = true
signal attack_did_hit(other: Area2D, power: int, attack_direction: Vector2)
signal defeated
func _unhandled_input(event):
if event.is_action_pressed("melee") and $AnimationTree.get("parameters/conditions/melee") == false:
if event.is_action_pressed("melee") and can_move:
var animation_rng = randf_range(0, 1)
$AnimationTree.set("parameters/melee/blend_position", animation_rng)
$AnimationTree.set("parameters/conditions/melee", true)
can_move = false
velocity = Vector2.ZERO
func _physics_process(_delta):
get_input()
move_and_slide()
func set_animation_direction(direction: Vector2):
$AnimationTree.set("parameters/idle/blend_position", direction)
$AnimationTree.set("parameters/walk/blend_position", direction)
$AnimationTree.set("parameters/melee/0/blend_position", direction)
$AnimationTree.set("parameters/melee/1/blend_position", direction)
$AnimationTree.set("parameters/melee/2/blend_position", direction)
$AnimationTree.set("parameters/hurt/blend_position", direction)
func xor(a:bool, b:bool):
return a != b
@ -38,23 +53,18 @@ func get_input():
if last_dpad[0] == Vector2.ZERO and input_direction != Vector2.ZERO:
last_dpad[0] = input_direction
if $AnimationTree.get("parameters/conditions/melee") ==true:
if not can_move:
input_direction = Vector2.ZERO
last_dpad[0] = Vector2.ZERO
last_dpad[1] = Vector2.ZERO
velocity = input_direction * speed
last_dpad[1] = Vector2.ZERO
else:
velocity = input_direction * speed
if input_direction == Vector2.ZERO:
$AnimationTree.set("parameters/conditions/is_moving", false)
else:
$AnimationTree.set("parameters/conditions/is_moving", true)
$AnimationTree.set("parameters/idle/blend_position", last_dpad[0])
$AnimationTree.set("parameters/walk/blend_position", last_dpad[0])
$AnimationTree.set("parameters/melee/0/blend_position", last_dpad[0])
$AnimationTree.set("parameters/melee/1/blend_position", last_dpad[0])
$AnimationTree.set("parameters/melee/2/blend_position", last_dpad[0])
set_animation_direction(last_dpad[0])
func _on_attackbox_area_entered(area: Area2D):
@ -64,3 +74,33 @@ func _on_attackbox_area_entered(area: Area2D):
func _on_hiro_dummy_defeated():
print("Yaaaaay!!")
func _on_enemy_attack_did_hit(other, power, attack_direction):
if other.get_parent().get_instance_id() == get_instance_id() :
$Attackbox/Collider.set_deferred("disabled", true)
health = health - power
can_move = false
if health <= 0:
print("Nooooooooooooo!!")
defeated.emit()
velocity = Vector2.ZERO
else:
var facing_direction = attack_direction * -1.0
set_animation_direction(facing_direction)
var knockback_variance = Vector2.ZERO
if attack_direction.x != 0:
knockback_variance.y = randf_range(-1, 1) * KNOCKBACK_RANDOMNESS
elif attack_direction.y != 0:
knockback_variance.x = randf_range(-1, 1) * KNOCKBACK_RANDOMNESS
velocity = KNOCKBACK_POWER * attack_direction + knockback_variance
var playback: AnimationNodeStateMachinePlayback = $AnimationTree.get("parameters/playback")
playback.travel("hurt")
$AnimationTree.set("parameters/conditions/melee", false)
func _on_animation_tree_animation_finished(anim_name):
if anim_name.contains("hurt") or anim_name.contains("kick") or anim_name.contains("punch"):
can_move = true
if anim_name.contains("kick") or anim_name.contains("punch"):
$Attackbox/Collider.set_deferred("disabled", true)

View file

@ -44,5 +44,7 @@ initial_node_to_watch = NodePath("../HiroAI")
[node name="HiroAI" parent="." node_paths=PackedStringArray("player_character") instance=ExtResource("5_r7nw4")]
position = Vector2(135, 215)
player_character = NodePath("../HiroPlayer")
attack_power = 5
[connection signal="attack_did_hit" from="HiroPlayer" to="HiroAI" method="_on_player_attack_did_hit"]
[connection signal="attack_did_hit" from="HiroAI" to="HiroPlayer" method="_on_enemy_attack_did_hit"]