Windspar

Simple State Machine And Transparency Example

Oct 29th, 2025 (edited)
894
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.32 KB | Gaming | 0 0
  1. import pygame
  2.  
  3. # Simple Infinite State Machine
  4. class State:
  5.     def __init__(self, control):
  6.         self.control = control
  7.  
  8.     def on_draw(self, surface): pass
  9.     def on_event(self, event): pass
  10.     def on_update(self, delta): pass
  11.  
  12. class StateHandler:
  13.     def __init__(self):
  14.         self.states = {}
  15.         self.current = None
  16.         self.next_ = None
  17.  
  18.     def add(self, name, state):
  19.         self.states[name] = state
  20.  
  21.     def get(self, name):
  22.         return self.states[name]
  23.  
  24.     def push(self, state):
  25.         self.next_ = self.states[state]
  26.  
  27.     def update(self):
  28.         if self.next_:
  29.             self.current = self.next_
  30.             self.next_ = None
  31.  
  32. class StateControl:
  33.     def __init__(self, caption, size, flags=0, fps=60):
  34.         pygame.display.set_caption(caption)
  35.         self.display = pygame.display.set_mode(size, flags)
  36.         self.rect = self.display.get_rect()
  37.         self.clock = pygame.time.Clock()
  38.         self.running = True
  39.         self.delta = 0
  40.         self.fps = fps
  41.  
  42.         self.state = StateHandler()
  43.  
  44.     def loop(self):
  45.         while self.running:
  46.             self.state.update()
  47.             for event in pygame.event.get():
  48.                 if event.type != pygame.QUIT:
  49.                     self.state.current.on_event(event)
  50.                 else:
  51.                     self.running = False
  52.  
  53.             self.state.current.on_update(self.delta)
  54.             self.state.current.on_draw(self.display)
  55.             pygame.display.flip()
  56.             self.delta = self.clock.tick(self.fps)
  57.  
  58.     def run(self, state=None):
  59.         if state:
  60.             self.state.current = state
  61.         else:
  62.             if self.state.current is None:
  63.                 self.state.current = State(self)
  64.                 print("You forgot to set state")
  65.  
  66.         self.loop()
  67.  
  68. # States
  69. class Intro(State):
  70.     def __init__(self, control):
  71.         super().__init__(control)
  72.         font = pygame.font.Font(None, 30)
  73.         self.image = font.render("Game Intro", 1, "dodgerblue")
  74.         self.rect = self.image.get_rect()
  75.         self.rect.top = self.control.rect.top + 20
  76.         self.rect.centerx = self.control.rect.centerx
  77.  
  78.     def on_draw(self, surface):
  79.         surface.fill("black")
  80.         surface.blit(self.image, self.rect)
  81.  
  82.     def on_event(self, event):
  83.         if event.type == pygame.KEYDOWN:
  84.             self.control.state.push("Game")
  85.  
  86. class Game(State):
  87.     def __init__(self, control):
  88.         super().__init__(control)
  89.         self.images = self.create_images()
  90.         self.positions = (40, 30), (500, 200), (150, 320)
  91.  
  92.     def create_images(self):
  93.         box = pygame.Surface((100, 100))
  94.         box.fill("blue")
  95.  
  96.         rect = pygame.Rect(0, 0, 50, 50)
  97.         circle = pygame.Surface(rect.size, pygame.SRCALPHA)
  98.         pygame.draw.circle(circle, "lawngreen", rect.center, rect.width / 2 - 1)
  99.  
  100.         rect = pygame.Rect(0, 0, 60, 60)
  101.         triangle = pygame.Surface(rect.size, pygame.SRCALPHA)
  102.         points = rect.midtop, rect.bottomright, rect.bottomleft
  103.         pygame.draw.polygon(triangle, "firebrick", points)
  104.  
  105.         return box, circle, triangle
  106.  
  107.     def on_draw(self, surface):
  108.         surface.fill("black")
  109.         for (image, pos) in zip(self.images, self.positions):
  110.             surface.blit(image, pos)
  111.  
  112.     def on_event(self, event):
  113.         if event.type == pygame.KEYDOWN:
  114.             if event.key == pygame.K_SPACE:
  115.                 self.control.state.push("Pause")
  116.  
  117. class Pause(State):
  118.     def __init__(self, control):
  119.         super().__init__(control)
  120.         self.image = pygame.Surface(self.control.rect.size, pygame.SRCALPHA)
  121.         self.fill_color = pygame.Color(250, 250, 0, 100)
  122.         self.font = pygame.font.Font(None, 24)
  123.         self.alpha_sprite = QuickSprite()
  124.         self.update_alpha()
  125.  
  126.     def on_draw(self, surface):
  127.         game = self.control.state.get("Game")
  128.         game.on_draw(surface)
  129.         surface.blit(self.image, (0, 0))
  130.         self.alpha_sprite.draw(surface)
  131.  
  132.     def on_event(self, event):
  133.         if event.type == pygame.KEYDOWN:
  134.             if event.key == pygame.K_UP:
  135.                 if self.fill_color.a < 250:
  136.                     self.fill_color.a += 10
  137.                     self.update_alpha()
  138.             elif event.key == pygame.K_DOWN:
  139.                 if self.fill_color.a > 10:
  140.                     self.fill_color.a -= 10
  141.                     self.update_alpha()
  142.             else:
  143.                 self.control.state.push("Game")
  144.  
  145.     def update_alpha(self):
  146.         self.image.fill(self.fill_color)
  147.         image = self.font.render(str(self.fill_color.a), 1, 'navy')
  148.         self.alpha_sprite.set_image(image)
  149.         self.alpha_sprite.rect.top = 20
  150.         self.alpha_sprite.rect.right = self.control.rect.right - 20
  151.  
  152. # Other
  153. class QuickSprite:
  154.     def __init__(self, image=None):
  155.         if image:
  156.             self.set_image(image)
  157.  
  158.     def draw(self, surface):
  159.         surface.blit(self.image, self.rect)
  160.  
  161.     def set_image(self, image):
  162.         self.image = image
  163.         self.rect = image.get_rect()
  164.  
  165. def main():
  166.     control = StateControl("Example", (800, 600))
  167.     control.state.add("Game", Game(control))
  168.     control.state.add("Pause", Pause(control))
  169.     control.run(Intro(control))
  170.  
  171. if __name__ == "__main__":
  172.     pygame.init()
  173.     main()
  174.     pygame.quit()
  175.  
Advertisement
Add Comment
Please, Sign In to add comment