From d912c000efef504c30579627da35bf17e317e0d4 Mon Sep 17 00:00:00 2001 From: Nitsud Yarg Date: Mon, 27 May 2024 19:23:37 -0700 Subject: [PATCH] State for animated actors now inherits from a base interface. --- .gitignore | 2 +- project.godot | 8 ++- src/playerC/Player-KinematicBody2D.gd | 8 ++- src/playerC/Player.tscn | 2 - src/playerC/states/fall.gd | 2 +- src/playerC/states/fire.gd | 2 +- src/playerC/states/hurt.gd | 2 +- src/playerC/states/idle.gd | 2 +- src/playerC/states/jump.gd | 2 +- src/playerC/states/move.gd | 2 +- src/state.gd | 78 ++------------------- src/state_animated_actor.gd | 99 +++++++++++++++++++++++++++ src/state_machine_animated_actor.gd | 14 +++- 13 files changed, 138 insertions(+), 85 deletions(-) create mode 100644 src/state_animated_actor.gd diff --git a/.gitignore b/.gitignore index 76aa238..121ad74 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ .import/ .mono/ addons/ -android/build \ No newline at end of file +android/build/ \ No newline at end of file diff --git a/project.godot b/project.godot index 3303092..2ad7811 100644 --- a/project.godot +++ b/project.godot @@ -9,7 +9,7 @@ config_version=4 _global_script_classes=[ { -"base": "Reference", +"base": "Node", "class": "Movement", "language": "GDScript", "path": "res://src/playerC/player_move_component.gd" @@ -19,6 +19,11 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://src/state.gd" }, { +"base": "State", +"class": "StateAnimatedActor", +"language": "GDScript", +"path": "res://src/state_animated_actor.gd" +}, { "base": "Node", "class": "StateMachine", "language": "GDScript", @@ -37,6 +42,7 @@ _global_script_classes=[ { _global_script_class_icons={ "Movement": "", "State": "", +"StateAnimatedActor": "", "StateMachine": "", "StateMachineAnimatedActor": "", "StateModifier": "" diff --git a/src/playerC/Player-KinematicBody2D.gd b/src/playerC/Player-KinematicBody2D.gd index 38dbd53..71aa249 100644 --- a/src/playerC/Player-KinematicBody2D.gd +++ b/src/playerC/Player-KinematicBody2D.gd @@ -50,9 +50,11 @@ func _process(delta: float) -> void: movement_state_machine.process_frame(delta) PlayerInfo.player_position = global_position -func _on_AnimatedSprite_animation_finished(): - if movement_animations.frames.get_animation_loop(movement_animations.animation) == false: - movement_state_machine.current_state.animation_index += 1 +##TODO: I don't like player class having do do this. +## Figure out how to programatically signal subscribe +#func _on_AnimatedSprite_animation_finished(): +# if movement_animations.frames.get_animation_loop(movement_animations.animation) == false: +# movement_state_machine.current_state.animation_index += 1 func _on_Hurtbox_area_entered(area): print("Ouch.",area) diff --git a/src/playerC/Player.tscn b/src/playerC/Player.tscn index 4ef3f7c..addaa08 100644 --- a/src/playerC/Player.tscn +++ b/src/playerC/Player.tscn @@ -517,5 +517,3 @@ one_shot = true points = PoolVector2Array( -5, 0, 5, 0 ) width = 2.0 default_color = Color( 1, 0.607843, 0, 1 ) - -[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"] diff --git a/src/playerC/states/fall.gd b/src/playerC/states/fall.gd index 31d31e3..8dd3b3f 100644 --- a/src/playerC/states/fall.gd +++ b/src/playerC/states/fall.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor export (NodePath) var idle_node export (NodePath) var move_node diff --git a/src/playerC/states/fire.gd b/src/playerC/states/fire.gd index 9ab1c64..077ce94 100644 --- a/src/playerC/states/fire.gd +++ b/src/playerC/states/fire.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor export (NodePath) var jump_node export (NodePath) var idle_node diff --git a/src/playerC/states/hurt.gd b/src/playerC/states/hurt.gd index e58c070..4785693 100644 --- a/src/playerC/states/hurt.gd +++ b/src/playerC/states/hurt.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor export (NodePath) var idle_node diff --git a/src/playerC/states/idle.gd b/src/playerC/states/idle.gd index f05c0f5..7c61a59 100644 --- a/src/playerC/states/idle.gd +++ b/src/playerC/states/idle.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor var debugTimeTracker := 0.0 diff --git a/src/playerC/states/jump.gd b/src/playerC/states/jump.gd index e09f4cb..63654d5 100644 --- a/src/playerC/states/jump.gd +++ b/src/playerC/states/jump.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor export (NodePath) var idle_node export (NodePath) var fall_node diff --git a/src/playerC/states/move.gd b/src/playerC/states/move.gd index 46b3662..7eaef63 100644 --- a/src/playerC/states/move.gd +++ b/src/playerC/states/move.gd @@ -1,4 +1,4 @@ -extends State +extends StateAnimatedActor var debugTimeTracker := 0.0 diff --git a/src/state.gd b/src/state.gd index 9ade050..81d707e 100644 --- a/src/state.gd +++ b/src/state.gd @@ -1,77 +1,20 @@ class_name State extends Node -## Animation and movement state class -## -## A state intended to control the movement and animation -## functions of a KinimaticBody2D node. Initialized with a -## player, movement node, and kinematicbody2d -## I think if we also had modifier states that transfered along with the enter and entrance of nodes, that would be helpful. -## -## @WIP -# export (NodePath) var jump_node -# onready var jump_state: State = get_node(jump_node) +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" -export var animation_name: String -export var move_speed: float = 60 -export var timeout_seconds: float = 0.0 - -export(Array, String) var animation_sequence -# this just wouldn't work well. Maybe I can try a resource -# export(Array, NodePath) var transition_state_nodes - -#TODO: I think these two variables accidentally serve the same purpose -# I think one was intended to be a string of the current animation name. -var animation_index: int = 0 -var current_animation_sequence: int = 0 -var animation_suffix: String = ''; - -var modifier_stack_ref: Array # Well this didn't work - -var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") - -var animations: AnimatedSprite -var move_component: Node -var parent: KinematicBody2D - -#var animation_sequence_timer: Timer - -var state_timeout: Timer +# Called when the node enters the scene tree for the first time. func _ready(): - # Only add timout node if timer value was specified. - if(timeout_seconds > 0.0): - state_timeout = Timer.new() - state_timeout.wait_time = timeout_seconds - state_timeout.one_shot = true - state_timeout.autostart = false - add_child(state_timeout) + pass # Replace with function body. func enter() -> void: - # Reset animation suffix in case there isn't one - animation_suffix = '' - print(parent.name, " entering State: ", self.name) - #modifier_stack_ref = state_modifiers - if modifier_stack_ref.empty() == false: - if modifier_stack_ref[-1].animation_name != '': - if modifier_stack_ref[-1].animation_suffix: - if animation_sequence.size() > 0: - animation_index = 0 - current_animation_sequence = 0 - # Guess I don't need this one anymore - #if animations.frames.get_animation_names().has(animation_sequence[animation_index] + modifier_stack_ref[-1].animation_name): - if animations.frames.has_animation(animation_sequence[animation_index] + modifier_stack_ref[-1].animation_name): - animation_suffix = modifier_stack_ref[-1].animation_name - else: - animations.play(modifier_stack_ref[-1].animation_name) - return - if animation_sequence.size() > 0: - animation_index = 0 - current_animation_sequence = 0 - animations.play(animation_sequence[animation_index] + animation_suffix) - return + pass + func exit() -> void: pass @@ -80,13 +23,6 @@ func process_input(_event: InputEvent) -> State: return null func process_frame(_delta: float) -> State: - if animation_sequence.size() > 0 and current_animation_sequence != animation_index: - if animation_index >= animation_sequence.size(): - animation_index = 0 - ##TODO: Add a safety check here. - animations.play(animation_sequence[animation_index] + animation_suffix) - print("An animation sequence: ", animations.animation , animation_index) - current_animation_sequence = animation_index return null func process_physics(_delta: float) -> State: diff --git a/src/state_animated_actor.gd b/src/state_animated_actor.gd new file mode 100644 index 0000000..9a9e09e --- /dev/null +++ b/src/state_animated_actor.gd @@ -0,0 +1,99 @@ +class_name StateAnimatedActor +extends State +## Animation and movement state class +## +## A state intended to control the movement and animation +## functions of a KinimaticBody2D node. Initialized with a +## player, movement node, and kinematicbody2d +## I think if we also had modifier states that transfered along with the enter and entrance of nodes, that would be helpful. +## +## @WIP + +# export (NodePath) var jump_node + +# onready var jump_state: State = get_node(jump_node) + +export var animation_name: String +export var move_speed: float = 60 +export var timeout_seconds: float = 0.0 + +export(Array, String) var animation_sequence +# this just wouldn't work well. Maybe I can try a resource +# export(Array, NodePath) var transition_state_nodes + +#TODO: I think these two variables accidentally serve the same purpose +# I think one was intended to be a string of the current animation name. +var animation_index: int = 0 +var current_animation_sequence: int = 0 +var animation_suffix: String = ''; + +var modifier_stack_ref: Array # Well this didn't work + +var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") + +var animations: AnimatedSprite +var move_component: Node +var parent: KinematicBody2D + +#var animation_sequence_timer: Timer + +var state_timeout: Timer + +func _ready(): + # Only add timout node if timer value was specified. + if(timeout_seconds > 0.0): + state_timeout = Timer.new() + state_timeout.wait_time = timeout_seconds + state_timeout.one_shot = true + state_timeout.autostart = false + add_child(state_timeout) + + +func enter() -> void: +# animations.connect("animation_finished", self, "_on_AnimatedSprite_animation_finished") + # Reset animation suffix in case there isn't one + animation_suffix = '' + print(parent.name, " entering State: ", self.name) + #modifier_stack_ref = state_modifiers + if modifier_stack_ref.empty() == false: + if modifier_stack_ref[-1].animation_name != '': + if modifier_stack_ref[-1].animation_suffix: + if animation_sequence.size() > 0: + animation_index = 0 + current_animation_sequence = 0 + # Guess I don't need this one anymore + #if animations.frames.get_animation_names().has(animation_sequence[animation_index] + modifier_stack_ref[-1].animation_name): + if animations.frames.has_animation(animation_sequence[animation_index] + modifier_stack_ref[-1].animation_name): + animation_suffix = modifier_stack_ref[-1].animation_name + else: + animations.play(modifier_stack_ref[-1].animation_name) + return + if animation_sequence.size() > 0: + animation_index = 0 + current_animation_sequence = 0 + animations.play(animation_sequence[animation_index] + animation_suffix) + return + +func exit() -> void: +# animations.disconnect("animation_finished", self, "_on_AnimatedSprite_animation_finished") + pass + +func process_input(_event: InputEvent) -> State: + return null + +func process_frame(_delta: float) -> State: + if animation_sequence.size() > 0 and current_animation_sequence != animation_index: + if animation_index >= animation_sequence.size(): + animation_index = 0 + ##TODO: Add a safety check here. + animations.play(animation_sequence[animation_index] + animation_suffix) + print("An animation sequence: ", animations.animation , animation_index) + current_animation_sequence = animation_index + return null + +func process_physics(_delta: float) -> State: + return null + +#func _on_AnimatedSprite_animation_finished(): +# if animations.frames.get_animation_loop(animations.animation) == false: +# animation_index += 1 diff --git a/src/state_machine_animated_actor.gd b/src/state_machine_animated_actor.gd index ed385bb..2acf4b6 100644 --- a/src/state_machine_animated_actor.gd +++ b/src/state_machine_animated_actor.gd @@ -3,8 +3,9 @@ class_name StateMachineAnimatedActor extends StateMachine # Initialize the state machine by giving each child state a reference to the # parent object it belongs to and enter the default starting_state. func init_animated_actor(parent: KinematicBody2D, animations: AnimatedSprite, move_component) -> void: + animations.connect("animation_finished", self, "_on_AnimatedSprite_animation_finished") for child in get_children(): - if child is State: + if child is StateAnimatedActor: print("Initializing State Node for ", parent.name, ": ", child.name) child.parent = parent child.animations = animations @@ -32,3 +33,14 @@ func process_frame(delta: float) -> void: var new_state = current_state.process_frame(delta) if new_state: change_state(new_state) + + +func _on_AnimatedSprite_animation_finished(): + if current_state.animations.frames.get_animation_loop( + current_state.animations.animation) == false: + if current_state.animation_sequence.size() > 0: + current_state.animation_index += 1 + + + +