From 438edc8e70d0b0937b8bdbb0c61a6e8935c40a07 Mon Sep 17 00:00:00 2001 From: Nitsud Yarg Date: Sun, 16 Jun 2024 08:43:50 -0700 Subject: [PATCH] Trying to add more logic to state machine. --- src/playerD/Player.tscn | 20 ++++++------- src/state_animated_actor.gd | 44 ++++++++++++++++++++++++++--- src/state_machine_animated_actor.gd | 7 +++++ src/state_modifier.gd | 12 ++++++++ 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/src/playerD/Player.tscn b/src/playerD/Player.tscn index 1ba7c31..f6f40b3 100644 --- a/src/playerD/Player.tscn +++ b/src/playerD/Player.tscn @@ -473,7 +473,7 @@ animations = [ { "speed": 10.0 }, { "frames": [ SubResource( 189 ) ], -"loop": true, +"loop": false, "name": "step_shoot", "speed": 10.0 } ] @@ -490,7 +490,7 @@ player_number = 1 position = Vector2( -1, -51 ) frames = SubResource( 190 ) animation = "idle" -frame = 32 +frame = 11 flip_h = false __meta__ = { "_aseprite_wizard_config_": { @@ -522,6 +522,12 @@ attack_node = NodePath("../attack") script = ExtResource( 6 ) animation_sequence = [ "jump" ] +[node name="landing" type="Node" parent="movement_state_machine/fall" index="0"] +script = ExtResource( 9 ) +animation_name = "jump" +starting_frame = 6 +pre_append_animation = true + [node name="move" parent="movement_state_machine" index="2"] script = ExtResource( 5 ) animation_sequence = [ "step", "run" ] @@ -542,15 +548,9 @@ jump_node = NodePath("../jump") idle_node = NodePath("../idle") fall_node = NodePath("../fall") move_node = NodePath("../move") -draw_weapon_node = NodePath("../draw_weapon") +draw_weapon_node = NodePath("draw_weapon") -[node name="landing" type="Node" parent="movement_state_machine" index="5"] -script = ExtResource( 9 ) -animation_name = "jump" -starting_frame = 6 -pre_append_animation = true - -[node name="draw_weapon" type="Node" parent="movement_state_machine" index="6"] +[node name="draw_weapon" type="Node" parent="movement_state_machine/attack" index="0"] script = ExtResource( 9 ) animation_name = "_shoot" timeout_seconds = 2.2 diff --git a/src/state_animated_actor.gd b/src/state_animated_actor.gd index 9408591..5a61631 100644 --- a/src/state_animated_actor.gd +++ b/src/state_animated_actor.gd @@ -103,8 +103,8 @@ func process_input(_event: InputEvent) -> State: func process_frame(_delta: float) -> State: #if animation_sequence.size() > 0 and current_animation_sequence != animation_index: if mod_animation_sequence.size() > current_animation_sequence and current_animation_sequence != animation_index: -# if animation_index >= mod_animation_sequence.size(): -# animation_index = 0 + if animation_index >= mod_animation_sequence.size(): + animation_index = 0 ##TODO: Add a safety check here. animations.play(mod_animation_sequence[animation_index] + animation_suffix) if debug_state: @@ -143,6 +143,42 @@ func move_actor_as_desired(delta: float): move_component.velocity = parent.move_and_slide(move_component.velocity, Vector2(0, -1)) func push_animation_state_modifier(modifier: StateModifier): + ## This function attempt to optimally place multiple modifiers in an array + # in such a way where the first elements are modifiers without animation changes + # the last elements are animation changes or animation suffixes. + # there is some potential for performance issues at scale with this kinds of operations. + + # This function will grow in complexity as needed but the idea is that here is + # where different modifier logic can be tested and developed. + + # First assure this modifer isn't already there. If it is, maybe I should reset it? if modifier_stack_ref.has(modifier) == false: - modifier.enter() - modifier_stack_ref.push_front(modifier) + modifier.enter() # call enter function of the modifier + if modifier_stack_ref.size() > 0: # only bother with this if multiple modifers applied + # Get the last modifier in the stack + var last_modifer: StateModifier = modifier_stack_ref[-1] + # If the modifier at the back and the new one are the same type, we have a problem. + if last_modifer.modifier_type == modifier.modifier_type and last_modifer.modifier_type != 'None': + print("WARNING: Multiple same type modifiers applying.") + # Replace the modifier + modifier_stack_ref.pop_back() + modifier_stack_ref.push_back(modifier) + else: + match last_modifer.modifier_type: + "None": + # no special processing, push it to the front of a list + modifier_stack_ref.push_front(modifier) + "Exit Animation": + if modifier.modifier_type == "Animation Suffix": + # We place this at the back so we can still modify it maybe? + modifier_stack_ref.push_back(modifier) + "Animation Suffix": + if modifier.modifier_type == "Exit Animation": + # We have to place this one right before maybe? + modifier_stack_ref.push_back(modifier) +# if last_modifer.animation_name != '': # and if an animation applies +# if last_modifer.pre_append_animation == modifier.pre_append_animation: # They're the same type +# if modifier.pre_append_animation == true and modifier_stack_ref[-1].animation_suffix == true: +# modifier.animation_suffix +# modifier_stack_ref.push_back(modifier) + diff --git a/src/state_machine_animated_actor.gd b/src/state_machine_animated_actor.gd index 996e03e..de91d82 100644 --- a/src/state_machine_animated_actor.gd +++ b/src/state_machine_animated_actor.gd @@ -25,6 +25,13 @@ func process_frame(delta: float) -> void: # We could iterate through a whole list of states but I'm not sure i want # states to be that complex. if state_modifiers.empty() == false: + +# for i in state_modifiers: +# # if this modifer is a timer based one +# if i.state_timeout.time_left == 0 and i.timeout_seconds !=0: +# if debug_state_machine: +# print("Pop State Modifier: ", i.name) + if state_modifiers[-1].state_timeout.time_left == 0 and state_modifiers[-1].pre_append_animation == false: if debug_state_machine: print("Pop State Modifier: ", state_modifiers[-1].name) diff --git a/src/state_modifier.gd b/src/state_modifier.gd index ba0f508..bb01c4b 100644 --- a/src/state_modifier.gd +++ b/src/state_modifier.gd @@ -13,6 +13,15 @@ extends Node export var debug_state: bool = false export var animation_name: String + +## Modification Type +## if an animation is specified, the default behavior will be just to override +## the state animation. Or perform a 'Replace Animation' +export(String, "None", + "Exit Animation", + "Animation Suffix", + "Replace Animation") var modifier_type = "None" + export var starting_frame: int = 0 export var move_speed: float = 60 export var timeout_seconds: float = 0.0 @@ -35,6 +44,9 @@ var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") var state_timeout: Timer func _ready(): + # If somebody forgot to specify the type + if animation_name != '' and modifier_type == "None": + modifier_type = "Replace Animation" state_timeout = Timer.new() state_timeout.wait_time = timeout_seconds state_timeout.one_shot = true