from os import environ
from pygame import display, image, mouse
from pygame.locals import *
from GameChild import *
class Display(GameChild):
def __init__(self, game):
GameChild.__init__(self, game)
self.delegate = self.get_delegate()
self.load_configuration()
self.align_window()
self.init_screen()
self.set_caption()
self.set_icon()
self.set_mouse_visibility()
self.subscribe(self.toggle_fullscreen)
def load_configuration(self):
config = self.get_configuration("display")
self.centered = config["centered"]
self.fullscreen_enabled = config["fullscreen"]
self.caption = config["caption"]
self.windowed_flag = config["windowed-flag"]
self.icon_path = self.get_resource("display", "icon-path")
self.mouse_visibility = self.get_configuration("mouse", "visible")
def align_window(self):
if self.centered:
environ["SDL_VIDEO_CENTERED"] = "1"
def init_screen(self):
flags = 0
if self.fullscreen_requested():
flags = FULLSCREEN
self.set_screen(flags)
def fullscreen_requested(self):
return not self.check_command_line(self.windowed_flag) and \
self.fullscreen_enabled
def set_screen(self, flags=0, dimensions=None):
self.dimensions_changed = dimensions is not None
if dimensions is None:
if display.get_surface():
dimensions = display.get_surface().get_size()
else:
dimensions = self.get_configuration("display", "dimensions")
self.screen = display.set_mode(dimensions, flags)
if self.dimensions_changed:
interpolator = self.get_game().interpolator
if interpolator.gui_enabled:
interpolator.gui.rearrange()
def set_caption(self):
display.set_caption(self.caption)
def set_icon(self):
if self.icon_path:
print self.icon_path
display.set_icon(image.load(self.icon_path).convert_alpha())
def set_mouse_visibility(self, visibility=None):
if visibility is None:
visibility = self.mouse_visibility
return mouse.set_visible(visibility)
def get_screen(self):
return self.screen
def get_size(self):
return self.screen.get_size()
def toggle_fullscreen(self, event):
if self.delegate.compare(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, time
from pygame.locals import *
import Game
class GameChild:
def __init__(self, parent=None):
self.parent = parent
self.game = self.get_game()
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.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.game.input
def get_screen(self):
return self.game.display.get_screen()
def get_display_surface(self):
current = self
attribute = "display_surface"
while not isinstance(current, Game.Game):
if hasattr(current, attribute):
return getattr(current, attribute)
current = current.parent
return current.display.get_screen()
def get_audio(self):
return self.game.audio
def get_delegate(self):
return self.game.delegate
def get_resource(self, path_or_section, option=None):
config = self.get_configuration()
rel_path = path_or_section
if option is not None:
rel_path = config.get(path_or_section, option)
if rel_path:
for root in config.get("setup", "resource-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(path_or_section, option))
def is_shared_mode(self):
return self.check_command_line("s")
def check_command_line(self, flag):
return "-" + flag in argv
def print_debug(self, statement):
if self.is_debug_mode():
print statement
def is_debug_mode(self):
return self.check_command_line("d")
def is_absolute_path(self, path):
return normpath(path) == abspath(path)
def subscribe(self, callback, kind=None):
self.game.delegate.add_subscriber(callback, kind)
def unsubscribe(self, callback, kind=None):
self.game.delegate.remove_subscriber(callback, kind)
import cProfile
from time import strftime
from os import mkdir
from os.path import join, exists
from GameChild import GameChild
class Profile(cProfile.Profile, GameChild):
def __init__(self, parent):
GameChild.__init__(self, parent)
cProfile.Profile.__init__(self)
if self.requested():
self.enable()
def requested(self):
return self.check_command_line("p")
def end(self):
if self.requested():
root = "stat/"
if not exists(root):
mkdir(root)
self.disable()
self.create_stats()
self.dump_stats(join(root, strftime("%Y%m%d-%H%M_%S.stat")))
from GameChild import GameChild
class Animation(GameChild):
def __init__(self, parent, method=None, interval=None, unfiltered=False):
GameChild.__init__(self, parent)
self.unfiltered = unfiltered
self.default_method = method or self.build_frame
self.accounts = {}
self.register(self.default_method, interval=interval)
self.last_update = 0
def build_frame(self):
pass
def register(self, *args, **kwargs):
interval = None
if kwargs.has_key("interval"):
interval = kwargs["interval"]
for method in args:
if method not in self.accounts:
self.accounts[method] = Account(interval, self)
else:
self.accounts[method].set_interval(interval)
def play(self, method=None, interval=None, delay=0, play_once=False,
**kwargs):
account = self.accounts[self.get_default(method)]
account.set_delay(delay)
account.set_args(kwargs)
account.set_play_once(play_once)
if interval:
account.set_interval(interval)
account.play()
def get_default(self, method=None):
if not method:
method = self.default_method
return method
def halt(self, method=None):
if not method:
for account in self.accounts.values():
account.halt()
else:
if self.accounts.has_key(method):
self.accounts[method].halt()
def is_playing(self, method=None, check_all=False, include_delay=False):
if check_all:
return any(self.is_account_playing(account, include_delay) for \
method, account in self.accounts.iteritems())
return self.is_account_playing(self.accounts[self.get_default(method)],
include_delay)
def is_account_playing(self, account, include_delay):
return account.playing and (not include_delay or not account.delay)
def update(self):
for method, account in self.accounts.iteritems():
if account.update():
method(**account.args)
class Account:
def __init__(self, interval, animation):
self.animation = animation
self.time_filter = animation.get_game().time_filter
self.set_interval(interval)
self.set_delay(0)
self.set_play_once(False)
self.interval_index = 0
self.last_frame = 0
self.halt()
def set_interval(self, interval):
if isinstance(interval, int) or isinstance(interval, str):
interval = [interval]
self.interval = interval
def set_delay(self, delay):
self.delay = delay
def set_play_once(self, play_once):
self.play_once = play_once
def set_args(self, args):
self.args = args
def play(self):
self.playing = True
def halt(self):
self.last_update = None
self.playing = False
def update(self):
if self.playing:
if self.animation.unfiltered:
ticks = self.time_filter.get_unfiltered_ticks()
else:
ticks = self.time_filter.get_ticks()
self.update_delay(ticks)
if not self.delay:
interval = self.interval
if interval:
if ticks - self.last_frame < self.get_current_interval():
return False
self.last_frame = ticks
self.increment_interval_index()
if self.play_once:
self.halt()
return True
def get_current_interval(self):
return self.interval[self.interval_index]
def increment_interval_index(self):
index = self.interval_index + 1
if index >= len(self.interval):
index = 0
self.interval_index = index
def update_delay(self, ticks):
delay = self.delay
if delay > 0:
last_update = self.last_update or ticks
delay -= ticks - last_update
if delay < 0:
delay = 0
self.last_update = ticks
self.delay = delay