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))
23.20.219.0
23.20.219.0
23.20.219.0
 
September 13, 2013

from array import array
from time import sleep

import pygame
from pygame.mixer import Sound, get_init, pre_init

class Note(Sound):

    def __init__(self, frequency, volume=.1):
        self.frequency = frequency
        Sound.__init__(self, self.build_samples())
        self.set_volume(volume)

    def build_samples(self):
        period = int(round(get_init()[0] / self.frequency))
        samples = array("h", [0] * period)
        amplitude = 2 ** (abs(get_init()[1]) - 1) - 1
        for time in xrange(period):
            if time < period / 2:
                samples[time] = amplitude
            else:
                samples[time] = -amplitude
        return samples

if __name__ == "__main__":
    pre_init(44100, -16, 1, 1024)
    pygame.init()
    Note(440).play(-1)
    sleep(5)

This program generates and plays a 440 Hz tone for 5 seconds. It can be extended to generate the spectrum of notes with a frequency table or the frequency formula. Because the rewards in Send are idealized ocean waves, they can also be represented as tones. Each level has a tone in its goal and a tone based on where the player's disc lands. Both play at the end of a level, sounding harmonic for a close shot and discordant for a near miss. The game can dynamically create these tones using the program as a basis.

I'm also building an algorithmically generated song: Silk Routes (Scissored). Here is an example of how it sounds so far:


↠ RSS Feed ↞