Source code for spyral.director

import spyral
import pygame

_initialized = False
_stack = []
_screen = None
_tick = 0
_max_fps = 30
_max_ups = 30

[docs]def quit(): """ Cleanly quits out of spyral by emptying the stack. """ spyral._quit()
[docs]def init(size=(0, 0), max_ups=30, max_fps=30, fullscreen=False, caption="My Spyral Game"): """ Initializes the director. This should be called at the very beginning of your game. :param size: The resolution of the display window. (0,0) uses the screen resolution :type size: :class:`Vec2D <spyral.Vec2D>` :param max_fps: The number of times that the director.update event will occur per frame. This will remain the same, even if fps drops. :type max_fps: ``int`` :param max_ups: The number of frames per second that should occur when your game is run. :type max_ups: ``int`` :param fullscreen: Whether your game should start in fullscreen mode. :type fullscreen: ``bool`` :param caption: The caption that will be displayed in the window. Typically the name of your game. :type caption: ``str`` """ global _initialized global _screen global _max_fps global _max_ups if _initialized: print 'Warning: Tried to initialize the director twice. Ignoring.' spyral._init() flags = 0 # These flags are going to be managed better or elsewhere later resizable = False noframe = False if resizable: flags |= pygame.RESIZABLE if noframe: flags |= pygame.NOFRAME if fullscreen: flags |= pygame.FULLSCREEN _screen = pygame.display.set_mode(size, flags) _initialized = True pygame.display.set_caption(caption) _max_ups = max_ups _max_fps = max_fps
[docs]def get_scene(): """ Returns the currently running scene; this will be the Scene on the top of the director's stack. :rtype: :class:`Scene <spyral.Scene>` :returns: The currently running Scene, or `None`. """ try: return _stack[-1] except IndexError: return None
[docs]def get_tick(): """ Returns the current tick number, where ticks happen on each update, not on each frame. A tick is a "tick of the clock", and will happen many (usually 30) times per second. :rtype: int :returns: The current number of ticks since the start of the game. """ return _tick
[docs]def replace(scene): """ Replace the currently running scene on the stack with *scene*. Execution will continue after this is called, so make sure you return; otherwise you may find unexpected behavior:: spyral.director.replace(Scene()) print "This will be printed!" return :param scene: The new scene. :type scene: :class:`Scene <spyral.Scene>` """ if _stack: spyral.event.handle('director.scene.exit', scene=_stack[-1]) old = _stack.pop() spyral.sprite._switch_scene() _stack.append(scene) spyral.event.handle('director.scene.enter', event=spyral.Event(scene=scene), scene=scene) # Empty all events! pygame.event.get()
[docs]def pop(): """ Pop the top scene off the stack, returning control to the next scene on the stack. If the stack is empty, the program will quit. This does return control, so remember to return immediately after calling it. """ if len(_stack) < 1: return spyral.event.handle('director.scene.exit', scene=_stack[-1]) scene = _stack.pop() spyral.sprite._switch_scene() if _stack: scene = _stack[-1] spyral.event.handle('director.scene.enter', scene=scene) else: exit(0) pygame.event.get()
[docs]def push(scene): """ Place *scene* on the top of the stack, and move control to it. This does return control, so remember to return immediately after calling it. :param scene: The new scene. :type scene: :class:`Scene <spyral.Scene>` """ if _stack: spyral.event.handle('director.scene.exit', scene=_stack[-1]) old = _stack[-1] spyral.sprite._switch_scene() _stack.append(scene) spyral.event.handle('director.scene.enter', scene=scene) # Empty all events! pygame.event.get()
[docs]def run(sugar=False, profiling=False, scene=None): """ Begins running the game, starting with the scene on top of the stack. You can also pass in a *scene* to push that scene on top of the stack. This function will run until your game ends, at which point execution will end too. :param bool sugar: Whether to run the game for Sugar. This is only to the special XO Launcher; it is safe to ignore. :param bool profiling: Whether to enable profiling mode, where this function will return on every scene change so that scenes can be profiled independently. :param scene: The first scene. :type scene: :class:`Scene <spyral.Scene>` """ if scene is not None: push(scene) if sugar: import gtk if not _stack: return old_scene = None scene = get_scene() clock = scene.clock stack = _stack while True: scene = stack[-1] if scene is not old_scene: if profiling and old_scene is not None: return clock = scene.clock old_scene = scene def frame_callback(interpolation): """ A closure for handling drawing, which includes forcing the rendering-related events to be fired. """ scene._handle_event("director.pre_render") scene._handle_event("director.render") scene._draw() scene._handle_event("director.post_render") def update_callback(delta): """ A closure for handling events, which includes firing the update related events (e.g., pre_update, update, and post_update). """ global _tick if sugar: while gtk.events_pending(): gtk.main_iteration() if len(pygame.event.get([pygame.VIDEOEXPOSE])) > 0: scene.redraw() scene._handle_event("director.redraw") scene._event_source.tick() events = scene._event_source.get() for event in events: scene._queue_event(*spyral.event._pygame_to_spyral(event)) scene._handle_event("director.pre_update") scene._handle_event("director.update", spyral.Event(delta=delta)) _tick += 1 scene._handle_event("director.post_update") clock.frame_callback = frame_callback clock.update_callback = update_callback clock.tick()