147 lines
6.3 KiB
GDScript
147 lines
6.3 KiB
GDScript
class_name StateMachineAnimatedActor extends StateMachine
|
|
|
|
func change_state(new_state: State) -> void:
|
|
if new_state.state_ready == false:
|
|
# Don't transition to unready state
|
|
return
|
|
if current_state:
|
|
current_state.exit()
|
|
# Set parameters for information
|
|
if new_state is StateAnimatedActor and current_state is StateAnimatedActor:
|
|
set_previous_animation( current_state, new_state)
|
|
if current_state.modifier: # Current state has a modifier
|
|
new_state.transfer_modifiers(current_state.modifier)
|
|
current_state.modifier = null
|
|
if current_state.physics_modifier: # Current state has a physics modifier
|
|
new_state.physics_modifier = current_state.physics_modifier
|
|
current_state.physics_modifier = null
|
|
|
|
current_state = new_state
|
|
current_state.enter()
|
|
# if(state_modifiers.size() > 0 and debug_state_machine):
|
|
# print("Active Modifiers:")
|
|
# for mods in state_modifiers:
|
|
# print(mods.name)
|
|
|
|
func set_previous_animation( old_state: StateAnimatedActor, new_state: StateAnimatedActor ) -> void:
|
|
# added this to help prevent nul index crashes. (Usually because of signal based state changes.)
|
|
if old_state.mod_animation_sequence:
|
|
new_state.previous_animation_name = old_state.mod_animation_sequence[old_state.current_animation_sequence]
|
|
new_state.previous_state_frame_number = old_state.animations.frame
|
|
new_state.previous_state_name = old_state.name
|
|
new_state.previous_speed_multiplier = old_state.speed_multiplier
|
|
#animation_name :String, frame_number : int, animation_sequence :Array
|
|
return
|
|
|
|
# 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: MovementComponent) -> void:
|
|
animations.connect("animation_finished", self, "_on_AnimatedSprite_animation_finished")
|
|
# for child in get_children():
|
|
# if child is StateAnimatedActor:
|
|
# if debug_state_machine:
|
|
# print("Initializing State Node for ", parent.name, ": ", child.name)
|
|
# child.parent = parent
|
|
# child.animations = animations
|
|
# child.move_component = move_component
|
|
## child.modifier_stack_ref = state_modifiers
|
|
# if debug_state_machine:
|
|
# child.debug_state = true
|
|
#states["default"] = StateAnimatedActor.new()
|
|
for s in states.keys():
|
|
var child = states[s]
|
|
if child is StateAnimatedActor:
|
|
if debug_state_machine:
|
|
print("Initializing State Node for ", parent.name, ": ", s)
|
|
child.debug_state = true
|
|
child.parent = parent
|
|
child.animations = animations
|
|
child.move_component = move_component
|
|
child.name = s
|
|
|
|
if states.has("default"):
|
|
print("I still haz default state")
|
|
change_state(states.default)
|
|
# current_state = states.default
|
|
# if current_state is StateAnimatedActor:
|
|
# current_state.animations = animations
|
|
# current_state.parent = parent
|
|
# current_state.move_component = move_component
|
|
# current_state.enter()
|
|
# #current_state.set_script("res://lib/templates/Actor/states/idle.gd")
|
|
|
|
# Initialize to the default state
|
|
#change_state(get_node(starting_state))
|
|
|
|
#change_state(states.default)
|
|
|
|
|
|
func process_frame(delta: float) -> void:
|
|
# Check the state modifiers for timeouts, and maybe more conditions later
|
|
# If the modifier is no longer valid, pop it from the stack.
|
|
# We could iterate through a whole list of states but I'm not sure i want
|
|
# states to be that complex.
|
|
# var current_anim_state :StateAnimatedActor = current_state
|
|
# if state_modifiers.empty() == false:
|
|
# for i in range(state_modifiers.size()):
|
|
# # if this modifer is a timer based one
|
|
# if state_modifiers[i].state_timeout.time_left == 0 and state_modifiers[i].timeout_seconds !=0:
|
|
# # Need to do extra stuff if it's an animation based one
|
|
# if state_modifiers[i].modifier_type == "Animation Suffix":
|
|
# if debug_state_machine:
|
|
# print("State Modifier Timeout: ", state_modifiers[i].name, " -> ", state_modifiers[i].animation_name)
|
|
# # Reset animation suffix
|
|
# current_anim_state.animation_suffix = ''
|
|
# # Get the current frame of animation
|
|
# var current_frame = current_anim_state.animations.frame
|
|
#
|
|
# # Set the animation index to the current one
|
|
# current_anim_state.animation_index = current_anim_state.current_animation_sequence
|
|
# #current_anim_state.current_animation_sequence
|
|
# #current_anim_state.animations.play()
|
|
#
|
|
# current_anim_state.animations.play(
|
|
# current_anim_state.mod_animation_sequence[current_anim_state.animation_index])
|
|
# # Try to set the current frame to the same as before.
|
|
# current_anim_state.animations.frames.frames.size() >= current_frame
|
|
# current_anim_state.animations.frame = current_frame
|
|
#
|
|
# if debug_state_machine:
|
|
# print("Pop State Modifier: ", state_modifiers[i].name)
|
|
# state_modifiers.pop_at(i)
|
|
if current_state is StateAnimatedActor:
|
|
current_state.process_animations()
|
|
change_to_known_state( current_state.process_frame(delta) )
|
|
|
|
|
|
func _on_AnimatedSprite_animation_finished():
|
|
# if debug_state_machine:
|
|
# print("Stop!!!!!")
|
|
##TODO:
|
|
# It's hard to pop an exit animation off when it's stacked with another kind of animation.
|
|
# for i in state_modifiers.size():
|
|
# if state_modifiers[i].modifier_type == "Exit Animation":
|
|
# #print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation + current_state.animation_suffix)
|
|
# if (state_modifiers[i].animation_name + current_state.animation_suffix) == current_state.animations.animation:
|
|
# print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation )
|
|
# print(current_state.mod_animation_sequence)
|
|
# state_modifiers.pop_at(i)
|
|
# current_state.animation_index += 1
|
|
# break
|
|
|
|
# if current_state is StateAnimatedActor:
|
|
# current_state.animation_finished = true
|
|
if current_state.animations.frames.get_animation_loop(
|
|
current_state.animations.animation) == false:
|
|
#print("Stop!!!!!", current_state.animation_sequence.size(), " - ", current_state.animation_index)
|
|
if current_state.animation_sequence.size() > 0:
|
|
#print("<-- next anim.")
|
|
current_state.animation_index += 1
|
|
if current_state.animation_index >= current_state.animation_sequence.size():
|
|
#print("Stop!!!!!")
|
|
current_state.animation_finished = true
|
|
|
|
|
|
|
|
|