1 | """Top-level event dispatching and area transition.""" |
---|
2 | |
---|
3 | import pygame |
---|
4 | import pygame.locals as pgl |
---|
5 | |
---|
6 | from nagslang import constants |
---|
7 | from nagslang.screens.menu import MenuScreen |
---|
8 | from nagslang.screens.area import AreaScreen |
---|
9 | from nagslang.screens.playerdied import PlayerDiedScreen |
---|
10 | from nagslang.events import ScreenChange |
---|
11 | from nagslang.world import World |
---|
12 | |
---|
13 | |
---|
14 | class Engine(object): |
---|
15 | def __init__(self, surface): |
---|
16 | self._surface = surface |
---|
17 | self._clock = pygame.time.Clock() |
---|
18 | self._fps = constants.FPS |
---|
19 | self._dt = 1. / self._fps |
---|
20 | self._world = World() |
---|
21 | self._current_screen = None |
---|
22 | self._screens = { |
---|
23 | 'menu': MenuScreen, |
---|
24 | 'dead': PlayerDiedScreen, |
---|
25 | } |
---|
26 | for area_name in AreaScreen.list_areas(): |
---|
27 | self._screens[area_name] = AreaScreen |
---|
28 | self._world.load() |
---|
29 | self.change_screen('menu') |
---|
30 | # Dummy resize event, to force us to realise our real size |
---|
31 | # http://stackoverflow.com/q/16442573/8629 |
---|
32 | pygame.event.post(pygame.event.Event(pgl.VIDEORESIZE, |
---|
33 | size=(0, 0), w=0, h=0)) |
---|
34 | |
---|
35 | def change_screen(self, new_screen): |
---|
36 | if self._current_screen is not None: |
---|
37 | self._current_screen.teardown() |
---|
38 | screen_cls = self._screens[new_screen] |
---|
39 | self._current_screen = screen_cls(new_screen, self._world) |
---|
40 | self._current_screen.setup() |
---|
41 | |
---|
42 | def run(self): |
---|
43 | running = True |
---|
44 | while running: |
---|
45 | for ev in pygame.event.get(): |
---|
46 | if ev.type == pgl.QUIT: |
---|
47 | running = False |
---|
48 | elif ev.type == pgl.VIDEORESIZE: |
---|
49 | pygame.display.set_mode(ev.size, |
---|
50 | pgl.SWSURFACE | pgl.RESIZABLE) |
---|
51 | self._surface = pygame.display.get_surface() |
---|
52 | elif ScreenChange.matches(ev): |
---|
53 | self._surface.fill(pygame.color.Color(0, 0, 0)) |
---|
54 | self.change_screen(ev.screen) |
---|
55 | else: |
---|
56 | self._current_screen.handle_event(ev) |
---|
57 | self._current_screen.tick(self._dt) |
---|
58 | self._current_screen.render(self._surface) |
---|
59 | pygame.display.flip() |
---|
60 | self._clock.tick(self._fps) |
---|