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): 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