Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

12d: interactive permutation – final

6. Januar 2011

Auf der Basis von 12c, hab ich noch ein paar Ändeurngen und Ergänzungen in mein Skript eingebaut: So lässt sich jetzt auch durch Musik und Geräusche Wellen oder Boost's erzeugen. Dabei werden diese entweder durch Mikrofon oder durch ein Musikstück erzeugt. Es gibt einen 'Colormode', bei welchem die Wellen farbige werden: Ein Rotationsmodus lässt die Zeichen um den Mauszeiger "Rotieren" (Es handelt sich hierbei nicht um eine richtige Rotation, sondern eher um einen Rotationseffekt): Es gibt einen Boost-modus, sowie lassen sich Boost's einzeln auf Kopfdruck erzeugen (Boost's sind Anhebungen aller Zeichen gleichzeitig um die gleiche Höhe, vergleichbar mit einer Lautsprechermembran). Ein Hilfe und Informationsfenster wurde eingebaut um die Benutzung zu vereinfachen: Beim Anfangscreen gibt es nun eine automatische Anitmation die durch einen Bouncingball iniziert wird: Und ein Fullscreenmodus wurde eingebaut. Weitere Screens: Downloadlink: _01_permutation_06 (4.5MB) Code:
// Copyright 2010 Fabian Troxler @ zhdk

//fulscreen library
import fullscreen.*;

// minim-audio library
import ddf.minim.*;
import ddf.minim.effects.*;
import ddf.minim.analysis.*;


//audio zeugs
Minim minim;
AudioInput input;
AudioPlayer song;
FFT fft;
BeatDetect beat;
BandPass bpf;
LowPassFS lpfilter;
HighPassSP hpf;

float eRadius;



Ball ball;

FullScreen fs;
ArrayList waves;
ArrayList boosts;
int     anzahl = 14;
int     rand = 50;
int     s = 0;
int     iinfo = 0;
int     ihelp = 0;
int     iboost = 0;
float istart = 0;
float     radi = 0;
float     r = 0;
float   i = 50;
float   xStep;
float   yStep;
float   rot,rotx,roty;
float   distance;
float   adddistance;
float   addwavedistance;
float   realdistance;
float   maxdistance;
float   maxdistanceratio;
float   sizeratio;
float   signr = 1;
float radiadd = 0.1;
float ballx, bally;

Wave    wave;

String  mode = "standard";
String colormode = "off";

boolean mousepressed = false;
boolean pressed = false;
boolean shadowswitch = false;
boolean m,c,infow = false;
boolean played = false;
boolean rotation= false;
boolean radtrig = true;
boolean helpw = false;
boolean boost = false;
boolean nowave = false;

char    keypressed = '0';
int     mousex,mousey;

void setup()
{
  cursor(CROSS);

  size(800, 800);
  smooth();
  minim = new Minim(this);
  song = minim.loadFile("beastie_02.mp3");

  input = minim.getLineIn();


 //beat detection
  beat = new BeatDetect();

  beat.setSensitivity(100);


  // beat.detect(song.mix);

  // bl = new BeatListener(beat, song);
  //song.play();
  // maxdistanceratio = Faktor für den Einflussbreich der Maus (Grösse)

  maxdistanceratio = 0.4;

  // abstand zwischen der Zeichen berechnen
  xStep = (width - 2 * rand) / (float)(anzahl-1);
  yStep = (height - 2 * rand) / (float)(anzahl-1);

  // maximale distanz welche die Maus zum ässersten Zeichen haben kann
  maxdistance = sqrt(sq(width)+sq(height));
  // Skalierung dieser Distanz mit einer Variabel
  maxdistance = maxdistance * maxdistanceratio;

  // Grössenvariabel in abhängikeit zur Anzahl Zeichen und Bildschirmgrösse
  sizeratio = 7.0/anzahl * (width/600);
  // addistance auf 0 setzen
  adddistance = 0;
  // Array-Liste für die Wellen (braucht es für mehrere Wellen gleichzeitig darzustellen)
  waves = new ArrayList();
  //noLoop();


  boosts = new ArrayList();
  // Fullscreen zeugs
  fs = new FullScreen(this,0);
  //fs.setResolution(800,800);
  fs.setShortcutsEnabled(true);
  //fs.enter();

  ball = new Ball(50,1);
  ballx = ball.coordx();
  bally = ball.coordy();
}

void draw()
{

  background(255);
  // bewegender ball
  ball.move();
  // balldartsellung -- deaktiviert
  // ball.display();
  ballx = ball.coordx();
  bally = ball.coordy();

  pushMatrix();
  translate(rand,rand);
  for(int y=0; y<anzahl;y++)
  {
    pushMatrix();
    for(int x=0; x<anzahl;x++)
    {

      maxdistance = sqrt(sq(width)+sq(height));
      maxdistance = maxdistance * maxdistanceratio;
      //rotationswinkel im Bezug zur Mausposition berechnen
      rot = atan2((mouseX-rand - x*xStep),(mouseY-rand - y*yStep));

      // Entfernung zwischen dem Zeichen (x,y) und dem Mauszeiger
      distance = dist(mouseX-rand,mouseY-rand,x*xStep,y*yStep);
      //distance = dist(ballx,bally,x*xStep,y*yStep); 
      //realdistance und adddistance zurücksetzte -> muss für jedes Zeichen einzel berechnet werden
      realdistance=0;
      adddistance = 0;
      addwavedistance = 0;

      // for Schleife für die Waves (Array durchlauf)
      for (int iwaves = 0; iwaves < waves.size(); iwaves++)
      {
        Wave wave=(Wave)waves.get(iwaves);

        // i Wert der wave(iwaves) erhöhen (siehe in der class) und diesen abfragen - i ist die entfernung die die Wave zurückgelegt hat - class Wave
        i = wave.i();
        
        // wellen loeschen die nicht mehr gebraucht werden
        if (wave.i >= 2*maxdistance + 200 )
        {
          waves.remove(iwaves);
        }
        else
        {

          // Entfernung vom Zeichen zum gespeicherten Punkt (mouseclick) ausrechnen - class Wave

            realdistance = wave.reald(x*xStep,y*yStep);

          // berechnung der addist (adddist = distanz die zur Distanz gerechnet wird, wo die Wave sich gerade befindet)
          wave.draw(realdistance, sizeratio, i);
          // addieren der adddistances (bei mehreren Waves
          adddistance += wave.adddist();
          addwavedistance += wave.adddist();
        }
      }
      // boost aktion
      for (int iboost = 0; iboost < boosts.size(); iboost++)
      {
        Boost boost=(Boost)boosts.get(iboost);


        // loeschen der uerbeflueessigen boost"wellen"
        boost.draw();
        if (boost.boosth() <=0)
        {
          boosts.remove(iboost);
        }
        else
        {

          adddistance -= boost.boosth();
        }
      }

      //wenn die distance zwischen Mauszeiger und Zeichen grösser als die "maximale" Distanz ist (maxdistance)
      // soll die distance auf maxdistance gesetzt werden.
      if (distance >= maxdistance )
      {
        distance = maxdistance;
      }
      // Zeichen zeichnen
      drawPermutationObj(rot,ballx,bally,xStep,yStep,x,y);

      // Koordinatensystem für nächstes zeichen verschieben (X-Richtung)
      translate(xStep,0.0f);
    }
    //println();
    popMatrix();

    // Koordinatensystem für nächstes zeichen verschieben (Y-Richtung)
    translate(0.0f,yStep);
  }
  popMatrix();
  // infofenster

  pushStyle();
  pushMatrix();
  if (infow)
    info();
  popMatrix();
  pushStyle();

  pushStyle();
  pushMatrix();
  if (helpw)
    help();
  popMatrix();
  pushStyle();
}

void drawPermutationObj(float rot, float ballx, float bally, float xStep, float yStep, int x, int y)
{
  // wenn Maustaste gedrückt soll eine neue Welle gezeichnet werden
  if (pressed)
  {
    // hinzufügen der Wave
    waves.add(new Wave(mousex, mousey, rand, -400, 80));

    // damit diese if-Schleife nur einmal durchlaufen wird
    pressed = false;
  }

  pushStyle();
  pushMatrix();
  // Skalierung der Zeichen (bei vergrösserung)
  scale(sizeratio * signr);

  // wenn Taste 'm' gedrückt
  if (m)
  {
    // damit der mauszeiger keinen Einfluss mehr auf die grösse und rotation hat werden die Variabeln mit einer Konstante überschrieben
    distance = maxdistance;
    // rot = 1;
    rot = atan2((height*.5-rand - x*xStep),(width*.5-rand - y*yStep));
  }

  if (c)
  {
    r = map(adddistance, -200,0,255,0);
  }
  else
  {
    r = 0;
  }

  //sound
  switch (s)
  {
  case 0:
    break;
  case 1:
    mode = "LineIn";
    beat.detect(input.mix);
    //float a = map(eRadius, 2.0, 8.0, 60, 255);
    //fill(60, 255, 0, a);
    if ( beat.isOnset() && nowave == false) 
    {

      if (boost)
      {
        boosts.add(new Boost(200,1200));
      }
      else
      {
        // eRadius = 2;
        float soundlevel = 10*input.mix.level();
        //println(soundlevel);
        waves.add(new Wave(width/2, height/2, rand, soundlevel*-400, soundlevel*40));
      }
    }
    //ellipse(width/2, height/2, eRadius, eRadius);
    //eRadius *= 0.999;
    //if ( eRadius < 1.1 ) eRadius = 1;
    break;
  case 2:
    mode= "Song";
    beat.detect(song.mix);
    //float a = map(eRadius, 2.0, 8.0, 60, 255);
    //fill(60, 255, 0, a);
    float soundlevel = 10*song.mix.level();
    if ( beat.isOnset() && nowave == false)
    {
      if (boost)
      {
        boosts.add(new Boost(100*soundlevel,1200));
      }
      else
      {
        // eRadius = 2;

        waves.add(new Wave(width/2, height/2, rand, soundlevel*-200, soundlevel*40 ));
      }
    }
    //ellipse(width/2, height/2, eRadius, eRadius);
    //eRadius *= 0.999;
    //if ( eRadius < 1.0 ) eRadius = 1;
    // sound end
    break;
  }
  //Rotation um rot, (+HALF_PI da zeichen um 90Grad gedreht)

  if (keypressed == '7' && rotation == false)
  {
    rotate(0);
  }
  else if (keypressed == '7' && rotation == true)
  {
    if (radi > 600 || radi < 0)
    {
      radiadd = radiadd*1;
    }  
    rotate((radi/600.0+(-rot+HALF_PI)));
    radi += radiadd;
  } 
  else {

    if (keypressed == '8')
    {
      rotate(0);
      //rot = atan2((height*.5-rand - x*xStep),(width*.5-rand - y*yStep));
      //rotate(rot);
    }
    else if (keypressed == '0')
    {
      rotate(0);
    }
    else
      rotate(-rot+HALF_PI);
  }

  if (keypressed == '0')
  {
    rotate(0);
  }


  // addieren der adddistance (wellenerhöhung) zur normalen distanzabhängigen Höhe (distance)
  switch (s)
  {
  case 0:
    mode = "standard";
    distance = (distance + adddistance);
    //println("normal");
    if (played)
    {
      song.pause();
      played = false;
    }
    break;
  case 1:
    distance = (distance + adddistance);
    //println("input");
    break;
  case 2:
    distance = (distance + adddistance);
    //distance = (distance + adddistance) / eRadius;
    // println("sound");
    song.play();
    played = true;
    break;
  }

  if (rotation)
  {
    //rotate(wave.i);
    translate(0*addwavedistance,0.5*addwavedistance);
  }

  // Zeichenauswahl

  switch(keypressed)
  {
  case '1':
    //distance = distance + adddistance;
    stroke(0);
    fill(0);
    // shadow

    // mit map wird das zeichen abhängig von der distanz gezeichnet
    ellipse(map(distance,0,maxdistance,0,14),0,map(distance,0,maxdistance,16,46),map(distance,0,maxdistance,16,46));
    noStroke();
    fill(255);
    //white ring
    ellipse(map(distance,0,maxdistance,0,-14),0,map(distance,0,maxdistance,46,50),map(distance,0,maxdistance,46,50));
    stroke(0);
    fill(r,r,0);
    // center ellipse
    ellipse(map(distance,0,maxdistance,0,-14),0,map(distance,0,maxdistance,16,42),map(distance,0,maxdistance,16,42));
    break;

  case '2':
    // distance = distance + adddistance;
    stroke(0);
    fill(0);
    // shadow
    ellipse(map(distance,0,maxdistance,14,0),0,map(distance,0,maxdistance,46,16),map(distance,0,maxdistance,46,16));
    noStroke();
    fill(255);
    //white ring
    ellipse(map(distance,0,maxdistance,-14,0),0,map(distance,0,maxdistance,50,46),map(distance,0,maxdistance,50,46));
    stroke(0);
    fill(r,r,0);
    //center ellipse
    ellipse(map(distance,0,maxdistance,-14,0),0,map(distance,0,maxdistance,42,16),map(distance,0,maxdistance,42,16));
    break;

  case '3':
    //distance = distance + adddistance;
    stroke(0);
    fill(0);
    // shadow
    ellipse(map(distance,0,maxdistance,0,0),0,map(distance,0,maxdistance,86,16),map(distance,0,maxdistance,86,16));
    noStroke();
    fill(255);
    //white ring
    ellipse(map(distance,0,maxdistance,-28,0),0,map(distance,0,maxdistance,100,46),map(distance,0,maxdistance,100,46));
    noStroke();
    fill(r,r,0);
    //center ellipse
    ellipse(map(distance,0,maxdistance,-28,0),0,map(distance,0,maxdistance,82,12),map(distance,0,maxdistance,82,12));
    break;

  case '4':
    //distance = distance + adddistance;
    stroke(0);
    fill(0);
    // shadow
    ellipse(map(distance,0,maxdistance,0,0),0,map(distance,0,maxdistance,46,16),map(distance,0,maxdistance,46,16));
    noStroke();
    fill(255);
    //white ring
    ellipse(map(distance,0,maxdistance,-28,0),0,map(distance,0,maxdistance,50,46),map(distance,0,maxdistance,50,46));
    noStroke();
    fill(r,r,0);
    //center ellipse
    ellipse(map(distance,0,maxdistance,-28,0),0,map(distance,0,maxdistance,42,16),map(distance,0,maxdistance,42,16));
    break;

  case '5':
    // distance = distance + adddistance;
    stroke(0);
    fill(0);
    // shadow
    ellipse(map(distance,0,maxdistance,0,0),0,map(distance,0,maxdistance,46,16),map(distance,0,maxdistance,46,16));
    noStroke();
    fill(255);
    //white ring
    ellipse(map(distance,0,maxdistance,-50,0),0,map(distance,0,maxdistance,50,46),map(distance,0,maxdistance,50,46));
    stroke(0);
    fill(r,r,0);
    //center ellipse
    ellipse(map(distance,0,maxdistance,-50,0),0,map(distance,0,maxdistance,42,16),map(distance,0,maxdistance,42,16));
    break;

  case '6':
    // distance = distance + adddistance*2;
    noStroke();
    fill(map(distance,0,maxdistance,255,80));
    // shadow
    //ellipse(map(distance,0,maxdistance,0,0),0,map(distance,0,maxdistance,46,16),map(distance,0,maxdistance,46,16));
    noStroke();
    fill(255);
    //white ring
    //ellipse(map(distance,0,maxdistance,-50,0),0,map(distance,0,maxdistance,50,46),map(distance,0,maxdistance,50,46));
    stroke(0);
    fill(r,r,0);
    //center ellipse
    ellipse(map(distance,0,maxdistance,-80,0),0,map(distance,0,maxdistance,100,16),map(distance,0,maxdistance,100,16));
    break;

  case '8':
    // distance = distance + adddistance*2;
    noStroke();
    fill(map(distance,0,maxdistance,200,0));
    // shadow
    pushMatrix();
    rotate(-rot+HALF_PI);
    translate(map(distance,0,maxdistance,0,-30),map(distance,0,maxdistance,0,0));
    rotate(rot-HALF_PI);
    rect(map(distance,0,maxdistance,-8,-45),map(distance,0,maxdistance,-8,-45),map(distance,0,maxdistance,16,90),map(distance,0,maxdistance,16,90));
    popMatrix();
    noStroke();
    fill(255);
    //white ring
    rect(map(distance,0,maxdistance,-8,-45),map(distance,0,maxdistance,-8,-45),map(distance,0,maxdistance,16,90),map(distance,0,maxdistance,16,90));
    stroke(0);
    fill(r,r,0);
    //center ellipse
    rect(map(distance,0,maxdistance,-6,-30),map(distance,0,maxdistance,-6,-30),map(distance,0,maxdistance,12,60),map(distance,0,maxdistance,12,60));
    break;

  case '7':
    // distance = distance + adddistance*2;
    noStroke();
    //fill(map(distance,0,maxdistance,200,0));
    fill(0);
    // shadow
    rect(map(distance,0,maxdistance,-8,-55),map(distance,0,maxdistance,-8,-55),map(distance,0,maxdistance,16,110),map(distance,0,maxdistance,16,110));
    noStroke();
    fill(255);
    //white ring
    // rect(map(distance,0,maxdistance,-8,-50),map(distance,0,maxdistance,-8,-50),map(distance,0,maxdistance,16,100),map(distance,0,maxdistance,16,100));
    stroke(0);
    // fill(r,r,0);
    //center ellipse
    // ellipse(map(distance,0,maxdistance,-80,0),0,map(distance,0,maxdistance,100,16),map(distance,0,maxdistance,100,16));
    break;

  case '0':
    if (istart < 2400)
    {
      //maxdistance = maxdistance*istart/40.0;
      istart+=.1;
    }

    // startbildschirm mit "ball"-effekt

    distance = dist(ballx,bally,x*xStep,y*yStep); 
    if (distance >= maxdistance )
    {
      distance = maxdistance;
    }
    pushMatrix();
    scale((istart/2400));
    pushStyle();
    fill(0);
    ellipse(0,0,map(distance,0,maxdistance,100,16),map(distance,0,maxdistance,100,16));
    popStyle();
    popMatrix();
    break;
  }

  popMatrix();
  popStyle();
}



// Tastenbelegung
void keyPressed()
{
  switch(key)
  {
  case ' ':
    save("permutation.jpg");
    break;
  case '1':
    keypressed = key;
    break;
  case '2':
    keypressed = key;
    break;
  case '3':
    keypressed = key;
    break;
  case '4':
    keypressed = key;
    break;
  case '5':
    keypressed = key;
    break;
  case '6':
    keypressed = key;
    break;
  case '7':
    keypressed = key;
    break;
  case '8':
    keypressed = key;
    break;
  case '0':
    keypressed = '0';
    break;

  case 'c':
    if (c)
    {
      colormode = "false";
      c = false;
    } 
    else {
      colormode = "true";
      c = true;
    }
    break;

  case 'm':
    if (m)
    {
      m = false;
    } 
    else {
      m = true;
    }
    break;

  case 's':
    if (s == 0)
    {
      s = 1;
    }
    else if (s == 1)
    {
      s = 2;
    }
    else
    {
      s = 0;
    }
    break;


  case 'i':
    if (infow)
    {
      infow = false;
      iinfo = 0;
    } 
    else {
      infow = true;
    }
    break;

  case 'h':
    if (helpw)
    {
      helpw = false;
      ihelp = 0;
    } 
    else {
      helpw = true;
    }
    break;

    // zeichengrösse verändern

  case 'e':
    //   signratio = "false";
    signr += .1;
    break;

  case 'd':
    //   signratio = "true";
    signr -= .1;
    break;

    // Random wavetaste
  case 'w':
    //   signratio = "true";
    float wrandom = random(0,width);
    waves.add(new Wave((int)random(0,width), (int)random(0,height), rand, (int)random(-400,400), (int)random(10,200)));
    //waves.add(new Wave(0, 0, rand, -200, 40));
    break;

    // rotate
  case 'r':
    if (rotation)
    {
      rotation = false;
    }
    else
    {
      rotation = true;
    }
    break;

  case 'b':
    if (boost)
    {
      boost = false;
    }
    else
    {
      boost = true;
    }
    break;


  case 'o':
    if (nowave)
    {
      nowave = false;
    }
    else
    {
      nowave = true;
    }
    break;


  case 'n':
    boosts.add(new Boost(random(200,300),random(1000,2000)));
    break;
  }
  // sonderzeichen (Pfeiltasten)

  if (key == CODED)
  {
    if (keyCode == UP)
    {
      // erhöhung der anzahl Zeichen
      anzahl++;
      // Veränderung des xSteps & ySteps, da mehr zeichen -> abstand kleiner
      xStep = (width - 2 * rand) / (float)(anzahl-1);
      yStep = (height - 2 * rand) / (float)(anzahl-1);
      // veränderung der grössenVariabel in abhängigkeit zur Anzahl
      sizeratio = 7.0/anzahl * (width/600);
      // maxdistance (maximale Distanz zum Muaszeiger, wo die Zeichen verändert werden sollen) in Abhängigkeit zur Zeichengrösse
      maxdistance = sqrt(sq(width)+sq(height)) * maxdistanceratio * sizeratio;
    }
    if (keyCode == DOWN)
    {
      anzahl--;
      xStep = (width - 2 * rand) / (float)(anzahl-1);
      yStep = (height - 2 * rand) / (float)(anzahl-1);
      sizeratio = 7.0/anzahl * (width/600);
      maxdistance = sqrt(sq(width)+sq(height)) * maxdistanceratio * sizeratio;
    }

    if (keyCode == LEFT)
    {
      // maxdistancratio ist eine Variabel zum ändern des einflussbereiches der Maus
      maxdistanceratio = maxdistanceratio - .1;
      maxdistance = sqrt(sq(width)+sq(height)) * maxdistanceratio * sizeratio;
    }

    if (keyCode == RIGHT)
    {
      maxdistanceratio = maxdistanceratio + .1;
      maxdistance = sqrt(sq(width)+sq(height)) * maxdistanceratio * sizeratio;
    }
  }
}

void mousePressed ()
{
  //Speichern der x/Y Koordinate beim Mausklick
  mousex = mouseX;
  mousey = mouseY;
  mousepressed = true;
  pressed = true;
} 

// infofenster mit Informationen über die Einstellungen

void info ()
{
  pushMatrix();
  noStroke();
  fill(200,240);
  translate(0,-iinfo);
  translate(0,height);
  rect(0,0,width,40); 
  fill(0,200);
  text("Zeichen Nr.: " + keypressed +  " | Anzahl Zeichen : " + anzahl + "/" + anzahl + " | mode: " + mode + 
    " | mousesize = " + maxdistanceratio + " | colormode: " + colormode + " | Waves:" + waves.size() + " | Boosts:" + boosts.size(),50,25);



  if (iinfo < 40)
  {
    iinfo+=2;
  }
  popMatrix();
} 

// Hilfefenster mit den Sortcuts  

void help ()
{
  pushMatrix();
  noStroke();
  fill(200,map(ihelp,0,40,0,240));
  //translate(0,-ihelp);
  translate(0,rand);
  rect(rand,0,width-2*rand,270); 
  fill(0,map(ihelp,0,40,0,240));
  translate(20,10);


  translate(0,15);
  text("'h'",50,0);
  text(":",200,0);
  text("help",220,0);

  translate(0,15);
  text("'1'-'8'",50,0);
  text(":",200,0);
  text("change signs",220,0);

  translate(0,15);
  text("'m'",50,0);
  text(":",200,0);
  text("no mousover",220,0);

  translate(0,15);
  text("'arrow up/down'",50,0);
  text(":",200,0);
  text("increase/decrease number of signs",220,0);

  translate(0,15);
  text("'arrow left/right'",50,0);
  text(":",200,0);
  text("increase/decrease mousoverradius",220,0);

  translate(0,15);
  text("'s'",50,0);
  text(":",200,0);
  text("change sound-mode",220,0);

  translate(0,15);
  text("'c'",50,0);
  text(":",200,0);
  text("change color-mode",220,0);

  translate(0,15);
  text("'r'",50,0);
  text(":",200,0);
  text("change rotate-mode",220,0);

  translate(0,15);
  text("'e & d'",50,0);
  text(":",200,0);
  text("enrease/decrease size of signs",220,0);

  translate(0,15);
  text("'w'",50,0);
  text(":",200,0);
  text("generate random wave",220,0);
  
  translate(0,15);
  text("'b'",50,0);
  text(":",200,0);
  text("boostmodus",220,0);
  
  translate(0,15);
  text("'n'",50,0);
  text(":",200,0);
  text("create a boost-wave",220,0);
  
  translate(0,15);
  text("'r'",50,0);
  text(":",200,0);
  text("rotationmodus",220,0);

  translate(0,40);
  text("copyright ©2010 by Fabian Troxler @ zhdk",50,0);



  if (ihelp < 40)
  {
    ihelp+=2;
  }
  popMatrix();
} 

ball-class:
// abgeaendertes Skript von Diego Matinez, zu erstellungung eines Bouncing-Balls

class Ball {

  float     r;   // radius
  float     x,y; // location
  float     xspeed,yspeed; // speed
  int      _lifeTime;
  int      _deathTime;
  float     _alpha;


  // Constructor
  Ball(float tempR, int lifeTime) {
    r = tempR;
    x = random(r,(width-r));
    y = random(r,(height-r));
    xspeed = random( 2,5);
    yspeed = random( 2,5);
    _lifeTime = lifeTime;
    _deathTime = (int)random(5000,8000);
    _alpha = 1.0;
  }

  void move() {
    x += xspeed; // Increment x
    y += yspeed; // Increment y

    // Check horizontal edges
    if (x >= width-r || x <= 0+r ) {
      xspeed *= - 1;
    }
    //Check vertical edges
    if (y >= height-r || y < 0+r) {
      yspeed *= - 1;
    }
  }

  void display() {
    stroke(0);
    fill(150,150,150,255*_alpha);
    ellipse(x,y,r*2,r*2);
  }

  float coordx() {
    return x;
  }

  float coordy() {
    return y;
  }
}
boost-class:
// boostklasse - ähnlich zur welle, jedoch werden alle zeichen gleichzeitig erhöht

class Boost {
  float _boostheight;
  float _boosthtemp = 0;
  float _boostvelocity;
  float _velocity = 0;
  float _startvelo = 0;
  float _startboost;




  Boost (float boostheight, float velocity)
  {
    _boostheight = boostheight;
    _startboost = boostheight;
    _velocity = velocity;
    _startvelo = velocity;
  }


  void draw()
  {


    if (_velocity > -100)
    {
      _boostheight -= (_startboost)/(_startvelo);
      //println("startb : " + _startboost + " _startvelo : " + _startvelo + " velo : " + _velocity + " boosth : " + _boostheight);

      _velocity--;
    }

    if (_velocity <= -100)
      _boostheight = 0;

    if (_startvelo-_velocity < 100)
    {
      _boosthtemp += (_startboost/100);
      _boostheight = _boosthtemp;
    }
  }


  float boosth()
  {
    return _boostheight;
  }
}
wave-class:
class Wave {
  float _adddistance = 0;  
  float _sizeratio;
  float i = 0;  
  float _realdistance;
  int _mousex,_mousey,_rand;
  // wellenbreite
  float _wavebreite = 80;
  // wellenhöhe
  float _waveheight = -200;

  // Ausbreitungsgeschwindigkeit
  float _wavespeed = 0.1;


  // Constructor
  Wave (int mousex, int mousey, int rand, float waveheight, float wavebreite)
  {
    // speichern diverser Variabeln welche di Klasse von aussen bekommt
    realdistance = realdistance;
    _mousex = mousex;
    _mousey = mousey;
    _rand = rand;
    _waveheight = waveheight;
    _wavebreite = wavebreite;
  } 


  // Funktion zur abfrage der adddistance

    float adddist()
  {

    return _adddistance;
  }


  // Funktion zur Erhöhung von i um den wellenspeed und die Abfrage von i ( i = wellenausbreitungsgrösse)

  float i()
  {
    i+=_wavespeed * _sizeratio;
    return i;
  }



  // funktion zu Abfrage der realdistance (Distanz zwichen dem Zeichen und dem ursprünglichen Ort wo geklickt wurde)

  float reald(float xstep, float ystep)

  {
    _realdistance = dist(_mousex-_rand,_mousey-_rand,xstep,ystep);
    return _realdistance;
  }


  // Funktion zum Berechnen der Wellenausbreitung ( Input ist die Distanz zwischen Zeichen und ursprüngliem Ort, grössenvariabel und dem ausbreitungswert i)

  void draw(float realdistance, float sizeratio, float i)
  {
    _sizeratio = sizeratio;

    // Ausbreitungsschlaufe ( i ist der imaginäre "Radius" der welle)
    if (i <= 1200)
    {
      //ellipse(mousex,mousey,i,i);
      // Abfrage ob ein Zeichen im Wellenbereich ist ( Radius der Welle +/- wellenbreite(_wavebreite))
      if (realdistance >= i-_wavebreite && realdistance <= i+_wavebreite)
      {

        float j = 0;
        // j = distanz zwichen zeichen und dem Wellenrand i
        j = (i - realdistance);


        // Mapping damit die welle zum Rand hin abflacht
        if (j >=0)
          _adddistance = map(j,-_wavebreite,_wavebreite,_waveheight,0);
        else
          _adddistance = map(j,-_wavebreite,_wavebreite,0,_waveheight);
        // println("adddist : " + _adddistance);
      }
      else {
        // wenn die Welle ihre maximale Ausbreitung hat soll soll die auswirkung auf null gestellt werden = welle ist weg
        _adddistance = 0;
      }
    }
    else
    {
      i = 0;
    }
  }
}