/*
INTERACTIVE MEDIA
"INTERACTIVE TOY"
MARINA PIMENTEL
OCT. 05, 2015
Two players; one player uses keyboard arrow keys (left/right) & spacebar to move & shoot respectively,
the other uses the mouse to manoeuver the block around the screen and dodge the fired shots & laser bars.
*/
// VARIABLES ***************************************************************************************************************
// - - - - - others - - - - - - - - - - - - - - - - - - - - - - ->
int screenSize = 500;
color bg = 150; //grey
String[] startMsg = {"QUICK, DODGE THINGS!", "PLAYER 1: use the mouse", "PLAYER 2: use arrow keys & spacebar"}; //appears all game (behind bars)
String[] lColMsg = {"ow", "oh god stop", "it hurts", "dear god why", "pls", "goddamnit", "[muffled sobbing]", "there goes my good eye", "sweet baby jesus", "help"}; //for when square intersects a laser bar (or 8)
String[] shColMsg = {"NICE SHOT", "that square sucks at dodging"}; //when square intersects fired shot(s)
color strColour = 120; //darker grey
// - - - - - player 1 (square) - - - - - - - - - - - - - - - - - >
int sSize = 20;
color sColour = color(255); //white
// - - - - - player 2 (triangles & fired shots) - - - - - - - - ->
boolean tMove = false; //determines whether arrow keys have been pressed & when to draw movement for triangles
float[] tPosX = {0, 100, 50, 500, 500, 470, 500, 400, 450, 0, 0, 30}; //triangles starting X
float[] tPosY = {500, 500, 470, 500, 400, 450, 0, 0, 30, 0, 100, 50}; //triangles starting Y
color tColour = 255; //white
// - - - fired shots - - ->
boolean tFireShots = false; //determines whether spacebar has been pressed & when to draw fired shots 'animation'
boolean shSwitch = false; //determines whether to actually draw fired shots
int shSize = 30;
float[] shPosX = new float[4];
float[] shPosY = new float[4];
color shColour = color(250, 200, 30); //gold
// - - - - - moving lasers - - - - - - - - - - - - - - - - - - - >
int lNum = 9; //number of laser bars on screen at once
int lHeight = 20;
color[] lColour = {color(100, 50, 50), color(50, 100, 100)}; //red & teal
float[] lPosY = new float[lNum];
// - - - laser gaps - - - >
int gHeight = lHeight+2;
float[] gWidth = new float[lNum];
float[] gPosX = new float[lNum];
color gColour = bg; //fake transparency (grey; although screws with the background text, which is unfortunate!)
// SETUP *******************************************************************************************************************
void setup() {
size(501, 501);
//first, let's define some array values...
for (int i=0; i<lNum; i++) {
lPosY[i]=(screenSize/lNum)*i; //laser bar Y (topmost)
gPosX[i]=random(0, 460); //gap X (leftmost)
gWidth[i]=random(40, 100); //gap width
}
}
// DRAW ********************************************************************************************************************
void draw() {
background(bg);
// - - - - - background message - - - - - - - - - - - - - - - - - - - - - - - - - - >
fill(strColour);
textSize(20);
text(startMsg[0], screenSize/2-(textWidth(startMsg[0])/2), (screenSize/2)+10);
textSize(10);
text(startMsg[1], (screenSize/2-(textWidth(startMsg[1])/2)-30), (screenSize/2)+30);
text(startMsg[2], (screenSize/2-(textWidth(startMsg[1])/2)-30), (screenSize/2)+40);
// - - - - - laser bars - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >
noStroke();
lasers(0.5); //initiates laser bar movement loop
// - - - - - square (player 1; controllable with mouse) - - - - - - - - - - - - - - >
stroke(1);
fill(sColour);
if (mouseX-(sSize/2) < 0) { //if square hits bottom of screen...
rect(0, mouseY-(sSize/2), sSize, sSize); //...keep it there until mouse moves away;
} else if (mouseX+(sSize/2) >= 500) { //similarly, if it hits right of screen...
rect(500-sSize, mouseY-(sSize/2), sSize, sSize); //...same thing;
} else if (mouseY-(sSize/2) <= 0) { //or, if it hits top of screen;
rect(mouseX-(sSize/2), 0, sSize, sSize);
} else if (mouseY+(sSize/2) >= 500) { //...or even left side of screen;
rect(mouseX-(sSize/2), 500-sSize, sSize, sSize);
} else { //HOWEVER, if it's within screen bounds...
detectCollision(mouseY-(sSize/2), mouseY+(sSize/2), mouseX-(sSize/2), mouseX+(sSize/2)); //find out whether square was hit with laser bar or fired shots & proceed in detectCollision()
rect(mouseX-(sSize/2), mouseY-(sSize/2), sSize, sSize); //draw square in any case
}
// - - - - - triangles (player 2; controllable with arrow keys) - - - - - - - - - - >
fill(tColour);
triangle(tPosX[0], tPosY[0], tPosX[1], tPosY[1], tPosX[2], tPosY[2]); //bottom triangle
triangle(tPosX[3], tPosY[3], tPosX[4], tPosY[4], tPosX[5], tPosY[5]); //right triangle
triangle(tPosX[6], tPosY[6], tPosX[7], tPosY[7], tPosX[8], tPosY[8]); //left triangle
triangle(tPosX[9], tPosY[9], tPosX[10], tPosY[10], tPosX[11], tPosY[11]); //top triangle
if (tFireShots) {
shotsFired(); //trigger firing shot x4 (aka. allows fire to rain down upon thine enemy)
}
// - - - - - triangle shots (spacebar) - - - - - - - - - - - - - - - - - - - - - - ->
fill(shColour);
noStroke();
if (shSwitch==true && shPosY[0]>0-shSize) { //if player 2 hits spacebar, shSwitch will enable drawing the fired shots, then update coords (providing a shot isn't already animating):
for (int i=0; i<4; i++) { //draw shots x4
rect(shPosX[i], shPosY[i], shSize, shSize);
}
shPosY[0]=shPosY[0]-10; //update bottom shot (^)
shPosX[1]=shPosX[1]-10; //update right shot (<--)
shPosY[2]=shPosY[2]+10; //update top shot (v)
shPosX[3]=shPosX[3]+10; //update left shot (-->)
} else { //...THEN, when the master shot (the bottom one) exceeds the boundaries of the screen...
shSwitch=false; //...stop animating & reset X & Y coordinates:
shPosX[0]=tPosX[2]-(shSize/2); //reset bottom shot
shPosY[0]=tPosY[2]-shSize;
shPosX[1]=tPosX[5]-shSize; //reset right shot
shPosY[1]=tPosY[5]-(shSize/2);
shPosX[2]=tPosX[8]-(shSize/2); //reset top shot
shPosY[2]=tPosY[8];
shPosX[3]=tPosX[11]; //reset left shot
shPosY[3]=tPosY[11]-(shSize/2);
}
}
// KEYPRESSED (PLAYER 2) ***************************************************************************************************
void keyPressed() {
if (key==CODED) {
//tMove=true;
if (keyCode==LEFT) { //if left arrow key is pressed...
if (tPosX[0]<=1) { //...prevent bottom triangle exiting screen left (master collision for all triangles)...
} else {
tMove=true; //...otherwise, draw normally with updated coords:
for (int i=0; i<=11; i++) {
if (i<=2) { //bottom triangle
tPosX[i]=tPosX[i]-5;
} else if (i>=3 && i<=5) { //right triangle
tPosY[i]=tPosY[i]+5;
} else if (i>=6 && i<=8) { //top triangle
tPosX[i]=tPosX[i]+5;
} else if (i>=9) { //left triangle
tPosY[i]=tPosY[i]-5;
}
}
}
} else if (keyCode==RIGHT) { //if right arrow key is pressed...
if (tPosX[1]>=499) { //...prevent bottom triangle exiting screen right (master collision for all triangles)...
} else {
tMove=true; //...otherwise, draw normally with updated coords:
for (int i=0; i<=11; i++) {
if (i<=2) { //bottom triangle
tPosX[i]=tPosX[i]+5;
} else if (i>=3 && i<=5) { //right triangle
tPosY[i]=tPosY[i]-5;
} else if (i>=6 && i<=8) { //top triangle
tPosX[i]=tPosX[i]-5;
} else if (i>=9) { //left triangle
tPosY[i]=tPosY[i]+5;
}
}
}
}
} else {
if (key==' ') { //when spacebar is pressed...
if (shPosY[0]>=0-shSize) {
tFireShots=true; //...trigger fired shots to be drawn with updated coords:
shPosX[0]=tPosX[2]-(shSize/2);
} else {
}
}
}
}
void keyReleased() {
if (key==' ') { //when player stops holding/pressing spacebar...
tFireShots=false; //...end fired shots drawing phase
} else if (key==LEFT || key==RIGHT) { //when player stops pressing LEFT/RIGHT arrows...
tMove=false; //...end triangle movement drawing phase
}
}
// FIRE SHOTS (PLAYER 2) ***************************************************************************************************
void shotsFired() {
if (shSwitch==false) { //if shSwitch is off...
shSwitch=true; //...turn it on (triggers the shots to draw in void draw() to preserve screen refresh)
}
}
// LASER BAR MOVEMENTS *****************************************************************************************************
void lasers(float lSpeed) {
for (int i=0; i<lNum; i++) { //for every iteration of laser bar...
if (lPosY[i]<=screenSize-lHeight) { //...if the bottom of the bar has not yet reached the bottom of the screen, move normally
fill(lColour[int(random(0, 2))]);
rect(0, lPosY[i], screenSize, lHeight); //laser bar
fill(gColour);
rect(gPosX[i], lPosY[i]-1, gWidth[i], gHeight); //fake gap
lPosY[i]=lPosY[i]+lSpeed;
} else if (lPosY[i]>screenSize-lHeight && lPosY[i]<=screenSize) { //HOWEVER, if it has, make it re-draw at the top as well
fill(lColour[int(random(0, 2))]);
rect(0, 0+lPosY[i]-screenSize, screenSize, lHeight); //laser bar (reappearing at top)
fill(gColour);
rect(gPosX[i], 0+lPosY[i]-screenSize-1, gWidth[i], gHeight); //fake gap (reappearing at top)
fill(lColour[int(random(0, 2))]);
rect(0, lPosY[i], screenSize, lHeight); //laser bar (disappearing at bottom)
fill(gColour);
rect(gPosX[i], lPosY[i]-1, gWidth[i], gHeight); //fake gap (disappearing at bottom)
lPosY[i]=lPosY[i]+lSpeed;
} else { //AND THEN, reset that laser's Y (top) so the 'animation' loops once it's completed a cycle
lPosY[i]=0;
fill(lColour[int(random(0, 2))]);
rect(0, lPosY[i], screenSize, lHeight); //laser bar
fill(gColour);
rect(gPosX[i], lPosY[i]-1, gWidth[i], gHeight); //fake gap
}
}
}
// DETECT COLLISION ********************************************************************************************************
void detectCollision(float mouseTop, float mouseBot, float mouseLeft, float mouseRight) {
// - - - - - laser - - - - - >
for (int i=0; i<lNum; i++) { //for each laser bar...
if (mouseTop <= lPosY[i]+lHeight && mouseBot >= lPosY[i]) { //...if square is within laser constraints (top & bottom)...
if (mouseLeft >= gPosX[i] && mouseRight <= gPosX[i]+gWidth[i]) { ///...UNLESS there's a 'gap', square is safe...
} else { //...BUT IF NOT, square collides with laser
fill(0);
textSize(10);
text(lColMsg[i], mouseX-(textWidth(lColMsg[i])/2), mouseY-textAscent()-5);
}
}
}
// - - - - - shot - - - - - ->
if (shSwitch) { //checks if collision detection for shots is turned on before proceeding (otherwise square can collide with shot 'placeholders')
for (int i=0; i<4; i++) { //for each of the 4 shots...
if (((mouseBot > shPosY[i] && mouseBot < (shPosY[i]+shSize)) || (mouseTop > shPosY[i] && mouseTop < shPosY[i]+shSize)) && ((mouseLeft > shPosX[i] && mouseLeft < (shPosX[i]+shSize)) || (mouseRight > shPosX[i]) && mouseRight < (shPosX[i]+shSize))) { //...check collision with square & proceed with screen message if hit
background(155, 0, 0);
fill(255, 0, 0);
textSize(50);
text(shColMsg[0], screenSize/2-(textWidth(shColMsg[0])/2), (screenSize/2)+textAscent()/3);
textSize(20);
text(shColMsg[1], screenSize/2-(textWidth(shColMsg[1])/2), (screenSize/2)+40);
}
}
}
}