A state machine for organizing different in-game screens in python.
This library supports python versions 3.8 - 3.14.
Create and activate a virtual environment in your workspace (optional) and run the following command-
pip install game_state
Note: This package does not have any dependancy on
pygame, hence you will need to install them separately on your own. This gives you the freedom to work withpygame,pygame-ceor any other library.
This is an example of creating two screens. One displaying green colour and the other blue with a player.
import pygame
from game_state import State, StateManager
from game_state.utils import MISSING
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
speed = 200
pygame.init()
pygame.display.init()
pygame.display.set_caption("Game State Example")
class MyBaseState(State["MyBaseState"]):
window: pygame.Surface = MISSING
# Attributes we want all our states to share.
def process_event(self, event: pygame.event.Event) -> None:
pass
def process_update(self, dt: float) -> None:
pass
class MainMenuState(MyBaseState, state_name="MainMenu"):
def process_event(self, event: pygame.event.Event) -> None:
if event.type == pygame.QUIT:
self.manager.is_running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
self.manager.change_state("Game")
def process_update(self, dt: float) -> None:
self.window.fill(GREEN)
pygame.display.update()
class GameState(MyBaseState, state_name="Game"):
def __init__(self) -> None:
self.player_x: float = 250.0
def process_event(self, event: pygame.event.Event) -> None:
if event.type == pygame.QUIT:
self.manager.is_running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_w:
self.manager.change_state("MainMenu")
def process_update(self, dt: float) -> None:
self.window.fill(BLUE)
pressed = pygame.key.get_pressed()
if pressed[pygame.K_a]:
self.player_x -= speed * dt
if pressed[pygame.K_d]:
self.player_x += speed * dt
pygame.draw.rect(
self.window,
"red",
(self.player_x, 100, 50, 50),
)
pygame.display.update()
def main() -> None:
window = pygame.display.set_mode((500, 600))
state_manager = StateManager(bound_state_type=MyBaseState, window=window)
state_manager.load_states(MainMenuState, GameState)
state_manager.change_state("MainMenu")
clock = pygame.time.Clock()
while state_manager.is_running:
dt = clock.tick(60) / 1000
for event in pygame.event.get():
state_manager.current_state.process_event(event)
state_manager.current_state.process_update(dt)
if __name__ == "__main__":
main()You can have a look at the game state guide for a more detailed explaination.
- Guide & API Reference: https://game-state.readthedocs.io/en/stable/
- PyPI Page: https://pypi.org/project/game-state/
- Github Page: https://github.com/Jiggly-Balls/game-state/