I made a fun game titled “Smooth Moves” that makes use of a custom built game controller that consists of several forms of input that I named with wacky names, including: Softpot (Sliding Thingy), a Potentiometer (Twisty Knob), a photocell sensor (Sun Blocker) and a rangefinder/distance sensor (Futuristic Sensor)! Some say it was too hard, ehh n00bs..
Image of final board:
There are 3 worlds, each with 4 games, 1 for each controller
(The distance sensor was later removed from the game and the game I designed for it is not documented; code will be made available)
Every world replays the same games, the difference is less time and faster speeds within the games
Image of games:
Sliding Thingy (Move Spaceship up and down to avoid asteroid, Sun and Planet drawn in the back for visual effect)
Twisty Knob Game (You are the DJ for a dead party, turn the potentiometer until you see people dancing)
Gifs broken apart into several .PNGs and constantly looped through for dancing effect
Sun Blocker (Cover photocell sensor at specific ranges to make it Morning, Afternoon, Night)
Morning:
Afternoon:
Night:
Splash Screen:
Loading Screen:
How To Play:
Progress Screen (Message to user and instructions for next game)
Level Display
Once 3 lives run out, it’s Game Over!
But if you make it past the 3 worlds, You Win!
The board was cut with acrylic and a laser cutter using this design:
(Outdated Design. Final Design on IM lab computer, hopefully to be updated later)
Images of Board front and back
Miscellaneous Images:
Designing Controller Board
Wiring up the components
Setting it up in project space
End of IM :'(
Images used in-game:
Code:
Arduino
int pinLife1 = 4; int pinLife2 = 5; int pinLife3 = 6; int pinWin1 = 8; int pinWin2 = 9; int pinWin3 = 10; void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(pinLife1, OUTPUT); pinMode(pinLife2, OUTPUT); pinMode(pinLife3, OUTPUT); pinMode(pinWin1, OUTPUT); pinMode(pinWin2, OUTPUT); pinMode(pinWin3, OUTPUT); } void loop() { // put your main code here, to run repeatedly: //int myByte = Serial.read(); int comm = Serial.read(); int win = Serial.read(); Serial.print(analogRead(A0)*4); Serial.print(","); Serial.print(analogRead(A1)); //Serial.print(digitalRead(7)); Serial.print(","); Serial.print(analogRead(A2)); Serial.print(","); Serial.println(analogRead(A3)); //this means comm is number of lives remaining if (comm == 3) { digitalWrite(pinLife1, LOW); digitalWrite(pinLife2, LOW); digitalWrite(pinLife3, LOW); } else if (comm == 2) { digitalWrite(pinLife1, HIGH); digitalWrite(pinLife2, LOW); digitalWrite(pinLife3, LOW); } else if (comm == 1) { digitalWrite(pinLife1, HIGH); digitalWrite(pinLife2, HIGH); digitalWrite(pinLife3, LOW); } else { digitalWrite(pinLife1, HIGH); digitalWrite(pinLife2, HIGH); digitalWrite(pinLife3, HIGH); } if (win == 1) { digitalWrite(pinWin1, LOW); digitalWrite(pinWin2, LOW); digitalWrite(pinWin3, LOW); } else if (win == 2) { digitalWrite(pinWin1, HIGH); digitalWrite(pinWin2, LOW); digitalWrite(pinWin3, LOW); } else if (win == 3) { digitalWrite(pinWin1, HIGH); digitalWrite(pinWin2, HIGH); digitalWrite(pinWin3, LOW); } else { digitalWrite(pinWin1, HIGH); digitalWrite(pinWin2, HIGH); digitalWrite(pinWin3, HIGH); } //String message = Serial.readString(); //Serial.print(","); //Serial.println(message); }
Processing
Main File (FinalProject.pde)
import ddf.minim.*; import ddf.minim.analysis.*; import ddf.minim.effects.*; import ddf.minim.signals.*; import ddf.minim.spi.*; import ddf.minim.ugens.*; import processing.serial.*; import de.looksgood.ani.*; Serial myPort; PFont myFont; boolean first = true; boolean firstPot = true; boolean firstProg = true; boolean wonLastGame = false; int lives = 3; String v; int vI; int r; int s; boolean restart = false; int restartCounter = 0; int restartTimer = 5; int timer = 12; int counter = 0; int potPrev; int potCurr; int photoVal = 0; int slidingVal = 0; int level = 1; int distLevel = 1; int potLevel = 1; int photoLevel = 1; int slidingLevel = 1; int pot; boolean gameOver = false; boolean win = false; Minim minim; AudioPlayer winner; AudioPlayer loser; //SoundFile winner = new SoundFile(this, "correct.mp3"); //SoundFile loser = new SoundFile(this, "wrong.mp3"); SplashScreen splashScreen = null; ProgressScreen progressScreen = null; PotLevelOne potLevelOne = null; PotLevelTwo potLevelTwo = null; DistLevelOne distLevelOne = null; PhotoLevelOne photoLevelOne = null; SlidingLevelOne slidingLevelOne = null; HowToPlay howToPlay = null; LevelDisplay levelDisplay = null; boolean newWorld = true; void setup() { //size(800, 600); fullScreen(); background(255); fill(1); textSize(15); Ani.init(this); minim = new Minim(this); winner = minim.loadFile("correct.mp3"); loser = minim.loadFile("wrong.mp3"); String portName = "COM9"; //portName = "/dev/tty.usbserial-DA01LMDP"; myFont = createFont("Green Eggs and Spam", 32); textFont(myFont); println(Serial.list()); myPort = new Serial(this, portName, 9600); myPort.bufferUntil('\n'); } void draw() { background(255); counter++; /*if (vI < 90) { fill(255); ellipse(width/2, height/2, vI, vI); text(vI, 50, 50); }*/ if (counter > 100) { if (first) { r = floor(random(0, 4)); //s = floor(random(0, 4)); first = false; splashScreen = new SplashScreen(potCurr); progressScreen = new ProgressScreen(level); howToPlay = new HowToPlay(); levelDisplay = new LevelDisplay(); } if (restart) { gameOver = false; r = floor(random(0, 4)); win = false; lives = 3; timer = 12; //counter = 0; level = 1; potLevelOne = null; potLevelTwo = null; distLevelOne = null; photoLevelOne = null; slidingLevelOne = null; firstProg = true; restartCounter = 0; restartTimer = 5; distLevel = 1; potLevel = 1; photoLevel = 1; slidingLevel = 1; progressScreen = new ProgressScreen(level); levelDisplay = new LevelDisplay(); } if (!gameOver) { //r = 0; if (lives != 0) { if (splashScreen != null) { splashScreen.draw(potCurr); if (splashScreen.isDone()) { splashScreen = null; } } else if (howToPlay != null) { howToPlay.draw(); if (howToPlay.isOver()) { howToPlay = null; } } else if (progressScreen != null && level < 4 && !newWorld) { progressScreen.draw(wonLastGame, lives, firstProg, r, s); if (progressScreen.isDone()) { progressScreen = null; firstProg = false; } } else if (levelDisplay != null && level < 4) { levelDisplay.draw(level); if (levelDisplay.isDone()) { if (newWorld) { background(255); progressScreen.draw(wonLastGame, lives, firstProg, r, s); if (progressScreen.isDone()) { progressScreen = null; firstProg = false; newWorld = false; levelDisplay = null; } } else { levelDisplay = null; } } } else { if (r == 0) { if (slidingLevelOne == null) { slidingLevelOne = new SlidingLevelOne(timer, level); } slidingLevelOne.draw(slidingVal); if (slidingLevelOne.gameOver()) { slidingLevel++; progressScreen = new ProgressScreen(level); r = floor(random(0, 4)); while (r == 0) { r = floor(random(0, 4)); } s = floor(random(0, 3)); wonLastGame = slidingLevelOne.isWinner(); if (!wonLastGame) { lives--; incorrect(); } else { correct(); } slidingLevelOne = null; } } else if (r == 1) { //text("Push sensor!", width/2, height/2); //if (distLevelOne == null) { // distLevelOne = new DistLevelOne(timer, level); //} //distLevelOne.draw(vI); if (slidingLevelOne == null) { slidingLevelOne = new SlidingLevelOne(timer, level); } slidingLevelOne.draw(slidingVal); if (slidingLevelOne.gameOver()) { distLevel++; progressScreen = new ProgressScreen(level); r = floor(random(0, 4)); while (r == 1) { r = floor(random(0, 4)); } //r = 2; s = floor(random(0, 3)); wonLastGame = slidingLevelOne.isWinner(); if (!wonLastGame) { lives--; incorrect(); } else { correct(); } slidingLevelOne = null; } } else if (r == 2) { if (photoLevelOne == null) { photoLevelOne = new PhotoLevelOne(timer, level); } photoLevelOne.draw(photoVal); if (photoLevelOne.gameOver()) { photoLevel++; progressScreen = new ProgressScreen(level); r = floor(random(0, 4)); while (r == 2) { r = floor(random(0, 4)); } //r = 1; s = floor(random(0, 3)); wonLastGame = photoLevelOne.isWinner(); if (!wonLastGame) { lives--; incorrect(); } else { correct(); } photoLevelOne = null; } } else { text("Turn potentiometer!", width/2, height/2); if (potLevelOne == null) { potLevelOne = new PotLevelOne(timer, potCurr); } potLevelOne.draw(potCurr); if (potLevelOne.gameOver()) { potLevel++; progressScreen = new ProgressScreen(level); r = floor(random(0, 4)); while (r > 2) { r = floor(random(0, 4)); } s = floor(random(0, 3)); wonLastGame = potLevelOne.isWinner(); if (!wonLastGame) { lives--; incorrect(); } else { correct(); } potLevelOne = null; } } println("Level: " + level); println("slidingLevel: " + slidingLevel); println("distLevel: " + distLevel); println("photoLevel: " + photoLevel); println("r: " + r); if (level == 1) { if (slidingLevel == 2 && distLevel == 2 && photoLevel == 2 && potLevel == 2) { level++; levelDisplay = new LevelDisplay(); timer = 7; } else { if (r == 0 && slidingLevel == 2) { while (r == 0) { r = floor(random(0, 4)); } } if (r == 1 && distLevel == 2) { while (r == 1) { r = floor(random(0, 4)); } } if (r == 2 && photoLevel == 2) { while (r == 2) { r = floor(random(0, 4)); } } if (r > 2 && potLevel == 2) { while (r > 2) { r = floor(random(0, 4)); } } } } else if (level == 2) { if (slidingLevel == 3 && distLevel == 3 && photoLevel == 3 && potLevel == 3) { level++; levelDisplay = new LevelDisplay(); timer = 5; } else { if (r == 0 && slidingLevel == 3) { while (r == 0) { r = floor(random(0, 4)); } } if (r == 1 && distLevel == 3) { while (r == 1) { r = floor(random(0, 4)); } } if (r == 2 && photoLevel == 3) { while (r == 2) { r = floor(random(0, 4)); } } if (r > 2 && potLevel == 3) { while (r > 2) { r = floor(random(0, 4)); } } } } else if (level == 3) { if (slidingLevel == 4 && distLevel == 4 && photoLevel == 4 && potLevel == 4) { level++; pot = potCurr; levelDisplay = new LevelDisplay(); timer = 5; } else { if (r == 0 && slidingLevel == 4) { while (r == 0) { r = floor(random(0, 4)); } } if (r == 1 && distLevel == 4) { while (r == 1) { r = floor(random(0, 4)); } } if (r == 2 && photoLevel == 4) { while (r == 2) { r = floor(random(0, 4)); } } if (r > 2 && potLevel == 4) { while (r > 2) { r = floor(random(0, 4)); } } } } else { gameOver = true; win = true; } } } else { gameOver = true; } } else { if (win) { fill(#10A073); background(255); textSize(128); text("You Win!", width/2-330, height/2); } else { fill(#C40E0E); background(1); textSize(128); text("Game Over!", width/2-330, height/2); } textSize(32); //text("Place your hand in front of the Futuristic Sensor for 5 seconds to restart!", width/2-550, height/2+300); //text("Twist the Twisty Knob to begin!", width/2-250, height/2+300); println("vI: " + vI); //if (abs(potCurr-pot) > 100) { // text(restartTimer, 50, 50); // restartCounter++; // if (restartCounter % 30 == 0) { // restartTimer--; // if (restartTimer == 0) { // restart = true; // } // } //} } } } void serialEvent(Serial myPort) { v = myPort.readString(); print("v:" + v); //int vI = 1; String vals[] = {}; if (v!=null) { vals = v.split(","); println("vals: "+vals[0]); } vI = 0; if (vals.length > 0) { vI = parseInt(vals[0].trim()); } print(" vI: "+vI); int z = 0; if (vals.length > 1) { z = parseInt(vals[1].trim()); photoVal = parseInt(vals[2].trim()); slidingVal = parseInt(vals[3].trim()); slidingVal = floor(map(slidingVal, 0, 1023, 0, height)); } //print(" z: " + z+"\n"); //println(vals[2].trim()); if (firstPot) { potPrev = z; potCurr = z; firstPot = false; } else { potCurr = z; //println(r); //if (abs(potPrev - potCurr) > 25) { // if (r < 1) { // r = random(1, 2); // } //} potPrev = potCurr; } //if (vI < 50) { // if (r >= 1 && r < 2) { // r = random(0, 1); // } //} //myPort.write('x'); myPort.write(lives); myPort.write(level); //myPort.write("Hello"); } void correct() { winner = minim.loadFile("correct.mp3"); //TODO winner.play(); } void incorrect() { loser = minim.loadFile("wrong.mp3"); // TODO loser.play(); }
Asteroid:
class Asteroid { PImage bigasteroid; int x; int y; int radius; int speed; Asteroid(int speed) { bigasteroid = loadImage("smallasteroid.png"); this.x = width+50; this.y = floor(random(0, height)); this.radius = 50; this.speed = speed; } void draw() { image(bigasteroid, x, y); x-=speed; } public int getX() { return x; } public int getY() { return y; } public boolean offScreen() { return (x < -50); } }
Cirlce (Used to draw various circles like the sun and moon in sun blocker and the loading screen blue circle):
class Cirlce { float x = width/2; float y = height/2; int diameter = 50; Ani diameterAni; color from = color(255, 8, 8); color to = color(8, 187, 255); color c = color(#1895F2); Cirlce(float x, float y, color c, float s, int r, int size) { this.x = x; this.y = y; this.c = c; // diameter animation diameterAni = new Ani(this, s, "diameter", size, Ani.EXPO_IN_OUT);//, "onEnd:randomize" // repeat yoyo style (go up and down) diameterAni.setPlayMode(Ani.YOYO); // repeat 3 times diameterAni.repeat(r); } void draw() { noStroke(); fill(c); ellipse(x, y, diameter, diameter); //fill(0); //text(diameterAni.getRepeatNumber()+" / "+diameterAni.getRepeatCount(), x, y+diameter); } void randomize(Ani _ani) { //c = lerpColor(from, to, random(1)); // new repeat count int newCount = 1+2*round(random(4)); diameterAni.repeat(newCount); // restart diameterAni.start(); // move to new position //Ani.to(this, 1.5, "x", width/2, Ani.EXPO_IN_OUT); //Ani.to(this, 1.5, "y", height/2, Ani.EXPO_IN_OUT); } }
Cloud (Drawn in day time for sun blocker):
class Cloud{ Cloud(){} public void draw(int x){ fill(255); ellipse(x, 200, 70, 70); ellipse(x, 240, 150, 65); } }
Futuristic Sensor Game (did not end up using because of distance sensor acting up):
class DistLevelOne { float upper; float lower; int timer; int count; boolean first; boolean winner; boolean gameOver; int winTime; PImage robber; PImage robberSad; PImage bank; PImage bankOpen; DistLevelOne(int timer, int level) { this.winner = false; this.gameOver = false; this.upper = floor(random(300, height/2)); this.lower = floor(random(100, 300)); this.timer = timer; this.first = false; this.robber = loadImage("robber.png"); this.robberSad = loadImage("robber sad.png"); this.bank = loadImage("bankbg.png"); this.bankOpen = loadImage("bankbgopen.png"); if (level == 1) { this.winTime = floor(random(4, 6)); } else { this.winTime = floor(random(3, 5)); } } public boolean gameOver() { return gameOver; } public boolean isWinner() { return winner; } void draw(float vI) { //background(); //vI = map(vI, 200,800,0,1023); println("dist vI: " + vI); textSize(32); if (!gameOver) { count++; if (count % 30 == 0) { timer--; } //background(255); image(bank, 0, 0); //fill(#555555); //ellipse(width/2, height/2, upper, upper); //fill(255); //ellipse(width/2, height/2, lower, lower); //fill(#FA0505); //if (vI < upper && vI > lower) { // fill(#0CBF33); //} if (winner) { //background(); image(bankOpen, 0, 0); image(robberSad, width/2-100, height/2-100); } else if (timer < winTime) { //background(); image(bankOpen, 0, 0); text("HE GOT AWAY!", width/2, height/2); } else { if (timer == winTime || timer-1 == winTime) { fill(100); text("STOP HIM!", width/2, height/2-100); //fill(#3AF71E); //ellipse(width/2, height/2, 50, 50); image(bankOpen, 0, 0); image(robber, width/2-100, height/2-100); } if (vI < 0) { if (timer == winTime) { winner = true; //gameOver = true; } else { winner = false; gameOver = true; } } } if (timer == 0) { gameOver = true; //winner = false; } //if (vI < 600) { // ellipse(width/2, height/2, vI, vI); //} //text(vI, 50, 50); text("Stop the robber using the Futuristic Sensor exactly when he appears!", width/2-100, 50); fill(100); text("Time: " + timer, 50, 75); } } }
How To Play Screen:
class HowToPlay { int timer = 20; int counter = 0; boolean done = false; HowToPlay() { } void draw() { counter++; if (counter % 30 == 0) { timer--; } if (timer==0) { done = true; } fill(80); textSize(64); text("How To Play", width/2-200, 100); textSize(32); text("Time: " + timer, 50, 50); textSize(48); text("\n There are 3 Worlds, each with 4 games\n 1 for each controller\n You have 3 lives\n\nYou will be told what controller is next\n Now go show off your Smooth Moves!", width/2-470, 200); } public boolean isOver() { return done; } }
LevelDisplay (Displays “World 1”, “World 2”, “World 3”):
class LevelDisplay { int counter = 0; int timer = 5; boolean done = false; //Change to false LevelDisplay() { } public void draw(int level) { counter++; if (counter % 30 == 0) { timer--; } if (timer == 0) { done = true; } textSize(64); fill(80); text("World " + level, width/2-130, height/2); } public boolean isDone(){ return done; } }
Sun Blocker Game (PhotoLevelOne.pde):
class PhotoLevelOne { int counter; int timer; boolean day; boolean noon; boolean night; boolean gameOver; boolean firstNight; boolean resetDay; boolean resetNoon; boolean resetNight; int sunSize = 150; Cloud cloud = new Cloud(); int cx = 500; Spaceship spaceship = new Spaceship(); int sx = 0; int sy = 100; ArrayList<Integer> x; ArrayList<Integer> y; String[] phrases = { "Breakfast", "Crack of Dawn", "Lunch", "Dusk", "Dinner", "Nocturnal" }; String phrase; //PImage sunflower; Cirlce sun; Cirlce noonSun; Cirlce moon; PhotoLevelOne(int timer, int level) { // int r = floor(random(0, 2)); // if (r==0) { // day = true; // } else { // day = false; // } this.timer = timer; //floor(random(5, 10)); this.counter = 0; this.day = true; this.noon = false; this.night = false; this.gameOver = false; this.firstNight = true; this.x = new ArrayList<Integer>(); this.y = new ArrayList<Integer>(); if (level >0) { int ran = floor(random(0, 6)); phrase = phrases[ran]; } else { int ran = floor(random(2, 6)); phrase = phrases[ran]; } this.resetDay = true; this.resetNoon = true; this.resetNight = true; } void draw(int light) { if (day) { background(#13D0F0); if (resetDay) { this.sun = new Cirlce(200, 200, color(#F6FF0D), 0.5, 1, sunSize); resetDay = false; resetNoon = true; resetNight = true; cx = 500; } sun.draw(); cloud.draw(cx); cx+=5; fill(#00B413); rect(0, height-200, width, 200); //image(sunflower, width/2+200, height-400); } else if (noon) { background(#F08213); if (resetNoon) { this.noonSun = new Cirlce(400, 600, color(#F7CF02), 0.5, 1, sunSize); resetDay = true; resetNoon = false; resetNight = true; } noonSun.draw(); fill(#019311); rect(0, height-200, width, 200); } else { background(#2F035D); if (resetNight) { this.moon = new Cirlce(width-200, 200, color(#E3E3E3), 0.5, 1, sunSize); sx = 0; resetDay = true; resetNoon = true; resetNight = false; } moon.draw(); fill(255); for (int i = 0; i < 500; i++) { if (firstNight) { x.add(floor(random(0, width))); y.add(floor(random(0, height))); } //int r = floor(random(0, 2)); if (i % 30 == 0) { ellipse(x.get(i), y.get(i), 2, 2); } } firstNight = false; fill(#013907); rect(0, height-200, width, 200); spaceship.drawCustom(sx, sy); sx+=10; } fill(250); textSize(32); text(timer, width-50, 50); counter++; if (counter % 30 == 0) { timer--; if (timer == 0) { gameOver = true; } } if (light < 400) { day = true; noon = false; night = false; } else if (light < 900) { day = false; noon = true; night = false; } else { day = false; noon = false; night = true; } fill(250); textSize(64); text(phrase, width/2-100, 100); textSize(32); text("Cover the Sun Blocker with your hand to change time of day!", width/2-500, height-50); } public boolean gameOver() { return gameOver; } public boolean isWinner() { if (phrase == "Breakfast") { return day; } else if (phrase == "Crack of Dawn") { return day; } else if (phrase == "Lunch") { return noon; } else if (phrase == "Dusk") { return noon; } else { println("NIGHT WONNER"); return night; } } }
Planet (Drawn in Sliding Thingy Game):
class Planet { PImage image; int x; int y; color c = color(random(0,255), random(0,255), random(0,255)); Planet() { this.image = loadImage("myPlanet.png"); this.x = width+150; this.y = height/2; } public void draw(int speed) { //ellipse(x, y, 300, 300); image(image, x, y); x -= speed-10; } public boolean offScreen(){ return x < -200; } }
Twisty Knob Game (PotLevelOne.pde):
class PotLevelOne { int upper; int lower; int timer; int counter; int charlie = 1; int lisa = 1; int ed = 1; int speaker = 1; int purp = 1; int mspacman = 1; int ironsprite = 1; boolean gameOver = false; boolean winner = false; boolean party; PotLevelOne(int timer, int potCurr) { this.timer = timer; this.counter = 0; this.party = false; lower = floor(random(0, 1023)); int u = lower + 300; if (u > 1023) { u = u - 1023; } upper = floor(random(lower+100, u)); while (potCurr > lower && potCurr < upper) { lower = floor(random(0, 1023)); u = lower + 300; if (u > 1023) { u = u - 1023; } upper = floor(random(lower+100, u)); } } public boolean gameOver() { return gameOver; } public boolean isWinner() { return party; } void draw(float potCurr) { counter++; if (counter % 30 == 0) { timer--; } if (timer == 0) { gameOver = true; } //ellipse(width/2, height/2, 100, 100); noStroke(); if (!party) { background(255); fill(#C4C5C6); rect(0, 0, width, height); fill(#4D4F50); rect(0, height/2+250, width, height); fill(#293A46); rect(0, 0, 150, height/2+250); rect(width-150, 0, 250, height/2+250); } else { background(#3E3C3D); fill(#0B7152); rect(0, 0, width, height); fill(#3E3C3D); rect(0, height/2+250, width, height); fill(#212121); rect(0, 0, 150, height/2+250); rect(width-150, 0, 250, height/2+250); image(loadImage("charlie"+charlie+".png"), width/2-500, 200); //image(loadImage("ed"+ed+".png"), width/2-100, 200); /*image(loadImage("speakers"+speaker+".png"), 25, 50); image(loadImage("speakers"+speaker+".png"), 25, 200); image(loadImage("speakers"+speaker+".png"), 25, 350); image(loadImage("speakers"+speaker+".png"), width-125, 50); image(loadImage("speakers"+speaker+".png"), width-125, 200); image(loadImage("speakers"+speaker+".png"), width-125, 350); */ for (int i = 1; i < 4; i++) { fill(#191A19); if (counter % 6 == 0) { ellipse(75, 150*i, 100, 100); } else { ellipse(75, 150*i, 75, 75); } fill(#D3D3D3); ellipse(75, 150*i, 30, 30); } for (int i = 1; i < 4; i++) { fill(#191A19); if (counter % 6 == 0) { ellipse(width-75, 150*i, 100, 100); } else { ellipse(width-75, 150*i, 75, 75); } fill(#D3D3D3); ellipse(width-75, 150*i, 30, 30); } //image(titans, width/2-100, 200); //image(ed, width/2+100, 200); image(loadImage("lisa"+lisa+".png"), width/2+200, 200); image(loadImage("purp"+purp+".png"), width/2, height/2); image(loadImage("mspacman"+mspacman+".png"), width/2-600, height/2); image(loadImage("ironsprite"+ironsprite+".png"), width/2-200, height/2-200); //ellipse(width/2, height/2, 50, 50); if (counter % 3 == 0) { charlie++; lisa++; ed++; } if (counter % 5 == 0) { speaker++; purp++; } if (counter % 10 == 0) { mspacman++; ironsprite++; } if (charlie == 17) { charlie = 1; } if (lisa == 7) { lisa = 1; } if (ed == 7) { ed = 1; } if (purp == 4) { purp = 1; } if (mspacman == 3) { mspacman = 1; } if (ironsprite == 5) { ironsprite = 1; } } if (speaker == 3) { speaker = 1; } //if (party) { //} else { // stroke(1); //} fill(1); ellipse(width/2, height/2+350, 180, 180); fill(255); ellipse(width/2, height/2+350, 30, 30); fill(1); ellipse(width/2-300, height/2+350, 180, 180); fill(255); ellipse(width/2-300, height/2+350, 30, 30); fill(1); ellipse(width/2+300, height/2+350, 180, 180); fill(255); ellipse(width/2+300, height/2+350, 30, 30); strokeWeight(2); stroke(255); line(width/2, height/2+350, width/2 + 90 * cos(radians(map(potCurr, 0, 1023, 180, 360))), height/2+350 + 90 * sin(radians(map(potCurr, 0, 1023, 180, 360)))); line(width/2-300, height/2+350, width/2-300 + 90 * cos(radians(map(potCurr, 0, 1023, 0, 180))), height/2+350 + 90 * sin(radians(map(potCurr, 0, 1023, 0, 180)))); line(width/2+300, height/2+350, width/2+300 + 90 * cos(radians(map(potCurr, 0, 1023, 90, 270))), height/2+350 + 90 * sin(radians(map(potCurr, 0, 1023, 90, 270)))); noStroke(); if (potCurr > lower && potCurr < upper) { //text("win!", width/2, height/2-300); //fill(#1FE012); //ellipse(width/2, height/2-300, 50, 50); party = true; } else { //text("lose!", width/2, height/2-300); //fill(#E02E12); //ellipse(width/2, height/2-300, 50, 50); party = false; } textSize(32); fill(#E3E3E3); text("Timer: " + timer, 50, height-50); text("Turn the turntables until the party starts!", width/2-350, 50); } void endGame(boolean win) { if (!gameOver) { gameOver = true; if (win) { winner = true; } else { winner = false; } } if (winner) { text("You Win!", width/2, height/2); } else { text("You Fail!", width/2, height/2); } } }
Progress Screen (Displays next controller to use and a snarky comment on how you did in the last game):
class ProgressScreen { boolean done; int counter; int timer; int nextGame; int o; int tw; int th; ProgressScreen(int level) { if(level == 1){ this.timer = 15; } else if (level == 2){ this.timer = 10; } else{ this.timer = 6; } this.done = false; this.counter = 0; o = floor(random(1, 4)); tw = floor(random(1, 3)); th = floor(random(1, 4)); } void draw(boolean win, int lives, boolean first, int r, int s) { fill(80); textSize(32); text("Timer: " + timer, 50, 50); counter++; if (counter % 20 == 0) { timer--; if (timer == 0) { done = true; } } //fill(255); text(lives + " lives left", width/2-100, height/2+20); textSize(64); if (!first) { if (win) { if (s == 0) { text("Good job!", width/2-150, height/2-100); } else if (s == 1) { text("Don't get too cocky now...", width/2-400, height/2-100); } else if (s == 2) { text("Ok I'll admit that was good", width/2-400, height/2-100); } } else { if (s == 0) { text("You suck!", width/2-200, height/2-100); } else if (s==1) { text("You're better than this!", width/2-400, height/2-100); } else if (s == 2) { text("What's wrong with you...", width/2-300, height/2-100); } } } else { text("Welcome first timer!", width/2-300, height/2-100); } textSize(32); //text("Loading next game", width/2-150, height/2+400); text("Up next:", width/2-75, height/2+200); textSize(64); if (r==0) { text("Sliding Thingy", width/2-250, height/2+300); textSize(32); text("Avoid the meteors!", width/2-150, height-50); } else if (r==1) { //text("Futuristic Sensor", width/2-300, height/2+300); //textSize(32); //text("Stop the robber using the Futuristic Sensor exactly when he appears!", width/2-450, height-50); text("Sliding Thingy", width/2-250, height/2+300); textSize(32); text("Avoid the meteors!", width/2-150, height-50); } else if (r == 2) { text("Sun Blocker", width/2-200, height/2+300); textSize(32); text("Cover the Sun Blocker with your hand to change time of day!", width/2-500, height-50); } else { text("Twisty Knob", width/2-210, height/2+300); textSize(32); text("Turn the turntables until the party starts!", width/2-350, height-50); } textSize(32); image(loadImage("ironsprite"+o+".png"), 100, 100); image(loadImage("mspacman"+tw+".png"), width-500, 350); image(loadImage("purp"+th+".png"), width-300, 500); } public boolean isDone() { return done; } }
Sliding Thingy Game (SlidingLevelOne.pde):
class SlidingLevelOne { int counter = 0; int speed; Planet planet = null; Sun sun = null; Spaceship spaceship; int timer; ArrayList<Star> stars; ArrayList<Asteroid> asteroids; boolean done = false; boolean win = false; SlidingLevelOne(int timer, int level) { //size(800, 600); //fullScreen(); noStroke(); //background(#2F035D); this.timer = timer; this.sun = new Sun(); this.spaceship = new Spaceship(); this.stars = new ArrayList<Star>(); for (int i = 0; i < 100; i ++) { stars.add(new Star(floor(random(0, width)), floor(random(0, width)))); } this.asteroids = new ArrayList<Asteroid>(); if(level == 1){ speed = 15; } else if (level == 2){ speed = 25; } else{ speed = 35; } } void draw(int pos) { background(#120134); textSize(32); text("Avoid the meteors!", width/2-100, 50); sun.draw(speed); counter++; //if (counter % 50 == 0) { // speed+=1; //} if (counter % 30 == 0) { timer--; } if (planet == null) { planet = new Planet(); } if (planet != null) { planet.draw(speed); if (planet.offScreen()) { planet = null; } } for (int i = 0; i < stars.size(); i ++) { stars.get(i).draw(speed+5); if (stars.get(i).offScreen()) { stars.remove(i); stars.add(new Star(width, floor(random(0, width)))); } } spaceship.draw(pos); fill(#E3E3E3); if (counter % 20 == 0) { asteroids.add(new Asteroid(speed)); } for (int i = 0; i < asteroids.size(); i++) { asteroids.get(i).draw(); if (rectRect(spaceship.getX(), spaceship.getY(), 200, 100, asteroids.get(i).getX(), asteroids.get(i).getY(), 100, 100)) { done = true; win = false; } if(asteroids.get(i).offScreen()){ asteroids.remove(i); } } text("Timer: " + timer, 50, 50); if (timer == 0) { done = true; win = true; } } // CIRCLE/RECTANGLE boolean circleRect(float cx, float cy, float radius, float rx, float ry, float rw, float rh) { // temporary variables to set edges for testing float testX = cx; float testY = cy; // which edge is closest? if (cx < rx) testX = rx; // compare to left edge else if (cx > rx+rw) testX = rx+rw; // right edge if (cy < ry) testY = ry; // top edge else if (cy > ry+rh) testY = ry+rh; // bottom edge // get distance from closest edges float distX = cx-testX; float distY = cy-testY; float distance = sqrt( (distX*distX) + (distY*distY) ); // if the distance is less than the radius, collision! if (distance <= radius) { return true; } return false; } // RECTANGLE/RECTANGLE boolean rectRect(float r1x, float r1y, float r1w, float r1h, float r2x, float r2y, float r2w, float r2h) { // are the sides of one rectangle touching the other? if (r1x + r1w >= r2x && // r1 right edge past r2 left r1x <= r2x + r2w && // r1 left edge past r2 right r1y + r1h >= r2y && // r1 top edge past r2 bottom r1y <= r2y + r2h) { // r1 bottom edge past r2 top return true; } return false; } public boolean gameOver() { return done; } public boolean isWinner() { return win; } }
Spaceship (Drawn in Sliding Thingy Game):
class Spaceship { int x; int y; PImage spaceship; Spaceship() { this.x = width/20; this.y = height/2; this.spaceship = loadImage("spaceship.png"); } public void draw(int pos) { //fill(#E3E3E3); //fill(#10A073); y = pos; //ellipse(x, pos, 60, 60); image(spaceship, x, y); } public void drawCustom(int x, int y) { //fill(#E3E3E3); //fill(#10A073); //ellipse(x, y, 60, 60); image(spaceship, x, y); } public int getX() { return x; } public int getY() { return y; } }
Splash Screen (Displayed at the very beginning, “Welcome to Smooth Moves”):
class SplashScreen { int upper; boolean done; int timer; int counter; Cirlce circle; boolean reset; int pot; SplashScreen(int potCurr) { this.upper = 100; this.done = false; // Change to false this.timer = 5; this.counter = 0; this.reset = true; this.pot = potCurr; println("this.pot = potCurr: " + pot); } public boolean isDone() { return done; } void draw(int potCurr) { background(255); if (!done) { fill(#555555); //ellipse(width/2, height/2, upper, upper); if (abs(pot-potCurr) > 100) { if(reset){ reset = false; circle = new Cirlce(width/2, height/2, color(#1895F2), 1, 10, 200); } text(timer, 50, 50); fill(#015F06); counter++; if (counter % 20 == 0) { timer--; } if (timer == 0) { done = true; } //ellipse(width/2, height/2, vI, vI); circle.draw(); text("Loading", width/2-50 , height-50); } else { fill(80); text("Welcome to",width/2-100,height/2-300); textSize(128); text("Smooth Moves",width/2-450,height/2-150); textSize(32); // text("Place your hand in front of the Futuristic Sensor for 5 seconds to begin!", width/2-550, height/2+300); text("Twist the Twisty Knob to begin!", width/2-250, height/2+300); timer = 5; reset = true; } } else { fill(255); text("DONE!", width/2, height/2); } } }
Star (Drawn in Sliding Thingy Game):
class Star { int x; int y; int s; Star(int x, int y) { this.x = x; this.y = y; this.s = floor(random(4,11)); } public void draw(int speed) { fill(#FFEB83); ellipse(x, y, s, s); x -= speed; } public boolean offScreen(){ return x < 0; } }
Sun (Drawn in Sliding Thingy Game):
class Sun { PImage image; float x; int y; Sun() { this.image = loadImage("mySun.png"); this.x = width/2; this.y = height/2-50; } public void draw(int speed) { fill(#FDB813); ellipse(x, y, 100, 100); //image(image, x, y); x -= speed/100.0; } public boolean offScreen(){ return x < -200; } }