Source code for ezpygame.scene

[docs]class Scene: """An isolated scene which can be ran by an application. Create your own scene by subclassing and overriding any methods. The hosting :class:`.Application` instance is accessible through the :attr:`application` property. Example usage with two scenes interacting: .. code-block:: python class Menu(Scene): def __init__(self): self.font = pygame.font.Font(...) def on_enter(self, previous_scene): self.application.title = 'Main Menu' self.application.resolution = (640, 480) self.application.update_rate = 30 def draw(self, screen): pygame.draw.rect(...) text = self.font.render(...) screen.blit(text, ...) def handle_event(self, event): if event.type == pygame.MOUSEBUTTONUP: if event.button == 1: game_size = self._get_game_size(event.pos) self.change_scene(Game(game_size)) def _get_game_size(self, mouse_pos_upon_click): ... class Game(ezpygame.Scene): title = 'The Game!' resolution = (1280, 720) update_rate = 60 def __init__(self, size): super().__init__() self.size = size self.player = ... ... def on_enter(self, previous_scene): super().on_enter(previous_scene) self.previous_scene = previous_scene def draw(self, screen): self.player.draw(screen) for enemy in self.enemies: ... def update(self, dt): self.player.move(dt) ... if self.player.is_dead(): self.application.change_scene(self.previous_scene) elif self.player_won(): self.application.change_scene(...) def handle_event(self, event): ... # Player movement etc. The above two classes use different approaches for changing the application's settings when the scene is entered: 1. Manually set them in :meth:`on_enter`, as seen in ``Menu`` 2. Use class variables, as I did with ``Game`` When using class variables (2), you can leave out any setting (defaults to ``None``) to not override that particular setting. If you override :meth:`on_enter` in the subclass, you must call ``super().on_enter(previous_scene)`` to use the class variables. These settings can further be overridden in individual instances: .. code-block:: python my_scene0 = MyScene() my_scene0.resolution = (1280, 720) my_scene1 = MyScene(title='My Second Awesome Scene') """ title = None resolution = None update_rate = None def __init__(self, title=None, resolution=None, update_rate=None): self._application = None if title is not None: self.title = title if resolution is not None: self.resolution = resolution if update_rate is not None: self.update_rate = update_rate @property def application(self): """The host application that's currently running the scene.""" return self._application
[docs] def draw(self, screen): """Override this with the scene drawing. :param pygame.Surface screen: screen to draw the scene on """
[docs] def update(self, dt): """Override this with the scene update tick. :param int dt: time in milliseconds since the last update """
[docs] def handle_event(self, event): """Override this to handle an event in the scene. All of :mod:`pygame`'s events are sent here, so filtering should be applied manually in the subclass. :param pygame.event.Event event: event to handle """
[docs] def on_enter(self, previous_scene): """Override this to initialize upon scene entering. The :attr:`application` property is initialized at this point, so you are free to access it through ``self.application``. Stuff like changing resolution etc. should be done here. If you override this method and want to use class variables to change the application's settings, you must call ``super().on_enter(previous_scene)`` in the subclass. :param Scene|None previous_scene: previous scene to run """ for attr in ('title', 'resolution', 'update_rate'): value = getattr(self, attr) if value is not None: setattr(self.application, attr.lower(), value)
[docs] def on_exit(self, next_scene): """Override this to deinitialize upon scene exiting. The :attr:`application` property is still initialized at this point. Feel free to do saving, settings reset, etc. here. :param Scene|None next_scene: next scene to run """