EVR.include("menu/Background.js");
EVR.include("menu/Cursor.js");
EVR.include("menu/Option.js");
EVR.include("menu/Parser.js");
EVR.include("menu/Dispatcher.js");
EVR.Menu = function(evr, container, indicator)
{
   EVR.Graphic.call(this, container, null, null, ALIGN_TOP);
   this.dispatcher = new EVR.Menu.Dispatcher(evr, this);
   this.cursor = new EVR.Menu.Cursor(this, indicator);
   this.background = new EVR.Menu.Background(this.container);
   this.cursor_width = indicator.get_dimensions(true)[0];
   this.scroll_offset = MENU_SCROLL_OFFSET;
   this.parents = [];
   this.margin = MENU_OPTION_MARGIN;
   this.row_count = MENU_MAX_ROWS;
   this.row_height = BEAM_HEIGHT_RATIO;
   this.css.overflow = "hidden";
   this.selection = 0;
   this.set_proportions();
   this.append();
   this.build_options();
   this.draw();
   this.highlight();
}
EVR.Menu.prototype = new EVR.Graphic;
EVR.Menu.prototype.remove = function()
{
   this.background.remove();
   EVR.Graphic.prototype.remove.call(this);
}
EVR.Menu.prototype.append = function()
{
   this.background.append();
   EVR.Graphic.prototype.append.call(this);
}
EVR.Menu.prototype.place = function()
{
   var x = 0;
   var y = 0;
   if (!!this.cursor.indicator && !!this.options)
   {
      x = -this.cursor.indicator.get_dimensions(true)[0];
      y = this.calculate_y();
   }
   EVR.Graphic.prototype.place.call(this, x, y);
}
EVR.Menu.prototype.calculate_y = function()
{
//    var y = INTRODUCTION_Y_RATIO;
   var y = MENU_Y_OFFSET;
   y -= (this.row_height + this.margin) * (this.row_count - 1);
   return y;
}
EVR.Menu.prototype.draw = function()
{
   this.background.draw();
   if (!!this.options && !!this.cursor)
   {
      for (var ii = 0; ii < this.options.length; ii++)
      {
	 this.options[ii].shape();
      }
      this.cursor.shape();
      this.set_proportions();
      EVR.Graphic.prototype.draw.call(this);
      for (var ii = 0; ii < this.options.length; ii++)
      {
	 this.options[ii].draw();
      }
      this.cursor.draw();
   }
}
EVR.Menu.prototype.build_options = function()
{
   var width = MENU_OPTION_WIDTH_RATIO;
   var height = this.row_height;
   var margin = this.margin;
   var dispatcher = this.dispatcher;
   var parser = new EVR.Menu.Parser(this, width, height, margin, dispatcher);
   this.set_options(parser.options, true);
}
EVR.Menu.prototype.set_options = function(options, push)
{
   if (!!this.options && this.options.length > 0)
   {
      this.clear();
      push && this.parents.push(this.options);
   }
   this.options = options;
   for (var ii = 0; ii < this.options.length; ii++)
   {
      if (!this.options[ii].attached)
      {
	 this.options[ii].append();
      }
      this.selection = 0;
      this.highlight();
   }
}
EVR.Menu.prototype.clear = function()
{
   for (var ii = 0; ii < this.options.length; ii++)
   {
      this.options[ii].remove();
   }
   this.cursor.reset();
}
EVR.Menu.prototype.set_proportions = function()
{
   var width = null;
   var height = null;
   if (!!this.options && this.options.length > 0)
   {
      width = this.calculate_width();
      height = this.calculate_height() + this.margin / 2;
   }
   EVR.Graphic.prototype.set_proportions.call(this, width, height);
}
EVR.Menu.prototype.calculate_width = function()
{
   var width = this.options[0].get_dimensions(true)[0];
   width += this.cursor.get_width() * 2;
   return width;
}
EVR.Menu.prototype.calculate_height = function()
{
   var row_height = this.options[0].get_dimensions(true)[1];
   return this.row_count * row_height + this.margin * (this.row_count - 1);
}
EVR.Menu.prototype.select = function(direction)
{
   var selection = this.selection + direction;
   if (selection >= 0 && selection < this.options.length)
   {
      this.selection = selection;
      this.shift_cursor(direction);
      this.scroll(-direction);
      this.highlight();
   }
}
EVR.Menu.prototype.shift_cursor = function(direction)
{
   var index = this.selection;
   var offset = this.scroll_offset;
   var end = this.options.length - this.row_count + offset;
   if (direction > 0 && (index <= offset || index > end))
   {
      this.cursor.move(direction);
   }
   if (direction < 0 && (index <= offset - 1 || index > end - 1))
   {
      this.cursor.move(direction);
   }
}
EVR.Menu.prototype.scroll = function(direction)
{
   var offset = this.scroll_offset;
   var end = this.options.length - this.row_count + offset;
   if (direction < 0 && this.selection > offset && this.selection <= end)
   {
      this.shift_options(direction);
   }
   if (direction > 0 && this.selection > offset - 1 && this.selection <= end - 1)
   {
      this.shift_options(direction);
   }
}
EVR.Menu.prototype.shift_options = function(direction)
{
   for (var ii = 0; ii < this.options.length; ii++)
   {
      this.options[ii].move(direction);
   }
}   
EVR.Menu.prototype.highlight = function()
{
   for (var ii = 0; ii < this.options.length; ii++)
   {
      if (ii != this.selection)
      {
	 this.options[ii].set_color("");
      }
      else
      {
	 this.options[ii].set_color(MENU_HIGHLIGHT_COLOR);
      }
   }
}   
EVR.Menu.prototype.execute = function()
{
   this.options[this.selection].execute();
}
EVR.Menu.prototype.escape = function()
{
   if (this.parents.length > 0)
   {
      var parents = this.parents.pop();
      this.set_options(parents);
   }
}
EVR.Menu.prototype.toString = function()
{
   return "[object EVR.Menu]";
}
216.73.216.141
216.73.216.141
216.73.216.141
 
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.