/*Adrian Cogswell *Interactive toy: Walking in winter *Introduction to Media Computation * *Control the alien ship's legs to avoid stepping on people and getting arrested *Score increases everytime a pedestrian touches the edge of the screen */ //foot variables //variables for foot positions, for speeds and booleans for whether a foot is raised or moving to the side float footSpeed = 1; float footAccel = 0.2; float leftFootX = 160; float rightFootX = 240; float leftFootY = 350; float rightFootY = 350; float leftSpeed = 2; float rightSpeed = 2; boolean leftUp=false; boolean rightUp=false; boolean leftLeft = false; boolean leftRight = false; boolean rightLeft = false; boolean rightRight = false; //saucer body variables //variables for saucer positions float saucerX; float saucerY; //pedestrian variables //set variables for the positions, speeds, acceleration(for ped3) and saves for the speeds(for when the pedestrian stops) float ped1X = 399; float ped2X = 399; float ped3X = 1; float pedSpeed1 = 1; float pedSpeed2 = 2; float pedSpeed3 = 0.5; float pedAccel = 0.005; float ped1Save = 0; float ped2Save = 0; float ped3Save = 0; float pedAccelSave = 0.005; //snow variables //set variables for the x and y positions of each snowflake, set the initial positions of the snowflakes float snow1X = 4; float snow2X = 38; float snow3X = 185; float snow4X = 240; float snow5X = 350; float snow1Y, snow2Y, snow3Y, snow4Y, snow5Y; //background variables int midRowX, backRowX, frontRowX; //score variables //track the player's score, variables for the score displayed on game over, boolean for whether the game is over, variables for the postitions of images in the gameover graphics int score = -2; int gameOverScore = 0; boolean gameOver = false; float endSaucerX; float endSaucerY; float endLeftFootX; float endLeftFootY; //setup - window size and state instructions for the game void setup() { size(400, 400); rectMode(CENTER); frameRate(60); println("~ to lift left foot, = to lift right, arrow keys to move a lifted foot. Don't step on people- it's rude."); } void draw() { //updates feetUpdate(); snowFallUpdate(); pedestriansMove(); pedestriansStop(); gameOverUpdate(); background(209, 219, 189); noStroke(); drawBackground(); drawSnowFall(); //street fill(62, 96, 111);//medblue rect(width/2, 375, width, 50); drawSaucer(); //PEDESTRIANS drawPedestrian1(); drawPedestrian2(); drawPedestrian3(); //score and gameover - make sure the player can't amass more score during a game over drawScore(); if (gameOver==true) { drawGameOver(); ped1X=200; ped2X=200; ped3X=200; } } void drawBackground() { //background buildings variables to be used in loops int midRowX = 20; int backRowX=10; int frontRowX=1; //parallax effect based on parallax effect demonstrated in week 2's class by Nicolas Hesler //buildings will move side to side with slight parallax effect //buildings are offset within the loops so that the cityscape looks more random and natural fill(169, 189, 172); while (backRowX < width) { rect(backRowX+2*sin(frameCount*0.01), 150, 25, 80); rect(2.85*backRowX+2*sin(frameCount*0.01), 175, 30, 40); rect(1.85*backRowX+2*sin(frameCount*0.01), 190, 50, 16); rect(1.37*backRowX+2*sin(frameCount*0.01), 180, 20, 20); rect(1.37*backRowX+35+2*sin(frameCount*0.01), 175, 20, 40); rect(0.9*backRowX+60+2*sin(frameCount*0.01), 140, 10, 90); backRowX= backRowX + 80; } fill(147, 163, 148); rect(width/2, 250, width, 75); fill(169, 189, 172); rect(width/2, 200, width, 50); fill(147, 163, 148); while (midRowX<width) { rect(midRowX+4*sin(frameCount*0.01), 250, 40, 180); rect(0.8*midRowX+30+4*sin(frameCount*0.01), 225, 10, 85); rect(1.5*midRowX+4*sin(frameCount*0.01), 225, 30, 40); rect(2*midRowX+50+4*sin(frameCount*0.01), 225, 60, 65); midRowX = midRowX +90; } fill(128, 143, 137); while (frontRowX<width) { rect(frontRowX+6*sin(frameCount*0.01), 300, 40, 180); rect(1.5*frontRowX+6*sin(frameCount*0.01), 300, 20, 300); rect(2.85*frontRowX+6*sin(frameCount*0.01)+24, 275, 80, 100); rect(0.8*frontRowX+6*sin(frameCount*0.01)-40, 325, 60, 140); frontRowX = frontRowX +120; } rect(width/2, 350, width, 150); fill(62, 96, 111);//medblue rect(width/2, 375, width, 50); } void drawSnowFall() { //SNOWFALL - have snowfall move left and right with sin(frameCount) fill(252, 255, 245);//offwhite rect(snow1X+sin(frameCount*0.1), snow1Y, 8, 8, 2); rect(snow1X+2*cos(frameCount*0.1)-100, snow1Y, 8, 8, 2); rect(snow2X+2*cos(frameCount*0.1), snow2Y, 8, 8, 2); rect(snow3X+3*sin(frameCount*0.1), snow3Y, 8, 8, 2); rect(snow4X+4*cos(frameCount*0.1), snow4Y, 8, 8, 2); rect(snow4X+5*sin(frameCount*0.1)-150, snow4Y, 8, 8, 2); rect(snow5X+5*sin(frameCount*0.1), snow5Y, 8, 8, 2); snow1Y=snow1Y+0.5; snow2Y=snow2Y+0.25; snow3Y=snow3Y+0.4; snow4Y=snow4Y+0.3; snow5Y=snow5Y+0.2; } void drawSaucer() { //Variables to track the saucer's position vertically and horizontally saucerX= 200+sin(frameCount*0.08); saucerY = 75+cos(frameCount*0.1); //DRAW THE LEGS //Have the legs bend up and away from the feet, then have the bend move relative to the feet but connect at the leg connectors of the saucer stroke(62, 96, 111);//medblue strokeWeight(10); line(saucerX-40, saucerY+37, 0.5*leftFootX, leftFootY-(saucerY+37)); line(0.5*leftFootX, leftFootY-(saucerY+37), leftFootX, leftFootY-10); line(saucerX+40, saucerY+37, 200+0.5*rightFootX, rightFootY-(saucerY+37)); line(200+0.5*rightFootX, rightFootY-(saucerY+37), rightFootX, rightFootY-10); noStroke(); //DRAW THE SAUCER //leg connectors fill(145, 170, 157);//medgrn ellipse(saucerX-40, saucerY+37, 25, 25); ellipse(saucerX+40, saucerY+37, 25, 25); //scarf fill(255, 135, 130);//orngPink quad( saucerX-70, saucerY+32, saucerX+70, saucerY+32, saucerX+90, saucerY, saucerX-90, saucerY); ellipse(saucerX, saucerY+32, 140, 20); rect(saucerX+80, saucerY+50, 20, 100); rect(saucerX+72.5, saucerY+100, 5, 20); rect(saucerX+80, saucerY+100, 5, 20); rect(saucerX+87.5, saucerY+100, 5, 20); //body fill(62, 96, 111);//medblue ellipse(saucerX, saucerY, 200, 40); fill(145, 170, 157);//medgrn ellipse(saucerX, saucerY-15, 125, 20); fill(252, 255, 245);//offwhite ellipse(saucerX, saucerY-20, 27, 27); //eyes ellipse (saucerX-65, saucerY+15, 35, 20); ellipse (saucerX+15, saucerY+15, 35, 20); fill(62, 96, 111);//medblue ellipse (saucerX-67, saucerY+19, 20, 12); ellipse (saucerX+13, saucerY+19, 20, 12); fill(252, 255, 245);//offwhite ellipse (saucerX-67, saucerY+20, 14, 8); ellipse (saucerX+13, saucerY+20, 14, 8); fill(25, 52, 65);//drkblue ellipse (saucerX-67, saucerY+20, 10, 5); ellipse (saucerX+13, saucerY+20, 10, 5); stroke(25, 52, 65); strokeWeight(6); line(saucerX-100, saucerY, saucerX-100, saucerY-40); line(saucerX+100, saucerY, saucerX+100, saucerY-40); line(saucerX-100, saucerY-40, saucerX+100, saucerY-40); noStroke(); fill(255, 135, 130);//orngPink ellipse(saucerX-100, saucerY, 23, 30); ellipse(saucerX+100, saucerY, 23, 30); //FEET //use seperate variables for the foot positions because they'll be moving //left foot fill(209, 219, 189); ellipse(leftFootX, leftFootY-10, 25, 25); fill(25, 52, 65);//drkblue ellipse(leftFootX, leftFootY, 40, 20); rect(leftFootX, leftFootY+10, 40, 20); stroke(255, 135, 130);//orngPink strokeWeight(10); line(leftFootX-15, leftFootY+10, leftFootX-30, leftFootY+12); line(leftFootX+15, leftFootY+10, leftFootX+30, leftFootY+12); //right foot noStroke(); fill(209, 219, 189); ellipse(rightFootX, rightFootY-10, 25, 25); fill(25, 52, 65);//drkblue ellipse(rightFootX, rightFootY, 40, 20); rect(rightFootX, rightFootY+10, 40, 20); stroke(255, 135, 130);//orngPink strokeWeight(10); line(rightFootX-15, rightFootY+10, rightFootX-30, rightFootY+12); line(rightFootX+15, rightFootY+10, rightFootX+30, rightFootY+12); } void drawPedestrian1() { //DRAW PEDESTRIAN 1 - have the pedestrian's head bob up and down on loop noStroke(); fill(252, 255, 245);//offwhite ellipse(ped1X, sin(frameCount*0.1)+325, 25, 25); ellipse(ped1X, 350, 25, 12); rect(ped1X, 362.5, 25, 25); fill(255, 135, 130);//orngPink rect(ped1X, 362.5, 20, 12); ellipse(ped1X+15, sin(frameCount*0.1)+325, 10, 15); ellipse(ped1X-15, sin(frameCount*0.1)+325, 10, 15); stroke(25, 52, 65); strokeWeight(4); line(ped1X+15, sin(frameCount*0.1)+325, ped1X+15, sin(frameCount*0.1)+307); line(ped1X-15, sin(frameCount*0.1)+325, ped1X-15, sin(frameCount*0.1)+307); line(ped1X+15, sin(frameCount*0.1)+307, ped1X-15, sin(frameCount*0.1)+307); strokeWeight(6); point(ped1X+6, sin(frameCount*0.1)+332); point(ped1X-6, sin(frameCount*0.1)+332); } void drawPedestrian2() { //DRAW PEDESTRIAN 2 - have the pedestrian's head bob up and down on loop noStroke(); fill(252, 255, 245);//offwhite ellipse(ped2X, cos(frameCount*0.1)+325, 25, 25); ellipse(ped2X, 350, 25, 12); rect(ped2X, 362.5, 25, 25); fill(255, 135, 130);//orngPink rect(ped2X, 362.5, 20, 12); quad(ped2X-15, sin(frameCount*0.1)+325, ped2X+15, sin(frameCount*0.1)+325, ped2X+5, sin(frameCount*0.1)+345, ped2X-5, sin(frameCount*0.1)+345); rect(ped2X+13, sin(frameCount*0.1)+340, 5, 30); stroke(25, 52, 65); strokeWeight(6); point(ped2X+5, cos(frameCount*0.1)+315); point(ped2X-5, cos(frameCount*0.1)+315); } void drawPedestrian3() { //DRAW PEDESTRIAN 3 - have the pedestrian's head bob up and down on loop and hat bob offbeat from the head noStroke(); fill(252, 255, 245);//offwhite ellipse(ped3X, sin(frameCount*0.1)+325, 25, 25); ellipse(ped3X, 350, 25, 12); rect(ped3X, 362.5, 25, 25); fill(255, 135, 130);//orngPink rect(ped3X, 362.5, 20, 12); rect(ped3X, cos(frameCount*0.1)+315, 25, 15, 5); fill(25, 52, 65);//drkblu rect(ped3X, cos(frameCount*0.1)+320, 18, 12, 5); stroke(25, 52, 65); strokeWeight(6); line(ped3X+14, cos(frameCount*0.1)+325, ped3X+14, cos(frameCount*0.1)+305); line(ped3X-14, cos(frameCount*0.1)+325, ped3X-14, cos(frameCount*0.1)+305); point(ped3X+7, sin(frameCount*0.1)+335); point(ped3X-7, sin(frameCount*0.1)+335); } //Use of text based on processing.org's reference section: https://processing.org/reference/text_.html void drawScore() { //SCORE textSize(20); fill(25, 52, 65);//drkblue text(score, saucerX-10, saucerY-45); } void feetUpdate() { //move feet up when appropriate buttons are pressed if (leftUp==true) { leftFootY= leftFootY-footSpeed; footSpeed=footSpeed+footAccel; } if (rightUp==true) { rightFootY= rightFootY-footSpeed; footSpeed=footSpeed+footAccel; } //let feet fall when buttons are no longer pressed if (leftUp==false) { leftFootY= leftFootY+footSpeed; footSpeed=footSpeed+footAccel; } if (leftFootY>350) { leftFootY=350; } if (leftFootY<250) { leftFootY=250; } if (leftFootX>400) { leftFootX=400; } if (leftFootX<0) { leftFootX=0; } //right foot if (rightUp==false) { rightFootY= rightFootY+footSpeed; footSpeed=footSpeed+footAccel; } if (rightFootY>350) { rightFootY=350; } if (rightFootY<250) { rightFootY=250; } if (rightFootX<0) { rightFootX=0; } if (rightFootX>400) { rightFootX=400; } } void snowFallUpdate() { //SNOWFALL - set snow to restart at the top of the screen with a random x value when they fall off the screen if (snow1Y>=400) { snow1Y=0; snow1X=random(1, 399); } if (snow2Y>=400) { snow2Y=0; snow2X=random(1, 399); } if (snow3Y>=400) { snow3Y=0; snow3X=random(1, 399); } if (snow4Y>=400) { snow4Y=0; snow4X=random(1, 399); } if (snow5Y>=400) { snow5Y=0; snow5X=random(1, 399); } } void pedestriansMove() { //PEDESTRIANS - set pedestrians to move left and right - have the pedestrians change direction when they hit the edge of the screen //pedestrian movement is based on section 5-7 of "Learning Processing, 2nd Edition" by Daniel Shiffman //pedestrian 1 if (ped1X>=0) { ped1X=ped1X+pedSpeed1; } if (ped1X>=400) { pedSpeed1=-pedSpeed1; ped1Save=pedSpeed1; score=score+1; } if (ped1X<=0) { pedSpeed1=-pedSpeed1; ped1Save=pedSpeed1; score=score+1; } //pedestrian2 if (ped2X>=0) { ped2X=ped2X+pedSpeed2; } if (ped2X>=400) { pedSpeed2=-pedSpeed2; ped2Save=pedSpeed2; ped2X=399; score=score+1; } if (ped2X<=0) { pedSpeed2=-pedSpeed2; ped2Save=pedSpeed2; ped2X=1; score=score+1; } //pedestrian acceleration is based on section 5-8 of "Learning Processing, 2nd Edition" by Daniel Shiffman //pedestrian3 if (ped3X>0) { ped3X=ped3X+pedSpeed3; } if (ped3X==1 || ped3X==399) { pedSpeed3= 0.5; } else { pedSpeed3=pedSpeed3+pedAccel; ped3Save=pedSpeed3; } if (ped3X>=400) { pedSpeed3=-pedSpeed3; pedAccel=-pedAccel; ped3Save=pedSpeed3; pedAccelSave=pedAccel; score=score+1; } if (ped3X<=1) { pedSpeed3=-pedSpeed3; pedAccel=-pedAccel; ped3Save=pedSpeed3; pedAccelSave=pedAccel; score=score+1; } if (ped3X<0) { ped3X=1; } } void pedestriansStop() { //set pedestrians to stop at feet - set up an area about the size of the feet where the pedestrians will stop if they are in its range and the foot is down //pedestrian 1 - left foot if (leftUp==false && ped1X>=(leftFootX-33) && ped1X<=(leftFootX+33)) { pedSpeed1=0; } else { pedSpeed1=ped1Save; } //pedestrian 1 - right foot if (rightUp==false && ped1X>=(rightFootX-33) && ped1X<=(rightFootX+33)) { pedSpeed1=0; } //pedestrian 2 - left foot if (leftUp==false && ped2X>=(leftFootX-33) && ped2X<=(leftFootX+33)) { pedSpeed2=0; } else { pedSpeed2=ped2Save; } //pedestrian 2 - right foot if (rightUp==false && ped2X>=(rightFootX-33) && ped2X<=(rightFootX+33)) { pedSpeed2=0; } //pedestrian 3 - left foot if (leftUp==false && ped3X>=(leftFootX-33) && ped3X<=(leftFootX+33)) { pedSpeed3=0; pedAccel=0; } else { pedSpeed3=ped3Save; pedAccel=pedAccelSave; } //pedestrian 3 - right foot if (rightUp==false && ped3X>=(rightFootX-33) && ped3X<=(rightFootX+33)) { pedSpeed3=0; pedAccel=0; } } //use of keypressed based on processing.org's reference section: https://processing.org/reference/keyPressed_.html void keyPressed() { //set the feet to move up with ` and =, make sure the player can't just hold both at the same time if (key=='`') { leftUp=true; rightUp=false; } else { footSpeed=1; } if (key=='=') { rightUp=true; leftUp=false; } else { footSpeed=1; } //reset button for when the player has stepped on a pedestrian - set most values to be the same as when the game is first launched if (key=='f' && gameOver==true) { score=-2; ped1X = 399; ped2X = 399; ped3X = 1; pedSpeed1 = 1; pedSpeed2 = 2; pedSpeed3 = 0.5; pedAccel = 0.005; ped1Save = 0; ped2Save = 0; ped3Save = 0; pedAccelSave = 0.005; leftFootX = 160; rightFootX = 240; gameOver=false; } //Use of arrowkeys based on processing.org's reference section: https://processing.org/reference/keyCode.html //arrow keys left foot - have the arrow keys move the left foot only when ~ is pressed if (key==CODED && leftUp==true && rightUp==false) { if (keyCode==LEFT) { leftLeft = true; } } else { leftLeft=false; } if (key==CODED && leftUp==true && rightUp==false) { if (keyCode==RIGHT) { leftRight = true; } } else { leftRight=false; } if (leftLeft==true) { leftFootX=leftFootX-leftSpeed; } if (leftRight==true) { leftFootX=leftFootX+leftSpeed; } //arrow keys right - have the arrow keys move the right foot only when = is pressed if (key==CODED && rightUp==true && leftUp==false) { if (keyCode==LEFT) { rightLeft=true; } } else { rightLeft=false; } if (key==CODED&& rightUp==true && leftUp==false) { if (keyCode==RIGHT) { rightRight=true; } } else { rightRight=false; } if (rightLeft==true) { rightFootX=rightFootX-rightSpeed; } if (rightRight==true) { rightFootX=rightFootX+rightSpeed; } } void keyReleased() { leftUp=false; rightUp=false; } void gameOverUpdate() { if ( ( ped1X>=(leftFootX-15) && ped1X<=(leftFootX+15) && leftUp==false && leftFootY==350 ) || (ped1X>=(rightFootX-15) && ped1X<=(rightFootX+15) && rightUp==false && rightFootY==350 ) ) { gameOverScore=score; gameOver=true; } if ( ( ped2X>=(leftFootX-15) && ped2X<=(leftFootX+15) && leftUp==false && leftFootY==350 ) || (ped2X>=(rightFootX-15) && ped2X<=(rightFootX+15) && rightUp==false && rightFootY==350 ) ) { gameOverScore=score; gameOver=true; } if ( ( ped3X>=(leftFootX-15) && ped3X<=(leftFootX+15) && leftUp==false && leftFootY==350 ) || (ped3X>=(rightFootX-15) && ped3X<=(rightFootX+15) && rightUp==false && rightFootY==350 ) ) { gameOverScore=score; gameOver=true; } } //GAME OVER SCREEN - have the saucer in jail with some text around it void drawGameOver() { endSaucerX=width/2-10; endSaucerY=height/2; endLeftFootX = 100; endLeftFootY = 250; noStroke(); fill(128, 143, 137); rect(width/2, height/2, 400, 400); fill(169, 189, 172); ellipse(width/2, height/2, 400, 400); fill(209, 219, 189); ellipse(width/2, height/2, 200, 200); fill(128, 143, 137); triangle(0, 0, 0, 100, 150, 150); triangle(400, 400, 400, 300, 200, 200); triangle(150, 250, 0, 300, 50, 400); //DRAW THE LEGS stroke(62, 96, 111);//medblue strokeWeight(10); line(endSaucerX-40, endSaucerY+37, endSaucerX-65, 404); line(endSaucerX-65, 404, endLeftFootX, endLeftFootY+30); line(endSaucerX+40, endSaucerY+37, endSaucerX+65, 404); noStroke(); //leg connectors fill(145, 170, 157);//medgrn ellipse(endSaucerX-40, endSaucerY+37, 25, 25); ellipse(endSaucerX+40, endSaucerY+37, 25, 25); //scarf fill(255, 135, 130);//orngPink quad( endSaucerX-70, endSaucerY+32, endSaucerX+70, endSaucerY+32, endSaucerX+90, endSaucerY, endSaucerX-90, endSaucerY); ellipse(endSaucerX, endSaucerY+32, 140, 20); rect(endSaucerX+80, endSaucerY+50, 20, 100); rect(endSaucerX+72.5, endSaucerY+100, 5, 20); rect(endSaucerX+80, endSaucerY+100, 5, 20); rect(endSaucerX+87.5, endSaucerY+100, 5, 20); fill(62, 96, 111);//medblue ellipse(endSaucerX, endSaucerY, 200, 40); fill(252, 255, 245);//offwhite ellipse(endSaucerX, endSaucerY-15, 125, 20); rect(endSaucerX, endSaucerY-32, 125, 42, 12); ellipse (endSaucerX-65, endSaucerY+15, 35, 20); ellipse (endSaucerX+15, endSaucerY+15, 35, 20); fill(62, 96, 111);//medblue ellipse (endSaucerX-67, endSaucerY+19, 20, 12); ellipse (endSaucerX+13, endSaucerY+19, 20, 12); fill(252, 255, 245);//offwhite ellipse (endSaucerX-67, endSaucerY+20, 14, 8); ellipse (endSaucerX+13, endSaucerY+20, 14, 8); fill(25, 52, 65);//drkblue ellipse (endSaucerX-67, endSaucerY+20, 10, 5); ellipse (endSaucerX+13, endSaucerY+20, 10, 5); //prison hat stripes rect(endSaucerX, endSaucerY-27, 10, 45, 10); rect(endSaucerX+20, endSaucerY-27, 10, 45, 10); rect(endSaucerX+38, endSaucerY-29, 10, 43, 10); rect(endSaucerX+56, endSaucerY-31, 12, 41, 10); rect(endSaucerX-20, endSaucerY-27, 10, 45, 10); rect(endSaucerX-40, endSaucerY-29, 10, 43, 10); rect(endSaucerX-58, endSaucerY-31, 8, 41, 10); //bars fill(252, 255, 245); rect(85, 200, 20, 400); rect(235, 200, 20, 400); rect(385, 200, 20, 400); //foot fill(145, 170, 157);//medgrn ellipse(endLeftFootX, endLeftFootY+30, 25, 25); fill(25, 52, 65);//drkblue ellipse(endLeftFootX, endLeftFootY+20, 40, 20); rect(endLeftFootX, endLeftFootY+10, 40, 20); stroke(255, 135, 130);//orngPink strokeWeight(10); line(endLeftFootX-15, endLeftFootY+10, endLeftFootX-30, endLeftFootY+8); line(endLeftFootX+15, endLeftFootY+10, endLeftFootX+30, endLeftFootY+8); noStroke(); fill(252, 255, 245); rectMode(CORNER); rect(210, 250, 168, 40); rectMode(CENTER); //screen fill(255, 135, 130, 122.5); rect(width/2, height/2, 400, 400); //gameover text fill(25, 52, 65);//drkblue textSize(80); text("ARRESTED", 0, 100); textSize(8); text("oh god, what have you done...", 135, 110); textSize(25); text("Inmate " + gameOverScore, 227, 275); text("Press F for parole", 90, 350); }