EVR.Animation.Ending.Tombstone.Base = function(tombstone)
{
   EVR.Graphic.call(
      this, tombstone.container, RATIO_HEIGHT, tombstone, ALIGN_BOTTOM);
   this.set_attributes();
}
EVR.Animation.Ending.Tombstone.Base.prototype = new EVR.Graphic;
EVR.Animation.Ending.Tombstone.Base.prototype.set_attributes = function()
{
   this.set_proportions(TOMBSTONE_BASE_WIDTH, TOMBSTONE_BASE_HEIGHT);
   this.set_color(TOMBSTONE_COLOR);
   this.set_z(TOMBSTONE_BASE_Z_INDEX);
   this.css.borderTop = TOMBSTONE_BASE_BORDER;
}
EVR.Animation.Ending.Tombstone.Base.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Tombstone.Base]";
}
EVR.include("animation/ending/tombstone/cross/Cross.js");
EVR.include("animation/ending/tombstone/Base.js");
EVR.Animation.Ending.Tombstone = function(ending)
{
   EVR.Graphic.call(this, ending.container, RATIO_HEIGHT, null, ALIGN_BOTTOM);
   this.ending = ending;
   this.set_attributes();
   this.cross = new EVR.Animation.Ending.Tombstone.Cross(this);
   this.base = new EVR.Animation.Ending.Tombstone.Base(this);
}
EVR.Animation.Ending.Tombstone.prototype = new EVR.Graphic;
EVR.Animation.Ending.Tombstone.prototype.set_attributes = function()
{
   this.set_proportions(TOMBSTONE_WIDTH, TOMBSTONE_HEIGHT);
   this.set_color(TOMBSTONE_COLOR);
   this.place(TOMBSTONE_OFFSET, this.ending.y_offset);
   this.set_z(TOMBSTONE_Z_INDEX);
   this.css.borderTop = TOMBSTONE_BORDER;
}
EVR.Animation.Ending.Tombstone.prototype.append = function()
{
   EVR.Graphic.prototype.append.call(this);
   this.base.append();
}
EVR.Animation.Ending.Tombstone.prototype.draw = function()
{
   EVR.Graphic.prototype.draw.call(this);
   this.base.draw();
   this.cross.draw();
}
EVR.Animation.Ending.Tombstone.prototype.remove = function()
{
   this.base.remove();
   EVR.Graphic.prototype.remove.call(this);
}
EVR.Animation.Ending.Tombstone.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Tombstone]";
}
EVR.Animation.Ending.Tombstone.Cross.Horizontal = function(cross)
{
   EVR.Graphic.call(this, cross.tombstone, null, null, ALIGN_TOP);
   this.set_attributes();
}
EVR.Animation.Ending.Tombstone.Cross.Horizontal.prototype = new EVR.Graphic;
EVR.Animation.Ending.Tombstone.Cross.Horizontal.prototype.set_attributes =
   function()
{
   this.set_color(TOMBSTONE_CROSS_COLOR);
   var thickness = TOMBSTONE_CROSS_THICKNESS;
   this.set_proportions(TOMBSTONE_CROSS_WIDTH, thickness);
   this.place(null, TOMBSTONE_CROSS_BAR_OFFSET);
}
EVR.Animation.Ending.Tombstone.Cross.Horizontal.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Tombstone.Cross.Horizontal]";
}
EVR.Animation.Ending.Tombstone.Cross.Vertical = function(cross)
{
   EVR.Graphic.call(this, cross.tombstone, null, null, ALIGN_TOP);
   this.set_attributes();
}
EVR.Animation.Ending.Tombstone.Cross.Vertical.prototype = new EVR.Graphic;
EVR.Animation.Ending.Tombstone.Cross.Vertical.prototype.set_attributes =
   function()
{
   this.set_color(TOMBSTONE_CROSS_COLOR);
   var thickness = TOMBSTONE_CROSS_THICKNESS / TOMBSTONE_WIDTH;
   this.set_proportions(TOMBSTONE_CROSS_THICKNESS, TOMBSTONE_CROSS_HEIGHT);
   this.place(null, TOMBSTONE_CROSS_OFFSET);
}
EVR.Animation.Ending.Tombstone.Cross.Vertical.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Tombstone.Cross.Vertical]";
}
EVR.include("animation/ending/tombstone/cross/Vertical.js");
EVR.include("animation/ending/tombstone/cross/Horizontal.js");
EVR.Animation.Ending.Tombstone.Cross = function(tombstone)
{
   this.tombstone = tombstone;
   this.add_bars();
   this.append();
}
EVR.Animation.Ending.Tombstone.Cross.prototype.add_bars = function()
{
   this.bars = [
      new EVR.Animation.Ending.Tombstone.Cross.Vertical(this),
      new EVR.Animation.Ending.Tombstone.Cross.Horizontal(this)];
}
EVR.Animation.Ending.Tombstone.Cross.prototype.append = function()
{
   var bars = this.bars;
   bars[0].append();
   bars[1].append();
}
EVR.Animation.Ending.Tombstone.Cross.prototype.draw = function()
{
   var bars = this.bars;
   bars[0].draw();
   bars[1].draw();
   this.fixDimensions();
}
EVR.Animation.Ending.Tombstone.Cross.prototype.fixDimensions = function()
{
   var bars = this.bars;
   var horizontal = bars[1];
   var vertical = bars[0];
   var horizontal_width = horizontal.get_dimensions()[0];
   var vertical_width = vertical.get_dimensions()[0];
   if ((horizontal_width - vertical_width) % 2)
   {
      vertical.set_dimensions(vertical_width + 1);
   }
}
EVR.Animation.Ending.Tombstone.Cross.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Tombstone.Cross]";
}
EVR.Animation.Ending.Message = function(ending)
{
   EVR.Animation.call(this, ENDING_MESSAGE_FRAME_RATE);
   this.container = ending.container;
   this.color = ENDING_MESSAGE_TEXT_COLOR;
   this.family = ENDING_MESSAGE_FONT_FAMILY;
   this.depth = ENDING_MESSAGE_Z_INDEX;
   this.attached = false;
   this.add_prompts();
}
EVR.Animation.Ending.Message.prototype = new EVR.Animation;
EVR.Animation.Ending.Message.prototype.add_prompts = function()
{
   this.prompts = [];
//    this.add_title();
//    this.add_thanks();
   this.add_command();
}
EVR.Animation.Ending.Message.prototype.add_title = function()
{
   var text = ENDING_MESSAGE_TITLE_TEXT;
   var size = ENDING_MESSAGE_TITLE_SIZE;
   var spacing = ENDING_MESSAGE_TITLE_LETTER_SPACING;
   var offset = [0, ENDING_MESSAGE_TITLE_OFFSET];
   this.add_prompt(text, size, spacing, offset);
}
EVR.Animation.Ending.Message.prototype.add_thanks = function()
{
   var text = ENDING_MESSAGE_THANKS_TEXT;
   var size = ENDING_MESSAGE_THANKS_SIZE;
   var spacing = ENDING_MESSAGE_THANKS_LETTER_SPACING;
   var offset = [0, ENDING_MESSAGE_THANKS_OFFSET];
   this.add_prompt(text, size, spacing, offset);
}
EVR.Animation.Ending.Message.prototype.add_command = function()
{
   var text = ENDING_MESSAGE_COMMAND_TEXT;
   var size = ENDING_MESSAGE_COMMAND_SIZE;
   var spacing = ENDING_MESSAGE_COMMAND_LETTER_SPACING;
   var offset = [0, ENDING_MESSAGE_COMMAND_OFFSET];
   this.add_prompt(text, size, spacing, offset);
}
EVR.Animation.Ending.Message.prototype.add_prompt = function(
   text, size, spacing, offset)
{
   this.prompts.push(new EVR.Prompt(
      this.container, text, this.color, size, null, this.depth, null, offset,
      spacing));
}
EVR.Animation.Ending.Message.prototype.sequence = function()
{
   var palette = TRANSMISSION_COLORS;
   var color = palette[Math.get_random_int(0, palette.length - 1)]
   var prompts = this.prompts;
   for (var ii = 0; ii < prompts.length; ii++)
   {
	 prompts[ii].text.css.color = color;
   }
}
EVR.Animation.Ending.Message.prototype.append = function()
{
   this.apply_to_prompts("append");
   this.attached = true;
   this.play();
}
EVR.Animation.Ending.Message.prototype.apply_to_prompts = function(method)
{
   var prompt, prompts = this.prompts;
   var args = Array.prototype.slice.call(arguments);
   for (var ii = 0; ii < prompts.length; ii++)
   {
      prompt = prompts[ii];
      prompt[method].apply(prompt, args.slice(1));
   }
}
EVR.Animation.Ending.Message.prototype.draw = function()
{
   this.apply_to_prompts("draw");
}
EVR.Animation.Ending.Message.prototype.remove = function()
{
   this.stop();
   if (this.attached)
   {
      this.apply_to_prompts("remove");
   }
   this.attached = false;
}
EVR.Animation.Ending.Message.prototype.toString = function()
{
   return "[object EVR.Animation.Ending.Message]";
}
3.146.152.147
3.146.152.147
3.146.152.147
 
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.