from pygame.key import get_pressed, get_mods
from pygame.font import Font
from pygame.locals import *

from esp_hadouken.pgfw.GameChild import GameChild

class Calibrator(GameChild):

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        self.display_surface = self.get_screen()
        self.font = Font(self.parent.font_path, 10)
        self.delegate = self.get_delegate()
        self.load_configuration()
        self.render()
        self.place()
        self.subscribe(self.respond, KEYDOWN)

    def load_configuration(self):
        config = self.get_configuration("engine")
        self.step = config["calibrator-step"]

    def render(self):
        string = str(self)
        self.text = self.font.render(string, False, (0, 0, 0), (255, 255, 255))
        self.string = string

    def __str__(self):
        engine = self.parent
        accelerator = engine.accelerator
        pattern = "v {0:.2f} a {1:.2f} r {2:.2f} t {3:.2f} pa {4:.2f} " + \
                  "pd {5:.2f} lna {6:.2f} lnd {7:.2f} hna {8:.2f} d {9:.2f}"
        return pattern.format(engine.max_velocity, accelerator.attack,
                              accelerator.release, accelerator.initial_thrust,
                              accelerator.peak_acceleration,
                              accelerator.peak_distance,
                              accelerator.min_negative_acceleration,
                              accelerator.min_negative_acceleration_distance,
                              accelerator.max_negative_acceleration,
                              engine.deceleration)

    def place(self):
        rect = self.text.get_rect()
        rect.bottomleft = self.display_surface.get_rect().bottomleft
        self.rect = rect

    def respond(self, event):
        if self.parent.parent.is_active():
            if get_mods() & KMOD_CTRL and event.key == K_COMMA:
                profile = self.parent.profile
                profile.add(increment_index=True)
                profile.write()

    def update(self):
        self.calibrate()
        self.draw()

    def calibrate(self):
        state = get_pressed()
        step = self.step
        engine = self.parent
        accelerator = engine.accelerator
        if state[K_1]:
            engine.max_velocity += step
        if state[K_q]:
            engine.max_velocity -= step
        if state[K_2]:
            accelerator.attack += step
        if state[K_w]:
            accelerator.attack -= step
        if state[K_3]:
            accelerator.release += step
        if state[K_e]:
            accelerator.release -= step
        if state[K_4]:
            accelerator.initial_thrust += step
        if state[K_r]:
            accelerator.initial_thrust -= step
        if state[K_5]:
            accelerator.peak_acceleration += step
        if state[K_t]:
            accelerator.peak_acceleration -= step
        if state[K_6]:
            accelerator.peak_distance += step
        if state[K_y]:
            accelerator.peak_distance -= step
        if state[K_7]:
            accelerator.min_negative_acceleration += step
        if state[K_u]:
            accelerator.min_negative_acceleration -= step
        if state[K_8]:
            accelerator.min_negative_acceleration_distance += step
        if state[K_i]:
            accelerator.min_negative_acceleration_distance -= step
        if state[K_9]:
            accelerator.max_negative_acceleration += step
        if state[K_o]:
            accelerator.max_negative_acceleration -= step
        if state[K_0]:
            engine.deceleration += step
        if state[K_p]:
            engine.deceleration -= step

    def draw(self):
        if self.string != str(self):
            self.render()
        self.display_surface.blit(self.text, self.rect)
from esp_hadouken.pgfw.GameChild import GameChild

class Profile(GameChild, list):

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        self.delegate = self.get_delegate()
        self.load_configuration()
        self.load()
        self.apply()
        self.subscribe(self.respond)

    def load_configuration(self):
        self.path = self.get_resource("engine", "profile-path")

    def load(self):
        list.__init__(self)
        for line in file(self.path):
            self.add(line.split())
        self.index = 0

    def add(self, values=None, increment_index=False):
        if not values:
            engine = self.parent
            accelerator = engine.accelerator
            values = "NAME-ME", engine.max_velocity, accelerator.attack, \
                     accelerator.release, accelerator.initial_thrust, \
                     accelerator.peak_acceleration, accelerator.peak_distance, \
                     accelerator.min_negative_acceleration, \
                     accelerator.min_negative_acceleration_distance, \
                     accelerator.max_negative_acceleration, \
                     engine.deceleration, 1
        self.append([values[0]] + map(float, values[1:-1]) + \
                    [bool(int(values[-1]))])
        if increment_index:
            self.increment_index()


    def apply(self):
        engine = self.parent
        profile = self[self.index]
        engine.set(profile[1], profile[-2])
        engine.accelerator.set(profile[2:-2])

    def respond(self, event):
        if self.parent.parent.is_active():
            if self.delegate.compare(event, "select"):
                self.rotate()

    def rotate(self):
        self.set_next_active()
        self.apply()

    def set_next_active(self):
        while True:
            self.increment_index()
            if self[self.index][-1]:
                break

    def increment_index(self):
        index = self.index + 1
        if index >= len(self):
            index = 0
        self.index = index

    def write(self):
        stream = file(self.path, "w")
        for profile in self:
            stream.write(" ".join(map(str, profile[:-1]) + \
                                  [str(int(profile[-1]))]) + "\n")
from esp_hadouken.pgfw.GameChild import GameChild
from esp_hadouken.pgfw.Vector import Vector
from esp_hadouken.dot.engine.accelerator.Pedal import Pedal

class Accelerator(GameChild, list):

    N, NE, E, SE, S, SW, W, NW = range(8)

    def __init__(self, parent):
        GameChild.__init__(self, parent)
        self.input = self.get_input()
        self.load_configuration()
        self.init_list()

    def load_configuration(self):
        config = self.get_configuration("engine")
        self.display_flag = config["accelerator-display-flag"]

    def init_list(self):
        list.__init__(self, [Pedal(self, ii) for ii in range(8)])

    def set(self, values):
        self.attack = values[0]
        self.release = values[1]
        self.initial_thrust = values[2]
        self.peak_acceleration = values[3]
        self.peak_distance = values[4]
        self.min_negative_acceleration = values[5]
        self.min_negative_acceleration_distance = values[6]
        self.max_negative_acceleration = values[7]

    def set_slopes(self):
        self.apply_to_pedals("set_slopes")

    def apply_to_pedals(self, method):
        for pedal in self:
            getattr(pedal, method)()

    def reset(self):
        self.apply_to_pedals("reset")

    def update(self):
        S, E, N, W = self.input.get_axes().values()
        self[self.N].update(N and not W and not E)
        self[self.NE].update(N and E)
        self[self.E].update(E and not N and not S)
        self[self.SE].update(E and S)
        self[self.S].update(S and not E and not W)
        self[self.SW].update(S and W)
        self[self.W].update(W and not S and not N)
        self[self.NW].update(W and N)

    def get_sum(self):
        total = Vector()
        for pedal in self:
            total += pedal
        return total
18.218.26.136
18.218.26.136
18.218.26.136
 
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.