from pygame import display, image
from pygame.locals import *
from GameChild import *
class Display(GameChild):
def __init__(self, game):
GameChild.__init__(self, game)
self.config = self.get_configuration().get_section("display")
self.set_screen()
self.set_caption()
self.set_icon()
self.subscribe_to(self.get_custom_event_id(), self.toggle_fullscreen)
def set_screen(self, flags=0):
self.screen = display.set_mode(self.config["dimensions"], flags)
# robot spaceman ninja ranger
def set_caption(self):
display.set_caption(self.config["caption"])
def set_icon(self):
if self.get_configuration().has_option("display", "icon-path"):
path = self.get_resource("display", "icon-path")
display.set_icon(image.load(path).convert_alpha())
def get_screen(self):
return self.screen
def get_size(self):
return self.screen.get_size()
def toggle_fullscreen(self, event):
if self.is_command(event, "toggle-fullscreen"):
screen = self.screen
cpy = screen.convert()
self.set_screen(self.screen.get_flags() ^ FULLSCREEN)
screen.blit(cpy, (0, 0))
from os.path import exists, join, basename, normpath, abspath
from sys import argv
from pygame import mixer, event
from pygame.locals import *
import Game
class GameChild:
def __init__(self, parent=None):
self.parent = parent
def get_game(self):
current = self
while not isinstance(current, Game.Game):
current = current.parent
return current
def get_configuration(self, section=None, option=None):
config = self.get_game().configuration
if option and section:
return config.get(section, option)
if section:
return config.get_section(section)
return config
def get_input(self):
return self.get_game().input
def get_screen(self):
return self.get_game().display.get_screen()
def get_audio(self):
return self.get_game().audio
def get_delegate(self):
return self.get_game().delegate
def get_resource(self, section, option):
config = self.get_configuration()
rel_path = config.get(section, option)
for root in config.get("setup", "resources-search-path"):
if self.is_shared_mode() and not self.is_absolute_path(root):
continue
path = join(root, rel_path)
if exists(path):
return path
self.print_debug("Couldn't find resource: {0}, {1}".\
format(section, option))
def print_debug(self, statement):
if self.is_debug_mode():
print statement
def is_absolute_path(self, path):
return normpath(path) == abspath(path)
def is_shared_mode(self):
return "-s" in argv
def subscribe_to(self, kind, callback):
self.get_game().delegate.add_subscriber(kind, callback)
def unsubscribe_from(self, kind, callback):
self.get_game().delegate.remove_subscriber(kind, callback)
def is_debug_mode(self):
return "-d" in argv
def get_custom_event_id(self):
return globals()[self.get_configuration().get("event",
"custom-event-id")]
def is_command(self, evt, cmd):
name = self.get_configuration().get("event", "command-event-name")
if not isinstance(cmd, list):
cmd = [cmd]
return evt.type == self.get_custom_event_id() and evt.name == name and \
evt.command in cmd
def post_command(self, command):
name = self.get_configuration().get("event", "command-event-name")
event.post(event.Event(self.get_custom_event_id(), name=name,
command=command))
import pygame
class Animation:
def __init__(self, frame_duration, skip_frames=False):
self.reset_ticks()
self.updates_this_cycle = 1
self.overflow = 0
self.update_count = 1
self.actual_frame_duration = 0
self.target_frame_duration = frame_duration
self.skip_frames = skip_frames
self.stopping = False
def reset_ticks(self):
self.last_ticks = self.get_ticks()
def play(self):
while not self.stopping:
self.advance_frame()
self.update_frame_duration()
self.update_overflow()
self.stopping = False
def advance_frame(self):
while self.update_count > 0:
self.sequence()
self.update_count -= 1
if not self.skip_frames:
break
def sequence(self):
pass
def update_frame_duration(self):
last_ticks = self.last_ticks
actual_frame_duration = self.get_ticks() - last_ticks
last_ticks = self.get_ticks()
wait_duration = self.get_configuration().get("display", "wait-duration")
while actual_frame_duration < self.target_frame_duration:
pygame.time.wait(wait_duration)
actual_frame_duration += self.get_ticks() - last_ticks
last_ticks = self.get_ticks()
self.actual_frame_duration = actual_frame_duration
self.last_ticks = last_ticks
def get_ticks(self):
return pygame.time.get_ticks()
def update_overflow(self):
self.update_count = 1
target_frame_duration = self.target_frame_duration
overflow = self.overflow
overflow += self.actual_frame_duration - target_frame_duration
while overflow > target_frame_duration:
self.update_count += 1
overflow -= target_frame_duration
overflow = self.overflow
def stop(self):
self.stopping = True
def clear_queue(self):
self.update_count = 1
from pygame import event
from pygame.locals import *
from GameChild import *
class EventDelegate(GameChild):
def __init__(self, game):
GameChild.__init__(self, game)
self.subscribers = dict()
self.disable()
def enable(self):
self.enabled = True
def disable(self):
self.enabled = False
def dispatch_events(self):
if self.enabled:
subscribers = self.subscribers
for evt in event.get():
kind = evt.type
if kind in subscribers:
for subscriber in subscribers[kind]:
self.print_debug("Passing {0} to {1}".\
format(evt, subscriber))
subscriber(evt)
else:
event.pump()
def add_subscriber(self, kind, callback):
self.print_debug("Subscribing {0} to {1}".\
format(callback, kind))
subscribers = self.subscribers
if kind not in subscribers:
subscribers[kind] = list()
subscribers[kind].append(callback)
def remove_subscriber(self, kind, callback):
self.subscribers[kind].remove(callback)