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/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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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)
|
||||
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)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
extends LimboState
|
||||
|
||||
## Idle state.
|
||||
|
||||
|
||||
@export var animation_player: AnimationPlayer
|
||||
@export var animation: StringName
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ func _damaged(_amount: float) -> void:
|
|||
hsm.set_active(true)
|
||||
|
||||
|
||||
|
||||
func _die() -> void:
|
||||
animation_player.play(&"death")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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_height=1080
|
||||
window/size/window_width_override=1280
|
||||
window/size/window_height_override=720
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
[input]
|
||||
|
||||
|
|
Loading…
Reference in New Issue