Announcements

November 24, 2007
Reading for November 27th, are now posted. Enjoy!

October 2, 2007
To upload your thoughtless acts, create a new assignment page like any other lab. You'll see "Thoughtless Acts" listed as one of the assignment options.

May 24, 2008
This site has been archived and is no longer editable. Stay tuned for the next version, coming in the fall!


Revision of Twista from Thu, 11/08/2007 - 17:19

Project Members: 
Alana
daniela
Isaac Salier-He...
Ken-ichi Ueda

Description

Twista is a version of the game Twister except played with the fingers and using musical notes to signal where players should place their fingers. Ideally, the computer will play a note, and the first player must press a colored key that corresponds to that note (3 colors, 3 notes). Once they've successfully done so, they hold their finger on that key, and the computer plays another note for the second player. The process continues until all keys are pressed or a player lifts a finger and loses.

Components

  • Numeric keypad

Processing Code

import ddf.minim.*;

boolean DEBUG = true;

AudioSample c3;           // Audio for the note C

AudioSample e3;           // Audio for the note E

AudioSample g3;           // Audio for the note G

AudioSample cheer;        // Audio for cheering

AudioSample woops;        // Audio for shaming

AudioSample studioCheer;  // Audio for ending well

AudioSample doh;          // Audio for ending badly

AudioSample sample;       // temp holder for samples

float eRadius;

boolean waiting = false;  // whether the system is waiting for player response

char tone;                // current tone

int rand;                 // random number holder

int keyInt;               // integer version of key pressed

boolean correct = false;  // whether the most recent key pressed is correct

// stores whether a number has already been chosen or not

boolean[] chosenNumbers = {false, false, false, false, 

  false, false, false, false, false, false};

// index key numbers to notes

char[] keyTones = {'x','c','c','c','e','e','e','g','g','g'};

// GUI vars

int winH = 512;

int winW = 512;

int butHeight = winH / 5;

int butWidth = winW / 2;

int butX = (winW/2) - (butWidth/2);

int butY = (winH/2) - (butHeight/2) + 70;

int boxSize = 80;

PFont trebuchet;

boolean startWait = true;

// solves for the key being held sending multiple keyPressed events (or, it should)

boolean onePressed = false;

boolean twoPressed = false;

boolean threePressed = false;

boolean fourPressed = false;

boolean fivePressed = false;

boolean sixPressed = false;

boolean sevenPressed = false;

boolean eightPressed = false;

boolean ninePressed = false;

void setup()

{

  size(winW, winH);

  // always start Minim before you do anything with it

  Minim.start(this);

  Minim.debugOn();

  // load BD.wav from the data folder, with a 512 sample buffer

  c3 = Minim.loadSample("50A-1GA1-C3.aif", 512);

  g3 = Minim.loadSample("50A-1GA5-G3.aif", 512);

  e3 = Minim.loadSample("50A-1GA1-E3.aif", 512);

  cheer = Minim.loadSample("kids_cheering-short.mp3", 512);

  studioCheer = Minim.loadSample("cheering_crown_studio-short.mp3", 512);

  woops = Minim.loadSample("woops.wav", 512);

  doh = Minim.loadSample("doh.wav", 512);

 

  // load SD.wav from the data folder

 

  // Load font for title screen and start button.

  trebuchet = loadFont("Trebuchet.vlw");

 

}

 

void draw()

{

  // GUI

 

  // Draw title screen and start button.

 

  if(startWait) {

    background(0,0,0);

    fill(255);

    textFont(trebuchet);

    text("Twista", 180, 140);

 

    textFont(trebuchet, 16);

    text("Alana Pechon, Daniela Rosner," , 144, 200);

    text("Isaac Salier-Hellendag, Ken-ichi Ueda", 120, 218);

    stroke(255);

    fill(159,39,39);

    rect(butX, butY, butWidth, butHeight);

 

    textFont(trebuchet, 32);

    fill(255);

    text("Click to start!", 156, 339);

 

    if(mouseX < (butX + butWidth) && mouseX > butX && mouseY < (butY + butHeight) && mouseY > butY) {

        cursor(HAND);

     } else {

        cursor(ARROW);

     }

  }

 

  // Draw the boxes and waveforms.

 

  if(!startWait) {

    cursor(ARROW);

    background(0);

 

    // Draw rects to represent the board.

 

    stroke(80);

 

    // Yellow boxes

 

    for(int j = 7 ; j < 10 ; j++) {

      if(!chosenNumbers[j])

        // fill(203, 100, 138);

        fill(0, 255, 0);

      else

/*        fill(66, 42, 51);*/

          fill(0, 105, 0);

      rect((winW * (j - 6) / 4) - (boxSize / 2), (winH * 1 / 4) - (boxSize / 2), boxSize, boxSize);

    }

 

    // Red boxes

 

    for(int j = 4 ; j < 7 ; j++) {

      if(!chosenNumbers[j])

/*        fill(76, 89, 212);*/

        fill(255, 0, 0);

      else

        // fill(29, 32, 59);

        fill(105, 0, 0);

      rect((winW * (j - 3) / 4) - (boxSize / 2), (winH * 2 / 4) - (boxSize / 2), boxSize, boxSize);

    }

 

    // Green boxes

 

    for(int j = 1 ; j < 4 ; j++) {

      if(!chosenNumbers[j])

        // fill(66, 217, 102);

        fill(255, 255, 0);

      else

        // fill(21, 43, 26);

        fill(105, 105, 0);

      rect((winW * j / 4) - (boxSize / 2), (winH * 3 / 4) - (boxSize / 2), boxSize, boxSize);

    } 

 

    stroke(180);

 

    // use the mix buffer to draw the waveforms.

    // because these are MONO files, we could have used the left or right buffers and got the same data

    float[] csamp = c3.mix.toArray();

    float[] esamp = e3.mix.toArray();

    float[] gsamp = g3.mix.toArray();

 

    for (int i = 0; i < c3.bufferSize() - 1; i++)

    {

      line(i, (winH * 1 / 4) - gsamp[i]*50, i+1, (winH * 1 / 4) - gsamp[i+1]*50);          // draw waveforms

      line(i, (winH * 2 / 4) - esamp[i]*50, i+1, (winH * 2 / 4) - esamp[i+1]*50);

      line(i, (winH * 3 / 4) - csamp[i]*50, i+1, (winH * 3 / 4) - csamp[i+1]*50);

    }

 

    playGame();

  }

}

 

void mouseClicked() {

  // If the user clicks the start button, start the game!

  if(mouseX < (butX + butWidth) && mouseX > butX && mouseY < (butY + butHeight) && mouseY > butY) {

    background(0);

    startWait = false;

  }

}

void playGame() {

/*

  PSEUDOCODE

 

 

  if waitState -- note, this went in the keyHandler method below

    if key corresponds to tone

      celebrate

      set playState

  if playState

    if all numbers chosen

      end game

    else

      choose a random number between 1 and 9

      if number not already chosen

        play tone corresponding to that number (1-3, 4-6, 7-9)

        set wait state

*/

  if (!waiting) {

    if (DEBUG) println("Playing...");

    if (chosenNumbers[1] &&                 // if all #s are chosen, end the game

        chosenNumbers[2] &&

        chosenNumbers[3] &&

        chosenNumbers[4] &&

        chosenNumbers[5] &&

        chosenNumbers[6] &&

        chosenNumbers[7] &&

        chosenNumbers[8] &&

        chosenNumbers[9]) {

      if (DEBUG) println("All numbers chosen, ending the game");

      studioCheer.trigger();

      stop();

    }

    else {

      // choose a random number

      rand = (int) random(1,9);

      if (DEBUG) print("Random Index: "); println(rand);

 

      // if rand hasn't already been chosen...

      if (chosenNumbers[rand] == false) {

        if (DEBUG) { print("keyTones[rand]: "); println(keyTones[rand]);}

        sample = getSample(keyTones[rand]);  // get the audio matching that number

        delay(3000);              // delay while the audio for the players key press plays

        sample.trigger();         // play the new tone

        tone = keyTones[rand];

        waiting = true;           // wait for input

      }

    }

  }

}

// just maps a note like 'g' to its corresponding AudioSample

AudioSample getSample(char note) {

  if (note == 'c') {

    return c3;

  }

  else if (note == 'e') {

    return e3;

  }

  else {

    return g3;

  }

}

// print the state of the board to the console

void printKeys() {

  for (int i = 1; i <= 9; i++) {

    if (chosenNumbers[i]) print(i + " ");

    else print(". ");

    if (i % 3 == 0) println();

  }

}

 

void keyPressed()

{

  // play selected tone on initial key press event 

  if ( key == '1' && !onePressed) {

    c3.trigger();

    onePressed = true;

    keyHandler();

  }

  else if ( key == '2' && !twoPressed) {

    c3.trigger();

    twoPressed = true; 

    keyHandler(); 

  } 

  else if ( key == '3' && !threePressed) {

    c3.trigger();

    threePressed = true; 

    keyHandler(); 

  }

  else if ( key == '4' && !fourPressed) {

    e3.trigger();

    fourPressed = true; 

    keyHandler(); 

  }

  else if ( key == '5' && !fivePressed) {

    e3.trigger();

    fivePressed = true; 

    keyHandler(); 

  }

  else if ( key == '6' && !sixPressed) {

    e3.trigger();

    sixPressed = true; 

    keyHandler(); 

  }

  else if ( key == '7' && !sevenPressed) {

    g3.trigger();

    sevenPressed = true; 

    keyHandler(); 

  }

  else if ( key == '8' && !eightPressed) {

    g3.trigger();

    eightPressed = true; 

    keyHandler(); 

  }

  else if ( key == '9' && !ninePressed) {

    g3.trigger();

    ninePressed = true; 

    keyHandler(); 

  }

}

 

// Decide whether the right key was pressed or not

void keyHandler() {

  keyInt = (int) key - (int) '0'; // stupid java...

  if (DEBUG) {

    print("keyInt: ");

    println(keyInt);

  }

  // if the user hit a key matching the selected tone...

  if (keyTones[keyInt] == tone) {

    cheer.trigger();                // celebrate

    waiting = false;                // return to the playing state

    chosenNumbers[keyInt] = true;   // cross this number off the list

    correct = true;                 // variable for allowing them to lift finger or not

    printKeys();

  }

  // if the user hit a key that does not match the selected tone...

  else {

    woops.trigger();                // shame

    waiting = false;                // return to the playing state

    correct = false;                // variable for allowing them to lift finger or not

    printKeys();                    // play another tone

  } 

}

void keyReleased()

{

  // end the game if a player releases a key they should be holding down

  if ( correct ) {

    doh.trigger();

    stop();

    }

}

void stop()

{

  // always close Minim audio classes when you are done with them

  delay(7000);

  c3.close();

  e3.close();

  g3.close();

  cheer.close();

  studioCheer.close();

  woops.close();

  doh.close();

  super.stop();

}

 

 

Pictures

Twista ScreenTwista Screen


Powered by Drupal - Design by Artinet