Demo: Combo attack, better particles and animation tweaks
This commit is contained in:
parent
597a795d6b
commit
f85555675b
File diff suppressed because it is too large
Load Diff
|
@ -9,8 +9,8 @@
|
||||||
var/speed/name = "speed"
|
var/speed/name = "speed"
|
||||||
var/speed/type = 3
|
var/speed/type = 3
|
||||||
var/speed/value = 400.0
|
var/speed/value = 400.0
|
||||||
var/speed/hint = 0
|
var/speed/hint = 1
|
||||||
var/speed/hint_string = ""
|
var/speed/hint_string = "10,1000,10"
|
||||||
|
|
||||||
[node name="AgentEnemy" instance=ExtResource("1_uffd7")]
|
[node name="AgentEnemy" instance=ExtResource("1_uffd7")]
|
||||||
script = ExtResource("2_w7f5y")
|
script = ExtResource("2_w7f5y")
|
||||||
|
|
|
@ -21,7 +21,8 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||||
func _init_state_machine() -> void:
|
func _init_state_machine() -> void:
|
||||||
hsm.add_transition(idle_state, move_state, idle_state.EVENT_FINISHED)
|
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(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.add_transition(attack_state, move_state, attack_state.EVENT_FINISHED)
|
||||||
hsm.initialize(self)
|
hsm.initialize(self)
|
||||||
hsm.set_active(true)
|
hsm.set_active(true)
|
||||||
|
|
|
@ -24,4 +24,4 @@ animation = &"walk"
|
||||||
[node name="AttackState" type="LimboState" parent="LimboHSM" index="2" node_paths=PackedStringArray("animation_player")]
|
[node name="AttackState" type="LimboState" parent="LimboHSM" index="2" node_paths=PackedStringArray("animation_player")]
|
||||||
script = ExtResource("5_mpgu6")
|
script = ExtResource("5_mpgu6")
|
||||||
animation_player = NodePath("../../AnimationPlayer")
|
animation_player = NodePath("../../AnimationPlayer")
|
||||||
animation = &"attack"
|
animations = Array[StringName]([&"attack_1", &"attack_2", &"attack_3"])
|
||||||
|
|
|
@ -1,13 +1,29 @@
|
||||||
extends LimboState
|
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_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:
|
func _enter() -> void:
|
||||||
animation_player.play(animation)
|
attack_pressed = 0
|
||||||
await animation_player.animation_finished
|
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():
|
if is_active():
|
||||||
get_root().dispatch(EVENT_FINISHED)
|
get_root().dispatch(EVENT_FINISHED)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
extends LimboState
|
extends LimboState
|
||||||
|
|
||||||
## Idle state.
|
## Idle state.
|
||||||
|
|
||||||
|
|
||||||
@export var animation_player: AnimationPlayer
|
@export var animation_player: AnimationPlayer
|
||||||
@export var animation: StringName
|
@export var animation: StringName
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
extends LimboState
|
extends LimboState
|
||||||
|
## Move state.
|
||||||
|
|
||||||
|
|
||||||
const VERTICAL_FACTOR := 0.8
|
const VERTICAL_FACTOR := 0.8
|
||||||
|
|
||||||
## Move state.
|
|
||||||
|
|
||||||
@export var animation_player: AnimationPlayer
|
@export var animation_player: AnimationPlayer
|
||||||
@export var animation: StringName
|
@export var animation: StringName
|
||||||
@export var speed: float = 500.0
|
@export var speed: float = 500.0
|
||||||
|
|
||||||
|
|
||||||
func _enter() -> void:
|
func _enter() -> void:
|
||||||
animation_player.play(animation, 0.1)
|
animation_player.play(animation, 0.1)
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ func _damaged(_amount: float) -> void:
|
||||||
hsm.set_active(true)
|
hsm.set_active(true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _die() -> void:
|
func _die() -> void:
|
||||||
animation_player.play(&"death")
|
animation_player.play(&"death")
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
class_name Health
|
class_name Health
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
## Tracks health and emits signal when damaged or dead.
|
## Tracks health and emits signal when damaged or dead.
|
||||||
|
|
||||||
|
|
||||||
signal death
|
signal death
|
||||||
signal damaged(amount: float)
|
signal damaged(amount: float)
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ func _ready() -> void:
|
||||||
|
|
||||||
|
|
||||||
func take_damage(amount: float) -> void:
|
func take_damage(amount: float) -> void:
|
||||||
|
if _current <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
_current -= amount
|
_current -= amount
|
||||||
_current = max(_current, 0.0)
|
_current = max(_current, 0.0)
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
class_name Hitbox
|
class_name Hitbox
|
||||||
extends Area2D
|
extends Area2D
|
||||||
|
|
||||||
## Area that deals damage.
|
## Area that deals damage.
|
||||||
|
|
||||||
|
|
||||||
@export var damage: float = 1.0
|
@export var damage: float = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
collision_layer = 0
|
||||||
|
collision_mask = 4
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
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
|
var hurtbox := area as Hurtbox
|
||||||
hurtbox.take_damage(damage, self)
|
hurtbox.take_damage(damage, self)
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
class_name Hurtbox
|
class_name Hurtbox
|
||||||
extends Area2D
|
extends Area2D
|
||||||
|
|
||||||
## Area that registers damage.
|
## Area that registers damage.
|
||||||
|
|
||||||
|
|
||||||
@export var health: Health
|
@export var health: Health
|
||||||
|
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
collision_layer = 4
|
||||||
|
collision_mask = 0
|
||||||
|
|
||||||
|
|
||||||
func take_damage(amount: float, source: Area2D) -> void:
|
func take_damage(amount: float, source: Area2D) -> void:
|
||||||
if source.owner == owner:
|
if source.owner == owner:
|
||||||
# Don't damage yourself.
|
# Don't damage yourself.
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
@tool
|
@tool
|
||||||
extends BTAction
|
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
|
const TOLERANCE := 30.0
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ var/speed/hint = 1
|
||||||
var/speed/hint_string = "10,1000,10"
|
var/speed/hint_string = "10,1000,10"
|
||||||
|
|
||||||
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
[sub_resource type="BBNode" id="BBNode_nrd4b"]
|
||||||
resource_name = "AnimationPlayer"
|
|
||||||
saved_value = NodePath("AnimationPlayer")
|
saved_value = NodePath("AnimationPlayer")
|
||||||
|
resource_name = "AnimationPlayer"
|
||||||
|
|
||||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_qiw21"]
|
||||||
animation_player = SubResource("BBNode_nrd4b")
|
animation_player = SubResource("BBNode_nrd4b")
|
||||||
|
@ -29,8 +29,8 @@ custom_name = "Pause before action"
|
||||||
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
|
children = [SubResource("BTPlayAnimation_qiw21"), SubResource("BTRandomWait_xlud8")]
|
||||||
|
|
||||||
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
[sub_resource type="BBNode" id="BBNode_wpj6d"]
|
||||||
resource_name = "AnimationPlayer"
|
|
||||||
saved_value = NodePath("AnimationPlayer")
|
saved_value = NodePath("AnimationPlayer")
|
||||||
|
resource_name = "AnimationPlayer"
|
||||||
|
|
||||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_olf37"]
|
||||||
animation_player = SubResource("BBNode_wpj6d")
|
animation_player = SubResource("BBNode_wpj6d")
|
||||||
|
@ -46,11 +46,11 @@ output_var = "_target"
|
||||||
script = ExtResource("2_h5db5")
|
script = ExtResource("2_h5db5")
|
||||||
target_var = "_target"
|
target_var = "_target"
|
||||||
speed_var = "speed"
|
speed_var = "speed"
|
||||||
approach_distance = null
|
approach_distance = 100.0
|
||||||
|
|
||||||
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
[sub_resource type="BTTimeLimit" id="BTTimeLimit_xek5v"]
|
||||||
children = [SubResource("BTAction_a4jqi")]
|
|
||||||
time_limit = 2.0
|
time_limit = 2.0
|
||||||
|
children = [SubResource("BTAction_a4jqi")]
|
||||||
|
|
||||||
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
[sub_resource type="BTSequence" id="BTSequence_1xfnq"]
|
||||||
custom_name = "Pursue player"
|
custom_name = "Pursue player"
|
||||||
|
@ -64,13 +64,13 @@ target_var = "_target"
|
||||||
duration = 0.1
|
duration = 0.1
|
||||||
|
|
||||||
[sub_resource type="BBNode" id="BBNode_s8evu"]
|
[sub_resource type="BBNode" id="BBNode_s8evu"]
|
||||||
resource_name = "AnimationPlayer"
|
|
||||||
saved_value = NodePath("AnimationPlayer")
|
saved_value = NodePath("AnimationPlayer")
|
||||||
|
resource_name = "AnimationPlayer"
|
||||||
|
|
||||||
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
|
[sub_resource type="BTPlayAnimation" id="BTPlayAnimation_ppmxd"]
|
||||||
await_completion = 2.0
|
await_completion = 2.0
|
||||||
animation_player = SubResource("BBNode_s8evu")
|
animation_player = SubResource("BBNode_s8evu")
|
||||||
animation_name = &"attack"
|
animation_name = &"attack_3"
|
||||||
|
|
||||||
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
[sub_resource type="BTSequence" id="BTSequence_ww5v2"]
|
||||||
custom_name = "Melee attack"
|
custom_name = "Melee attack"
|
||||||
|
|
|
@ -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="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"]
|
[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://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://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://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"]
|
[sub_resource type="Animation" id="Animation_gwtgs"]
|
||||||
length = 0.001
|
length = 0.001
|
||||||
|
@ -2873,9 +2872,6 @@ metadata/_edit_lock_ = true
|
||||||
y_sort_enabled = true
|
y_sort_enabled = true
|
||||||
metadata/_edit_lock_ = 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")]
|
[node name="AgentEnemy" parent="YSort/Agents" instance=ExtResource("5_knyss")]
|
||||||
position = Vector2(1527.4, 690.665)
|
position = Vector2(1527.4, 690.665)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -19,6 +19,9 @@ config/icon="res://demo/icon.svg"
|
||||||
|
|
||||||
window/size/viewport_width=1920
|
window/size/viewport_width=1920
|
||||||
window/size/viewport_height=1080
|
window/size/viewport_height=1080
|
||||||
|
window/size/window_width_override=1280
|
||||||
|
window/size/window_height_override=720
|
||||||
|
window/stretch/mode="canvas_items"
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue