Updated escoria-demo-game

This commit is contained in:
2023-06-06 19:28:49 +02:00
parent 6d3bd3511c
commit 0d38a8646a
116 changed files with 1670 additions and 1291 deletions

View File

@@ -0,0 +1,31 @@
"""
Base interface for all states: it doesn't do anything in itself
but forces us to pass the right arguments to the methods below
and makes sure every State object had all of these methods.
"""
extends Node
signal finished(next_state_name)
# Initialize the state. E.g. change the animation
func enter():
return
# Clean up the state. Reinitialize values like a timer
func exit():
return
func handle_input(_event):
return
func update(_delta):
return
func _on_animation_finished(_anim_name):
return

View File

@@ -0,0 +1,92 @@
"""
Base interface for a generic state machine
It handles initializing, setting the machine active or not
delegating _physics_process, _input calls to the State nodes,
and changing the current/active state.
"""
extends Node
signal state_changed(current_state)
"""
You must set a starting node from the inspector or on
the node that inherits from this state machine interface
If you don't the game will crash (on purpose, so you won't
forget to initialize the state machine)
"""
export(NodePath) var START_STATE
var states_map = {}
var states_stack = [] # can also be used as a pushdown automaton
var current_state = null
var current_state_name = ""
var _active = false setget set_active
func initialize(start_state):
for child in get_children():
child.connect("finished", self, "_change_state")
set_active(true)
states_stack.push_front(start_state)
current_state = states_stack[0]
current_state.enter()
func set_active(value):
_active = value
set_physics_process(value)
set_process_input(value)
if not _active:
states_stack = []
current_state = null
func _input(event):
current_state.handle_input(event)
func _physics_process(delta):
current_state.update(delta)
func _on_animation_finished(anim_name):
if not _active:
return
current_state._on_animation_finished(anim_name)
func _change_state(state_name):
if not _active:
return
escoria.logger.trace(
self,
"Dialog State Machine: Changing state from '%s' to '%s'." % [current_state_name, state_name]
)
current_state.exit()
if state_name == "previous":
states_stack.pop_front()
else:
states_stack[0] = states_map[state_name]
current_state = states_stack[0]
emit_signal("state_changed", current_state)
#if state_name != "previous":
current_state.enter()
current_state_name = state_name
func get_current_state_name():
for key in states_map.keys():
if states_map[key] == current_state:
return key
return null