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: 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 # Initialize to the default state change_state(get_node(starting_state)) 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. if state_modifiers.empty() == false: if state_modifiers[-1].state_timeout.time_left == 0: if debug_state_machine: print("Pop State Modifier: ", state_modifiers[-1].name) state_modifiers.pop_back() # Reset animation suffix current_state.animation_suffix = '' var current_frame = current_state.animations.frame #current_state.animations.play(current_state.animation_sequence[current_state.animation_index]) #TODO: Bodge to fix crash current_state.animation_index = 0 current_state.current_animation_sequence = 0 current_state.animations.play(current_state.animation_sequence[0]) current_state.animations.frame = current_frame; 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