Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import pygame
- # Simple Infinite State Machine
- class State:
- def __init__(self, control):
- self.control = control
- def on_draw(self, surface): pass
- def on_event(self, event): pass
- def on_update(self, delta): pass
- class StateHandler:
- def __init__(self):
- self.states = {}
- self.current = None
- self.next_ = None
- def add(self, name, state):
- self.states[name] = state
- def get(self, name):
- return self.states[name]
- def push(self, state):
- self.next_ = self.states[state]
- def update(self):
- if self.next_:
- self.current = self.next_
- self.next_ = None
- class StateControl:
- def __init__(self, caption, size, flags=0, fps=60):
- pygame.display.set_caption(caption)
- self.display = pygame.display.set_mode(size, flags)
- self.rect = self.display.get_rect()
- self.clock = pygame.time.Clock()
- self.running = True
- self.delta = 0
- self.fps = fps
- self.state = StateHandler()
- def loop(self):
- while self.running:
- self.state.update()
- for event in pygame.event.get():
- if event.type != pygame.QUIT:
- self.state.current.on_event(event)
- else:
- self.running = False
- self.state.current.on_update(self.delta)
- self.state.current.on_draw(self.display)
- pygame.display.flip()
- self.delta = self.clock.tick(self.fps)
- def run(self, state=None):
- if state:
- self.state.current = state
- else:
- if self.state.current is None:
- self.state.current = State(self)
- print("You forgot to set state")
- self.loop()
- # States
- class Intro(State):
- def __init__(self, control):
- super().__init__(control)
- font = pygame.font.Font(None, 30)
- self.image = font.render("Game Intro", 1, "dodgerblue")
- self.rect = self.image.get_rect()
- self.rect.top = self.control.rect.top + 20
- self.rect.centerx = self.control.rect.centerx
- def on_draw(self, surface):
- surface.fill("black")
- surface.blit(self.image, self.rect)
- def on_event(self, event):
- if event.type == pygame.KEYDOWN:
- self.control.state.push("Game")
- class Game(State):
- def __init__(self, control):
- super().__init__(control)
- self.images = self.create_images()
- self.positions = (40, 30), (500, 200), (150, 320)
- def create_images(self):
- box = pygame.Surface((100, 100))
- box.fill("blue")
- rect = pygame.Rect(0, 0, 50, 50)
- circle = pygame.Surface(rect.size, pygame.SRCALPHA)
- pygame.draw.circle(circle, "lawngreen", rect.center, rect.width / 2 - 1)
- rect = pygame.Rect(0, 0, 60, 60)
- triangle = pygame.Surface(rect.size, pygame.SRCALPHA)
- points = rect.midtop, rect.bottomright, rect.bottomleft
- pygame.draw.polygon(triangle, "firebrick", points)
- return box, circle, triangle
- def on_draw(self, surface):
- surface.fill("black")
- for (image, pos) in zip(self.images, self.positions):
- surface.blit(image, pos)
- def on_event(self, event):
- if event.type == pygame.KEYDOWN:
- if event.key == pygame.K_SPACE:
- self.control.state.push("Pause")
- class Pause(State):
- def __init__(self, control):
- super().__init__(control)
- self.image = pygame.Surface(self.control.rect.size, pygame.SRCALPHA)
- self.fill_color = pygame.Color(250, 250, 0, 100)
- self.font = pygame.font.Font(None, 24)
- self.alpha_sprite = QuickSprite()
- self.update_alpha()
- def on_draw(self, surface):
- game = self.control.state.get("Game")
- game.on_draw(surface)
- surface.blit(self.image, (0, 0))
- self.alpha_sprite.draw(surface)
- def on_event(self, event):
- if event.type == pygame.KEYDOWN:
- if event.key == pygame.K_UP:
- if self.fill_color.a < 250:
- self.fill_color.a += 10
- self.update_alpha()
- elif event.key == pygame.K_DOWN:
- if self.fill_color.a > 10:
- self.fill_color.a -= 10
- self.update_alpha()
- else:
- self.control.state.push("Game")
- def update_alpha(self):
- self.image.fill(self.fill_color)
- image = self.font.render(str(self.fill_color.a), 1, 'navy')
- self.alpha_sprite.set_image(image)
- self.alpha_sprite.rect.top = 20
- self.alpha_sprite.rect.right = self.control.rect.right - 20
- # Other
- class QuickSprite:
- def __init__(self, image=None):
- if image:
- self.set_image(image)
- def draw(self, surface):
- surface.blit(self.image, self.rect)
- def set_image(self, image):
- self.image = image
- self.rect = image.get_rect()
- def main():
- control = StateControl("Example", (800, 600))
- control.state.add("Game", Game(control))
- control.state.add("Pause", Pause(control))
- control.run(Intro(control))
- if __name__ == "__main__":
- pygame.init()
- main()
- pygame.quit()
Advertisement
Add Comment
Please, Sign In to add comment