Advertisement
thewindmage420

Python FSM Example

Feb 3rd, 2025 (edited)
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.27 KB | None | 0 0
  1. # Define a base State class with methods that all states will share.
  2. class State:
  3.     def enter(self):
  4.         pass  # Called when entering the state; override in subclasses.
  5.  
  6.     def update(self):
  7.         pass  # Called every update/frame; override in subclasses.
  8.  
  9.     def exit(self):
  10.         pass  # Called when leaving the state; override in subclasses.
  11.  
  12. # Define the IdleState, inheriting from State.
  13. class IdleState(State):
  14.     def enter(self):
  15.         print("Entering Idle State")  # Print a message when entering Idle state.
  16.  
  17.     def update(self):
  18.         # Check for transitions: if the 'W' key is pressed, transition to Walking state.
  19.         if self.fsm.input_manager.is_key_pressed('W'):
  20.             self.fsm.transition_to('Walking')
  21.    
  22.     def exit(self):
  23.         print("Exiting Idle State")  # Print a message when exiting Idle state.
  24.  
  25. # Define the WalkingState, inheriting from State.
  26. class WalkingState(State):
  27.     def enter(self):
  28.         print("Entering Walking State")  # Print a message when entering Walking state.
  29.  
  30.     def update(self):
  31.         # In a real game you would handle movement here.
  32.         # Check for transitions: if the 'W' key is released, transition back to Idle.
  33.         if self.fsm.input_manager.is_key_released('W'):
  34.             self.fsm.transition_to('Idle')
  35.    
  36.     def exit(self):
  37.         print("Exiting Walking State")  # Print a message when exiting Walking state.
  38.  
  39. # Define a simple InputManager to handle keyboard inputs.
  40. class InputManager:
  41.     def __init__(self):
  42.         # Dictionary to store the pressed state of keys.
  43.         self.key_pressed = {}
  44.         # Dictionary to store the released state of keys.
  45.         self.key_released = {}
  46.  
  47.     def process_inputs(self):
  48.         """
  49.        Process input from the user.
  50.        This simple version waits for the user to type a key.
  51.        If the user types a key, we record it as 'pressed'.
  52.        If no key is typed (just pressing Enter), we simulate releasing key 'W' if it was pressed.
  53.        """
  54.         # Ask the user for input (in a real game, input would be non-blocking).
  55.         key = input("Press a key (W to walk, or Enter to simulate release): ").strip()
  56.         if key:
  57.             # When a key is pressed, mark it as pressed (converted to uppercase).
  58.             self.key_pressed[key.upper()] = True
  59.             # Also, mark that key as not released.
  60.             self.key_released[key.upper()] = False
  61.         else:
  62.             # If no key is pressed, simulate that 'W' has been released if it was pressed before.
  63.             if self.key_pressed.get('W', False):
  64.                 self.key_pressed['W'] = False
  65.                 self.key_released['W'] = True
  66.             else:
  67.                 # Reset the released state if nothing is happening.
  68.                 self.key_released = {}
  69.  
  70.     def is_key_pressed(self, key):
  71.         """
  72.        Return True if the specified key is currently marked as pressed.
  73.        """
  74.         return self.key_pressed.get(key.upper(), False)
  75.  
  76.     def is_key_released(self, key):
  77.         """
  78.        Return True if the specified key is currently marked as released.
  79.        """
  80.         return self.key_released.get(key.upper(), False)
  81.  
  82. # Define the Finite State Machine (FSM) class that manages states.
  83. class FSM:
  84.     def __init__(self):
  85.         # Dictionary to hold the states by name.
  86.         self.states = {}
  87.         # Variable to track the current state.
  88.         self.current_state = None
  89.         # Create an instance of the InputManager to handle inputs.
  90.         self.input_manager = InputManager()
  91.  
  92.     def add_state(self, name, state):
  93.         """
  94.        Add a new state to the FSM.
  95.        'name' is a string key, and 'state' is an instance of a State.
  96.        """
  97.         self.states[name] = state
  98.         # Give the state a reference back to the FSM so it can trigger transitions.
  99.         state.fsm = self
  100.  
  101.     def transition_to(self, state_name):
  102.         """
  103.        Transition from the current state to a new state.
  104.        """
  105.         # If there is a current state, call its exit method.
  106.         if self.current_state is not None:
  107.             self.current_state.exit()
  108.         # Set the new state as the current state.
  109.         self.current_state = self.states[state_name]
  110.         # Call the enter method of the new state.
  111.         self.current_state.enter()
  112.  
  113.     def update(self):
  114.         """
  115.        Update the current state by calling its update method.
  116.        """
  117.         if self.current_state:
  118.             self.current_state.update()
  119.  
  120. # Main execution starts here.
  121.  
  122. # Create an instance of the FSM.
  123. fsm = FSM()
  124.  
  125. # Add the Idle and Walking states to the FSM.
  126. fsm.add_state('Idle', IdleState())
  127. fsm.add_state('Walking', WalkingState())
  128.  
  129. # Set the initial state of the FSM to Idle.
  130. fsm.transition_to('Idle')
  131.  
  132. # Start the game loop.
  133. # In this example, the loop will continue indefinitely.
  134. # In a real game, you would include a proper exit condition.
  135. while True:
  136.     # Process inputs using the InputManager.
  137.     fsm.input_manager.process_inputs()
  138.     # Update the FSM which in turn updates the current state.
  139.     fsm.update()
  140.     # Print the current state (class name)
  141.     print("Current State:", fsm.current_state.__class__.__name__)
  142.     # Print a separator for clarity.
  143.     print("-" * 40)
  144.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement