EVR.Delegate.Keys = function()
{
   this.codes = [];
}
EVR.Delegate.Keys.prototype.add = function(code)
{
   this.codes.push(code);
}
EVR.Delegate.Keys.prototype.remove = function(code)
{
   var index = this.find(code);
   if (index !== null)
   {
      this.codes.splice(index, 1)
   }
}
EVR.Delegate.Keys.prototype.find = function(code)
{
   var codes = this.codes;
   for (var ii = codes.length - 1; ii >= 0; ii--)
   {
      if (codes[ii] == code)
      {
	 return ii;
      }
   }
   return null;
}
EVR.Delegate.Keys.prototype.toString = function()
{
   return "[object EVR.Delegate.Keys]";
}
EVR.include("delegate/Keys.js")

EVR.Delegate = function(application)
{
   this.application = application;
   this.introduction = application.introduction;
   this.history = application.history;
   this.resize_response = false;
   this.keys_down = new EVR.Delegate.Keys();
}

EVR.Delegate.prototype.handle_key_down = function(event)
{
   event = this.fix_event(event);
   var code = event.keyCode;
   if (this.keys_down.find(code) !== null)
   {
      return;
   }
   if (code == KEY_C)
   {
      console.toggle_visibility();
      this.application.repopulate();
   }
   if (code == KEY_ENTER)
   {
      this.handle_enter();
   }
   if (code == KEY_UP || code == KEY_UP_ALTERNATE)
   {
      !!this.menu && this.menu.attached && this.menu.select(-1);
      !!this.level && this.level.delegate.up();
   }
   if (code == KEY_DOWN || code == KEY_DOWN_ALTERNATE)
   {
      !!this.menu && this.menu.attached && this.menu.select(1);
      !!this.level && this.level.delegate.down();
   }
   if (code == KEY_SPRINT || code == KEY_SPRINT_ALTERNATE)
   {
      !!this.level && this.level.delegate.sprint();
   }
   if (code == KEY_GRID)
   {
      !!this.album && this.album.attached && this.album.toggle_grid();
   }
   if (code == KEY_PREVIOUS_PAGE)
   {
      !!this.album && this.album.attached && this.album.previous();
   }
   if (code == KEY_NEXT_PAGE)
   {
      !!this.album && this.album.attached && this.album.next();
   }
   if (code == KEY_QUIT)
   {
      !!this.album && this.album.attached && this.application.unload_album();
      !!this.ending && this.ending.visible && this.application.unload_ending();
   }
   if (code == KEY_MENU)
   {
      !!this.level && this.level.delegate.main_menu();
   }
   if (code == KEY_NEXT_LEVEL)
   {
      !!this.level && this.level.delegate.next_level();
   }
   if (code == KEY_SOUND)
   {
      this.application.toggle_sound();
   }
   this.keys_down.add(code);
}

EVR.Delegate.prototype.handle_enter = function()
{
   if (!!this.ending && this.ending.finished)
   {
      this.application.unload_ending();
      return;
   }
   if (!!this.about && this.about.attached)
   {
      this.application.unload_about();
      return;
   }
   if (!!this.instructions && this.instructions.attached)
   {
      this.application.unload_instructions();
      return;
   }
   if (this.history.attached)
   {
      this.application.unload_history();
      return;
   }
   if (!!this.level)
   {
      this.level.delegate.enter();
   }
   if (!!this.menu && this.menu.attached)
   {
      this.menu.execute();
   }
   if (!!this.album)
   {
      this.album.attached && this.album.toggle_menu();
   }
   if (!!!this.level)
   {
      this.application.build_start_menu();
   }
}

EVR.Delegate.prototype.handle_key_up = function(event)
{
   event = this.fix_event(event);
   var code = event.keyCode;
   if (code == KEY_SPRINT || code == KEY_SPRINT_ALTERNATE)
   {
      !!this.level && this.level.delegate.cancel_sprint();
   }
   this.keys_down.remove(code);
}

EVR.Delegate.prototype.handle_key_press = function(event)
{
   event = this.fix_event(event);
   var code = event.keyCode || event.charCode;
   switch (code)
   {
      case KEY_RESTART:
      case KEY_RESTART + 32:
         !!this.level && this.level.delegate.restart();
   }
}

EVR.Delegate.prototype.handle_resize_event = function()
{
   if (this.resize_response !== false)
   {
      window.clearInterval(this.resize_response);
   }
   var current = this;
   this.resize_response = window.setTimeout(
      function() { current.respond_to_resize() }, 200);
}

EVR.Delegate.prototype.respond_to_resize = function()
{
   this.application.repopulate();
}

EVR.Delegate.prototype.fix_event = function(event)
{
   if (typeof(event) == "undefined")
   {
      event = window.event;
   }
   return event;
}

EVR.Delegate.prototype.toString = function()
{
   return "[object EVR.Delegate]";
}
34.236.192.4
34.236.192.4
34.236.192.4
 
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.