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.current_elapsed = 0
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 reset_timer(self, method):
if not method:
for account in self.accounts.values():
account.reset_timer()
else:
self.accounts[method].reset_timer()
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, increment=1):
index = self.interval_index + increment
while index >= len(self.interval):
index -= len(self.interval)
self.interval_index = index
def reset_interval(self):
self.interval_index = 0
def reset_timer(self):
if self.animation.unfiltered:
ticks = self.time_filter.get_unfiltered_ticks()
else:
ticks = self.time_filter.get_ticks()
self.last_frame = ticks
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
from pygame.event import get, pump, Event, post
from pygame.locals import *
from GameChild import GameChild
from Input import Input
class Delegate(GameChild):
def __init__(self, game):
GameChild.__init__(self, game)
self.subscribers = dict()
self.load_configuration()
self.disable()
def load_configuration(self):
config = self.get_configuration("event")
self.cancel_flag_key = config["cancel-flag-key"]
self.command_key = config["command-key"]
self.command_event_id = config["command-id-offset"] + \
globals()[config["user-event-id"]]
def disable(self):
self.enabled = False
def enable(self):
self.enabled = True
self.interpolator = self.get_game().interpolator
def dispatch(self):
if self.enabled:
subscribers = self.subscribers
for evt in get():
kind = evt.type
if kind in subscribers:
for subscriber in subscribers[kind]:
if not self.interpolator.is_gui_active() or \
hasattr(subscriber, "im_class") and \
(subscriber.im_class == Input or \
subscriber.im_class == \
self.interpolator.gui.__class__):
self.print_debug("Passing %s to %s" % (evt,
subscriber))
subscriber(evt)
else:
pump()
def add_subscriber(self, callback, kind=None):
self.print_debug("Subscribing %s to %s" % (callback, kind))
if kind is None:
kind = self.command_event_id
subscribers = self.subscribers
if kind not in subscribers:
subscribers[kind] = list()
subscribers[kind].append(callback)
def is_command(self, event):
return event.type == self.command_event_id
def remove_subscriber(self, callback, kind=None):
if kind is None:
kind = self.command_event_id
self.subscribers[kind].remove(callback)
def compare(self, evt, commands=None, cancel=False, **attributes):
if self.is_command(evt):
self.add_cancel_flag_to_attributes(attributes, cancel)
if commands is not None and not isinstance(commands, list):
commands = [commands]
if commands is not None:
if not self.command_in_list(evt, commands):
return False
return all(key in evt.dict and evt.dict[key] == value for \
key, value in attributes.iteritems())
def add_cancel_flag_to_attributes(self, attributes, cancel):
attributes[self.cancel_flag_key] = cancel
def command_in_list(self, evt, commands):
return self.get_command_attribute(evt) in commands
def get_command_attribute(self, evt):
return evt.dict[self.command_key]
def post(self, command=None, cancel=False, **attributes):
attributes[self.command_key] = command
self.add_cancel_flag_to_attributes(attributes, cancel)
post(Event(self.command_event_id, attributes))