Demo: Combo attack, better particles and animation tweaks

This commit is contained in:
Serhii Snitsaruk 2024-01-31 17:27:35 +01:00
parent 597a795d6b
commit f85555675b
16 changed files with 907 additions and 817 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,8 +9,8 @@
var/speed/name = "speed"
var/speed/type = 3
var/speed/value = 400.0
var/speed/hint = 0
var/speed/hint_string = ""
var/speed/hint = 1
var/speed/hint_string = "10,1000,10"
[node name="AgentEnemy" instance=ExtResource("1_uffd7")]
script = ExtResource("2_w7f5y")

View File

@ -21,7 +21,8 @@ func _unhandled_input(event: InputEvent) -> void:
func _init_state_machine() -> void:
hsm.add_transition(idle_state, move_state, idle_state.EVENT_FINISHED)
hsm.add_transition(move_state, idle_state, move_state.EVENT_FINISHED)
hsm.add_transition(hsm.ANYSTATE, attack_state, "attack!")
hsm.add_transition(idle_state, attack_state, "attack!")
hsm.add_transition(move_state, attack_state, "attack!")
hsm.add_transition(attack_state, move_state, attack_state.EVENT_FINISHED)
hsm.initialize(self)
hsm.set_active(true)

View File

@ -24,4 +24,4 @@ animation = &"walk"
[node name="AttackState" type="LimboState" parent="LimboHSM" index="2" node_paths=PackedStringArray("animation_player")]
script = ExtResource("5_mpgu6")
animation_player = NodePath("../../AnimationPlayer")
animation = &"attack"
animations = Array[StringName]([&"attack_1", &"attack_2", &"attack_3"])

View File

@ -1,13 +1,29 @@
extends LimboState
## Idle state.
## Attack state: Perform 3-part combo attack for as long as player hits attack button.
@export var animation_player: AnimationPlayer
@export var animation: StringName
@export var animations: Array[StringName]
var attack_pressed: int
func _unhandled_input(event: InputEvent) -> void:
if event.is_echo():
return
if event.is_action_pressed("attack"):
attack_pressed += 1
func _enter() -> void:
animation_player.play(animation)
await animation_player.animation_finished
attack_pressed = 0
for idx in animations.size():
animation_player.play(animations[idx])
await animation_player.animation_finished
if attack_pressed <= 0 or not is_active():
# Interrupt combo if player didn't press attack button again,
# or state is no longer active.
break
attack_pressed -= 1
if is_active():
get_root().dispatch(EVENT_FINISHED)

View File

@ -1,7 +1,7 @@
extends LimboState
## Idle state.
@export var animation_player: AnimationPlayer
@export var animation: StringName

View File

@ -1,13 +1,14 @@
extends LimboState
## Move state.
const VERTICAL_FACTOR := 0.8
## Move state.
@export var animation_player: AnimationPlayer
@export var animation: StringName
@export var speed: float = 500.0
func _enter() -> void:
animation_player.play(animation, 0.1)

View File

@ -47,7 +47,6 @@ func _damaged(_amount: float) -> void:
hsm.set_active(true)
func _die() -> void:
animation_player.play(&"death")

View File

@ -1,8 +1,8 @@
class_name Health
extends Node
## Tracks health and emits signal when damaged or dead.
signal death
signal damaged(amount: float)
@ -16,6 +16,9 @@ func _ready() -> void:
func take_damage(amount: float) -> void:
if _current <= 0:
return
_current -= amount
_current = max(_current, 0.0)

View File

@ -1,14 +1,20 @@
class_name Hitbox
extends Area2D
## Area that deals damage.
@export var damage: float = 1.0
func _init() -> void:
collision_layer = 0
collision_mask = 4
func _ready() -> void:
area_entered.connect(_on_area_entered)
area_entered.connect(_area_entered)
func _on_area_entered(area: Area2D) -> void:
func _area_entered(area: Area2D) -> void:
var hurtbox := area as Hurtbox
hurtbox.take_damage(damage, self)

View File

@ -1,11 +1,16 @@
class_name Hurtbox
extends Area2D
## Area that registers damage.
@export var health: Health
func _init() -> void:
collision_layer = 4
collision_mask = 0
func take_damage(amount: float, source: Area2D) -> void:
if source.owner == owner:
# Don't damage yourself.

View File

@ -1,5 +1,11 @@
@tool
extends BTAction
## Pursue target.
##
## Returns RUNNING, while moving towards target but not yet at the desired distance.
## Returns SUCCESS, when at the desired distance from target.
## Returns FAILURE, if target is not a valid instance.
const TOLERANCE := 30.0

View File

@ -12,8 +12,8 @@ var/speed/hint = 1
var/speed/hint_string = "10,1000,10"
[sub_resource type="BBNode" id="BBNode_nrd4b"]
resource_name = "AnimationPlayer"
saved_value = NodePath("AnimationPlayer")
resource_name = "AnimationPlayer"
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
animation_player = SubResource("BBNode_nrd4b")
@ -29,8 +29,8 @@ custom_name = "Pause before action"
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
[sub_resource type="BBNode" id="BBNode_wpj6d"]
resource_name = "AnimationPlayer"
saved_value = NodePath("AnimationPlayer")
resource_name = "AnimationPlayer"
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
animation_player = SubResource("BBNode_wpj6d")
@ -46,11 +46,11 @@ output_var = "_target"
script = ExtResource("2_h5db5")
target_var = "_target"
speed_var = "speed"
approach_distance = null
approach_distance = 100.0
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
children = [SubResource("BTAction_a4jqi")]
time_limit = 2.0
children = [SubResource("BTAction_a4jqi")]
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
custom_name = "Pursue player"
@ -64,13 +64,13 @@ target_var = "_target"
duration = 0.1
[sub_resource type="BBNode" id="BBNode_s8evu"]
resource_name = "AnimationPlayer"
saved_value = NodePath("AnimationPlayer")
resource_name = "AnimationPlayer"
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
await_completion = 2.0
animation_player = SubResource("BBNode_s8evu")
animation_name = &"attack"
animation_name = &"attack_3"
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
custom_name = "Melee attack"

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=3 uid="uid://bsig1usigbbuy"]
[gd_scene load_steps=11 format=3 uid="uid://bsig1usigbbuy"]
[ext_resource type="Texture2D" uid="uid://b3g14elmg0m36" path="res://demo/assets/env_rocks.png" id="1_145kx"]
[ext_resource type="PackedScene" uid="uid://dt2jlrqffpyw" path="res://demo/scenes/clouds.tscn" id="1_gsxmp"]
@ -7,7 +7,6 @@
[ext_resource type="PackedScene" uid="uid://bpd1wmw2f7bvg" path="res://demo/props/gong.tscn" id="3_nbto3"]
[ext_resource type="PackedScene" uid="uid://d07ag5dcje13i" path="res://demo/agents/player/player.tscn" id="5_cmgoj"]
[ext_resource type="PackedScene" uid="uid://sjans5psq6pg" path="res://demo/agents/agent_base_enemy.tscn" id="5_knyss"]
[ext_resource type="PackedScene" uid="uid://comfxjrcylgb" path="res://demo/agents/agent_melee_simple.tscn" id="7_ruy6b"]
[sub_resource type="Animation" id="Animation_gwtgs"]
length = 0.001
@ -2873,9 +2872,6 @@ metadata/_edit_lock_ = true
y_sort_enabled = true
metadata/_edit_lock_ = true
[node name="AgentMeleeSimple" parent="YSort/Agents" instance=ExtResource("7_ruy6b")]
position = Vector2(1212, 333)
[node name="AgentEnemy" parent="YSort/Agents" instance=ExtResource("5_knyss")]
position = Vector2(1527.4, 690.665)

37
demo/export_presets.cfg Normal file
View File

@ -0,0 +1,37 @@
[preset.0]
name="Web"
platform="Web"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path=""
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.0.options]
custom_template/debug=""
custom_template/release=""
variant/extensions_support=false
vram_texture_compression/for_desktop=true
vram_texture_compression/for_mobile=false
html/export_icon=true
html/custom_html_shell=""
html/head_include=""
html/canvas_resize_policy=2
html/focus_canvas_on_start=true
html/experimental_virtual_keyboard=false
progressive_web_app/enabled=false
progressive_web_app/offline_page=""
progressive_web_app/display=1
progressive_web_app/orientation=0
progressive_web_app/icon_144x144=""
progressive_web_app/icon_180x180=""
progressive_web_app/icon_512x512=""
progressive_web_app/background_color=Color(0, 0, 0, 1)

View File

@ -19,6 +19,9 @@ config/icon="res://demo/icon.svg"
window/size/viewport_width=1920
window/size/viewport_height=1080
window/size/window_width_override=1280
window/size/window_height_override=720
window/stretch/mode="canvas_items"
[input]