/* 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); } } } }