Final Project- Royale Nicholson (Professor Dan Mikesell)

So basically my original idea was to have a box with 9 LED buttons on it. Buttons would light up randomly, one at a time, and you had to press the button when it was lit. You would need to correctly press the buttons a certain number of times within a specific time frame in order to move onto the next round. Each round would be represented by another chapter of a story that was being told through Processing. The story would scroll up from the bottom of the screen, and sound would be cued.

Since I’m more familiar with Processing, I decided to start with that first. Just to get the mechanics of it right, I first just practiced the scrolling motion, representing the button press with a key press, and where to place the instructions on the screen. I drew a bar at the top to indicate how many times the button(key) had been pressed by growing larger and larger horizontally. Each time the bar reached the right edge of the screen, it would become small again and change to a different color. I fine tuned the visuals, adding a score count, and a rectangle (later the story) that would scroll up from the bottom of the window at a certain score. 

import processing.sound.*;

SoundFile file;

float x=0;

boolean X= false;

PFont f;

int barColorRed=255;

int barColorGreen=255;

int barColorBlue=255;

int b=0;

int count=0;

int[] barColor= {255,255,255};

void setup(){

 size (800,800);

 file=new SoundFile(this, “plz work.mp3”);

 f = createFont(“Arial”, 12, true);

 

}

void draw(){

 background(0);

 textFont(f, 25);                  //Text for instructions: Story Time! Press the buttons on the cube that light up as fast as you can! The more buttons pressed, the more of the story you can read. Press START to begin.

 fill(255);

 text (“INSTRUCTIONS”, 500,100);

 text (“Story Time!”, 525,150);

 text (“Press the buttons on the cube”, 425,200);

 text (“that light up as fast as you”, 425,250);

 text (“can! The more buttons pressed,”, 425,300);

 text (“the more of the story that”, 425,350);

 text (“will play.”, 425,400);

 text (“Press START to begin.”, 425,500);

 text (“SCORE: “+ count, 475,700);

rect(495,550,180,60);    

   textFont(f, 50);

 fill(255,0,0);

 text (“START!”, 500,600);

 fill(barColor[0],barColor[1],barColor[2]);                         //White Rectangle      

 rect(0,0,x, 50);

 if (x>800){

   x=0;

   b=b+1;

   b=b%4;

 }

 if (b==0){                             

   barColor[0]=255;

   barColor[1]=255;

   barColor[2]=255;

 }

 if (b==1){                             //The bar above will change colors once you press the button enough times to get to the edge of the screen

   barColor[0]=255;

   barColor[1]=0;

   barColor[2]=0;

 }

 if (b==2){

   barColor[0]=0;

   barColor[1]=255;

   barColor[2]=0;

 }

 if (b==3){

   barColor[0]=0;

   barColor[1]=0;

   barColor[2]=255;

 }

 if (count>5 && count<10){

   fill(0,0,255);

   rect(100,500,200,200);

 }

}

void keyPressed(){

  if(keyPressed==true){

    x=x+100;                                           //how far the bar moves when a button is pushed

    println(count);                                    //how many times to make squares flash

   count++;

  }

}

void mousePressed() {                                 //start sequence when you click START

 if (mouseX>490 && mouseX<650 && mouseY>550 && mouseY<625) {

   println(“PRESSED”);

   count=0;

   x=0;

 }

}

It was around this point that I finalized what I wanted the story theme to be. It would tell the story of the player learning how to finger dance, and having to defeat more difficult competitors, until eventually the player’s legendary finger dancing skills would save the world. Instead of having the story scroll up from the bottom of the screen, instead it would be told through videos of the player’s “competitors” performing. These performances (and accompanying story dialogue) would be prompted by achieving certain scores before the timer runs out for each round.

While my original intention was to have the score count start over at the end of every round, I had to scratch that idea because of the problems I was encountering. Each video was attached to a certain x-value, and each time I restarted it, it would just replay the videos attached to the lower x-values. So I decided to instead make the rounds have a cumulative score. That meant that my start button just referred to the beginning of the game, not the beginning of each round like I had hoped.

I wanted to add in another video of finger dancing that would play as soon as the program started running, so I put in a tutorial video of finger dancing. I put in a secret mousepressed in the upper left hand corner, and if I clicked it the tutorial video would begin. 

I wanted more focus to be on the video, and not so much the words and storyline, so I changed around the layout of the screen so that the videos would take up the majority of the bottom half of the window.

One problem I was having was that once the videos finished playing, they would just stay on the screen. I didn’t think that provided enough contrast between the rounds, so I just drew black rectangles over the video and the accompanying text so that it “disappeared.” 

Another problem I had was that the videos were extremely laggy. The sound would finish around 10 seconds before the video. It turns out that the problem was that the video files were simply too large. Once I changed them to a smaller size, they ran within Processing as desired. With all four rounds of my game finished, it was time to start the Arduino side of things. 

I started by just trying to get Processing to recognize that one button is being pushed (I had scrapped the idea of using the LED in the LED button pusher which I had bought from Taobao, and chose to instead use an outside led alongside the LED push buttons). I borrowed code from here: (https://www.arduino.cc/en/Tutorial/StateChangeDetection) and I got inspiration from the previous lab we had done of serial communication. I also decided to change from using 9 buttons to 6 (because 9 was just too many for my Arduino to handle).

With lots of help from everyone in the IMA lab, I could manage to get the button presses to pop up in the serial window on arduino, and I could get the LED’s to light up, but I just really couldn’t figure out how to put the two together, even just for one LED and push button together. As my frustration continued to build up, I decided to focus on another task, laser cutting a box for my Arduino to go in. I did not include a top to the box because it was too complicated to measure exactly where my buttons and LED’s would be, especially since I didn’t even have functioning code yet, and I thought that being able to see all of the wires made it look prettier. After box assembly, I trimmed down my wires for a prettier presentation.

 

 

13241589_1206636892680726_762489416_o

13234662_1206642839346798_280938550_o

 

 

After all the procrastination, I spent the last several hours trying to get the LEDs and push buttons to work together, until it finally clicked.

This is the final product:

Video_1

This is the Processing code:

import processing.serial.*;
Serial myPort;
import processing.video.*;
Movie movie1;
Movie movie2;
Movie movie3;
Movie movie4;

float x=0;
PFont f;
int barColorRed=255;
int barColorGreen=255;
int barColorBlue=255;
int b=0;
int count=0;
int[] barColor= {255,255,255};
void setup(){
size (800,800);
myPort=new Serial(this, Serial.list()[0], 9600);
movie1= new Movie(this, “tutorial.mp4”);
movie2 = new Movie(this, “girly fingers.mp4”);
movie3= new Movie(this, “world.mp4”);
movie4= new Movie(this, “aliens.mp4”);
f = createFont(“Arial”, 12, true);

}

void movieEvent(Movie m) {
m.read();
}

void draw(){
background(0);
image(movie1, 10, 300, width-20, height/2); //tutorial video at beginning.
textFont(f, 35); //Text for instructions: Story Time! Press the buttons on the cube that light up as fast as you can! The more buttons pressed, the more of the story you can read. Press START to begin.
fill(255);
text (“Fire Fingers!”, 300,90);
textFont(f,25);
text (“One day while on YouTube, you found a tutorial for”, 70,125);
text (“finger dancing. You decide to try it out.”, 50,150);
text (“CONTROLS: Press the buttons on the cube when they light up”, 50,200);
text (“as fast as you can. Reach the target score within 30 seconds”, 50,225);
text (“to proceed to the next round.”, 50,250);
text (“Press START to begin/restart.”, 50,275);
text (“SCORE: “+ count, 600,750);
rect(495,235,180,60); //Setting the Start button.
textFont(f, 50);
fill(255,0,0);
text (“START!”, 500,285);
fill(barColor[0],barColor[1],barColor[2]); //The color of the bar.
rect(0,0,x, 50);
if (x>width){ //Change the color of the bar if it gets longer than the screen
x=0;
b=b+1;
b=b%4;
}
if (b==0){
barColor[0]=255;
barColor[1]=255;
barColor[2]=255;
}
if (b==1){ //The bar above will change colors once you press the button enough times to get to the edge of the screen
barColor[0]=255;
barColor[1]=0;
barColor[2]=0;
}
if (b==2){
barColor[0]=0;
barColor[1]=255;
barColor[2]=0;
}
if (b==3){
barColor[0]=0;
barColor[1]=0;
barColor[2]=255;
}
if (count>0){
fill(0);
rect(10, 300, width-20, height/2);
}
if (count==5){ //Round 1 Finger girl
image(movie2, 10, 300, width-20, height/2);
movie2.play();
fill(0); //erase previous text with black rectangles
rect(0,105,width,130);
rect(0,105,400,150);
fill(255);
textFont(f,25);
text (“You go to a local finger dancing party to test out your new skills.”, 70,125); //text for round 2
text (“While dancing, you accidentally bump into a girl. She “, 50,150);
text (“challenges you to a finger dancing duel. Press ROUND 2 to accept”, 50,175);
text (“her challenge.”, 50,200);
fill(0,255,0); //round 2 prompt
rect(40,710,140,40);
fill(255);
textFont(f,25);
text(“ROUND 2!”, 50,740);
}
if (count==15){ //Round 2 World Championships
image(movie3, 10, 300, width-20, height/2);
movie3.play();
fill(0); //erase previous text with black rectangles
rect(0,105,width,130);
rect(0,105,400,150);
fill(255);
textFont(f,25);
text (“Although at first you were nervous, you win the duel. Later, you”, 70,125); //text for round 3
text (“find out that someone had recorded you, and the video went viral “, 50,150);
text (“on Youtube. You get invited to compete at the world championships”, 50,175);
text (“for finger dancing. Press ROUND 3 to enter the big leagues.”, 50,200);
fill(0, 0,255); //round 3 prompt
rect(190,710,140,40);
fill(255);
textFont(f,25);
text(“ROUND 3!”, 200,740);
}
if(count==30){ //final round video and instructions (alien destruction muahaha)
image(movie4, 10, 300, width-20, height/2);
movie4.play();
fill(0); //erase previous text with black rectangles
rect(0,105,width,130);
rect(0,105,400,150);
fill(255);
textFont(f,25);
text (“The crowd goes wild as you accept the 1st place trophy. But your”, 70,125); //text for story of final round.
text (“celebrations are cut short, because ALIENS HAVE INVADED!”, 50,150);
text (“While everyone runs away, you go up and face them. ‘Finger battle”, 50,175);
text (“me to the death,’ you shout.”, 50,200);
text (“Press FINAL ROUND to save humanity. “, 50,225);
fill(255,0,0); //final round prompt
rect(340,710,200,40);
fill(255);
textFont(f,25);
text(“FINAL ROUND!”, 350,740);
}
}

void serialEvent(Serial port) { ///get data from arduino: if buttons are pressed, increase the count/score
String data = port.readString();
if (data != null) {
if (data.equals(“A”)) {
x=x+100;
println(count);
count++;
}
if (data.equals(“B”)) {
x=x+100;
println(count);
count++;
}
if (data.equals(“C”)) {
x=x+100;
println(count);
count++;
}
if (data.equals(“D”)) {
x=x+100;
println(count);
count++;
}
if (data.equals(“E”)) {
x=x+100;
println(count);
count++;
}
if (data.equals(“F”)) {
x=x+100;
println(count);
count++;
}
}
}

void mousePressed() {
if (mouseX>490 && mouseX<650 && mouseY>235 && mouseY<315) { //start sequence when you click START (also stop tutorial video)
println(“PRESSED”);
count=0;
x=0;
movie1.noLoop();
movie1.stop();
}
if (mouseX>40 && mouseX<180 && mouseY>710 && mouseY<750){ //start sequence for round 2 (competition)
count=6;
movie2.stop();
}
if (mouseX>190 && mouseX<330 && mouseY>710 && mouseY<750){ //start sequence for round 3 (competition)
count=16;
movie3.stop();
}
if (mouseX>0 && mouseX<50 && mouseY>0 && mouseY<50) { //press secret square in the upper left to start tutorial video.
if (count==0){
image(movie1, 10, 300, width-20, height/2);
movie1.loop();
}
}
}

 

This is the final Arduino code:

boolean X=false;
int count=0;
int chosen=1;

const int buttonPin1 = 2; // the pin that the pushbutton is attached to
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int buttonPin4 = 5;
const int buttonPin5 = 6;
const int buttonPin6 = 7;
const int ledPin1 = 8;
const int ledPin2 = 9;
const int ledPin3 = 10;
const int ledPin4 = 11;
const int ledPin5 = 12;
const int ledPin6 = 13;

// Variables will change:
int buttonState1 = 0; // current state of the button
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int buttonState6 = 0;
int ledState1 = 0;
int ledState2 = 0;
int ledState3 = 0;
int ledState4 = 0;
int ledState5 = 0;
int ledState6 = 0;

void setup() {

pinMode(buttonPin1, INPUT); // initialize the button pin as a input:
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
pinMode(buttonPin5, INPUT);
pinMode(buttonPin6, INPUT);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
Serial.begin(9600); // initialize serial communication:
}
void loop() {

buttonState1 = digitalRead(buttonPin1); // read the pushbutton input pin:
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
buttonState5 = digitalRead(buttonPin5);
buttonState6 = digitalRead(buttonPin6);
ledState1 = digitalRead(ledPin1);
ledState2 = digitalRead(ledPin2);
ledState3 = digitalRead(ledPin3);
ledState4 = digitalRead(ledPin4);
ledState5 = digitalRead(ledPin5);
ledState6 = digitalRead(ledPin6);

Serial.println(chosen);
if (chosen == 1) {
digitalWrite(ledPin1, HIGH); // sets the LED on
if (buttonState1 == HIGH && ledState1 == HIGH) {
Serial.println(“A”);
digitalWrite(ledPin1, LOW);
delay(300);
count++;
chosen=random(1,6);
}
} else if (chosen ==2) {
digitalWrite(ledPin2, HIGH); // sets the LED on
if (buttonState2 == HIGH && ledState2 == HIGH) {
Serial.println(“B”);
digitalWrite(ledPin2, LOW);
delay(300);
chosen=random(1,6);
}
} else if (chosen ==3) {
digitalWrite(ledPin3, HIGH); // sets the LED on
if (buttonState3 == HIGH && ledState3 == HIGH) {
Serial.println(“C”);
digitalWrite(ledPin3, LOW);
delay(300);
chosen=random(1,6);
}
} else if (chosen ==4) {
digitalWrite(ledPin4, HIGH); // sets the LED on
if (buttonState4 == HIGH && ledState4 == HIGH) {
Serial.println(“D”);
digitalWrite(ledPin4, LOW);
delay(300);
chosen=random(1,6);
}
} else if (chosen ==5) {
digitalWrite(ledPin5, HIGH); // sets the LED on
if (buttonState5 == HIGH && ledState5 == HIGH) {
Serial.println(“E”);
digitalWrite(ledPin5, LOW);
delay(300);
chosen=random(1,6);
}
} else {
digitalWrite(ledPin6, HIGH); // sets the LED on
if (buttonState6 == HIGH && ledState6 == HIGH) {
Serial.println(“F”);
digitalWrite(ledPin6, LOW);
delay(300);
chosen=random(1,6);
}
}

if ((buttonState1 == HIGH && ledState1 == HIGH)||(buttonState2 == HIGH && ledState2 == HIGH)||(buttonState3 == HIGH && ledState3 == HIGH)||(buttonState4 == HIGH && ledState4 == HIGH)||(buttonState5 == HIGH && ledState5 == HIGH)||(buttonState6 == HIGH && ledState6 == HIGH)){
Serial.println(“good”);
ledState1= LOW;
ledState2= LOW;
ledState3= LOW;
ledState4= LOW;
ledState5= LOW;
ledState6= LOW;
count++;
}

Serial.println(“chosen++”);
delay(200);
}

Leave a Reply