Created
June 3, 2023 11:58
-
-
Save WolfgangSenff/469bb278647da5820dfa2550d175c708 to your computer and use it in GitHub Desktop.
Pushdown Automata Godot 4.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends RefCounted | |
class_name StateMachine | |
class PDA: | |
var stack = [] | |
func push(state): | |
if stack.size() > 0: | |
stack[-1].exit(state) | |
stack.append(state) | |
state.enter(stack.size() > 1 if stack[stack.size() - 2] != null else null) | |
Debug.info("Entering state: " + state.get_script().to_string()) | |
func pop(): | |
var prev_state = stack.pop_back() | |
Debug.info("Leaving state: " + prev_state.get_script().to_string()) | |
prev_state.exit(stack.size() > 0 if stack.back() != null else null) | |
if stack.size() > 0: | |
stack.back().enter(prev_state) | |
return prev_state | |
func pop_and_push(state): | |
pop() | |
push(state) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Node | |
class_name States # Give it a class_name to refer to the states more easily without having to make this a singleton | |
class State: | |
var _character # Reference to character | |
var Gravity = ProjectSettings.get("physics/2d/default_gravity") | |
func _init(character): | |
_character = character | |
func enter(previous_state): | |
pass | |
func exit(next_state): | |
pass | |
func physics_process(delta): | |
pass | |
# Example 1: | |
class SideIdle extends State: | |
func enter(previous_state): | |
_character.state_machine.stack = [] | |
_character.state_machine.stack.append(self) | |
_character.play_animation("Idle") | |
_character.velocity.x = 0.0 | |
func physics_process(delta): | |
if _character.is_moving(): | |
_character.state_machine.push(SideMove.new(_character)) | |
return | |
if _character.is_jumping(): | |
_character.state_machine.push(SideJump.new(_character)) | |
# Example 2: | |
class SideFalling extends State: | |
func enter(previous_state): | |
_character.play_animation("Fall") | |
if not _character.state_machine.stack.any(func(state): state is SideJump): # Actually use PDA to check for jump in previous states to prevent coyote jumping if you've jumped already | |
_character.coyote_timer = _character.coyote_time | |
... # There's a lot more here, this was just to show the use of the PDA's stack |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment