/** * Olympic Hurdles * by Daniel Smith - October 3rd, 2017 * * You are an olympic track athlete. * This is the hurdles event. * Your goal is to clear as many hurldes as you can. * * CONTROLS: * You only need the SPACE BAR * Press SPACE to start * Press SPACE to jump * Press SPACE to restart when you fall * Good luck! :] * * Known bugs/issues: * -Sometimes the strokes of the hurdle glitch out, seemingly at random. * -Maybe it's just my computer, but sometimes the program starts to lag when the hurdle gets close to the runner. */ byte phase = 1; //The current state of the game (1 = Game hasn't started, 2 = In the middle of gameplay, 3 = The game ended) int roundNumber = 1, hurdlesCleared = 0; //Score/round# is printed to the console at the end. int bestCleared = 0; int playerCollisionSpanX1 = 80, playerCollisionSpanX2 = 120; //Only when the hurdle origin is in this <-span-> does it check if the player is jumping. The collision span doesn't change. int hurdleOriginX = 450; //The player should be jumping while this is in their collision <-span->. All of the hurdle's X coordinates are drawn relative to this. float hurdleSpeed = 0.5; //The speed at which the hurdle approaches. int millisAtJumpStart = 1251; //Used to end the jump animation, and prevent spamming. boolean isJumping = false; //Is the player jumping? /*The following variables are just to randomize the appearance of the player each round *There are 64 possible colour combinations (if my math is right...) *128 if you count skin colour */ int skinColour_R = 134, skinColour_G = 76, skinColour_B = 0; //You start off as Usain Bolt, who is black... int primaryColour_R = 255, primaryColour_G = 255, primaryColour_B = 0; //Wears yellow int secondaryColour_R = 0, secondaryColour_G = 255, secondaryColour_B = 0; //And green -- representing Jamaica. void setup(){ size(400, 400); print("**WELCOME TO THE 2017 Sheridan BaGD Games**\nToday's event: Track & Field (Hurdles)! Let's get right into it!\n"); } /*My main draw() loop does the following: * Draw the background (Which I decided will just be a grid with the olympic symbol) * Call the drawPlayer() func * Call the drawHurdle() func if in the right phase(2) */ void draw(){ //White background fill(255); rect(0, 0, width, height); /*Draw a grid*/ stroke(0, 255, 0); //Vertical for(int x = 20; x < width; x+=20){ line(x, 0, x, height); } //Horizontal for(int y = 20; y < height; y+=20){ line(0, y, width, y); } /*Draw Olympic Symbol*/ strokeWeight(7); noFill(); stroke(0, 0, 255); //Blue ellipse(125, 150, 60, 60); stroke(0); //Black ellipse(200, 150, 60, 60); stroke(255, 0, 0); //Red ellipse(275, 150, 60, 60); stroke(255, 255, 0); //Yellow ellipse(162.5, 180, 60, 60); stroke(0, 255, 0); //Green ellipse(237.5, 180, 60, 60); strokeWeight(1); stroke(0); //The floor/track fill(222, 94, 0); rect(0, 350, width, 51); /*Hurdles only spawn while gameplay is in prgross*/ if(phase == 2){ drawPlayer(); drawHurdle(); } else{ drawPlayer(); } } //END OF draw() void drawPlayer(){ if(phase == 1){ //The game hasn't started yet /*READY STANCE*/ //Head fill(skinColour_R, skinColour_G, skinColour_B); ellipse(150, 280, 30, 40); //Torso fill(primaryColour_R, primaryColour_G, primaryColour_B); quad(80, 310, 130, 285, 130, 315, 80, 350); //Pants fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); ellipse(80, 340, 30, 60); //Leg fill(skinColour_R, skinColour_G, skinColour_B); ellipse(60, 370, 60, 20); //Shoe fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); ellipse(30, 380, 20, 30); //Arm fill(skinColour_R, skinColour_G, skinColour_B); ellipse(130, 300, 23, 30); //Shoulder rect(125, 340, 10, 35); //Forearm ellipse(130, 330, 20, 40); //Bicep ellipse(130, 380, 14, 14); //Hand } else if(phase == 2){ //You're in the middle of the game if(isJumping){ /*JUMPING STANCE*/ //Left Arm fill(skinColour_R, skinColour_G, skinColour_B); quad(142, 210, 148, 210, 110, 260, 110, 240); //Forearm ellipse(145, 210, 12, 12); //Hand //Torso fill(primaryColour_R, primaryColour_G, primaryColour_B); ellipse(100, 250, 40, 80); //Head fill(skinColour_R, skinColour_G, skinColour_B); ellipse(100, 210, 30, 40); //Other Arm quad(40, 240, 60, 240, 40, 270, 30, 270); //Forearm ellipse(80, 240, 20, 20); //Shoulder ellipse(60, 240, 40, 20); //Bicep //Legs quad(20, 270, 80, 260, 85, 285, 20, 280); //Back quad(120, 260, 180, 275, 180, 285, 115, 285); //Front //Pants fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); quad(80, 260, 120, 260, 115, 290, 85, 290); //Shoes ellipse(20, 285, 15, 30); //Back ellipse(180, 275, 15, 30); //Front if(millis() - millisAtJumpStart > 750){ //You stay in the air for 3/4 of a second. isJumping = false; } } else { /*RUNNING STANCE*/ //Left Arm fill(skinColour_R, skinColour_G, skinColour_B); quad(132, 250, 138, 250, 110, 310, 110, 290); //Forearm ellipse(135, 250, 12, 12); //Hand //Torso fill(primaryColour_R, primaryColour_G, primaryColour_B); //Yellow ellipse(100, 280, 40, 80); //Head fill(skinColour_R, skinColour_G, skinColour_B); ellipse(100, 240, 30, 40); //Pants fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); quad(80, 290, 120, 290, 110, 320, 70, 320); quad(120, 290, 140, 300, 120, 320, 110, 320); //Legs fill(skinColour_R, skinColour_G, skinColour_B); quad(75, 320, 100, 320, 70, 380, 60, 380); //Straight leg triangle(140, 300, 145, 320, 120, 320); //Bent leg: Knee quad(120, 320, 145, 320, 110, 350, 100, 350); //Bent leg: Shin //Shoes fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); ellipse(70, 380, 20, 10); //Straight leg shoe ellipse(120, 350, 40, 10); //Bent leg shoe //Right Arm fill(skinColour_R, skinColour_G, skinColour_B); quad(40, 270, 60, 270, 60, 310, 50, 310); //Forearm ellipse(55, 310, 14, 14); //Hand ellipse(80, 270, 20, 20); //Shoulder ellipse(60, 270, 40, 20); //Bicep } } else { //The game ended /*FALL STANCE*/ //Torso fill(primaryColour_R, primaryColour_G, primaryColour_B); //Yellow ellipse(120, 365, 80, 30); //Legs fill(skinColour_R, skinColour_G, skinColour_B); quad(20, 360, 70, 360, 70, 380, 20, 370); //Back rect(80, 320, 15, 30); //Front thigh rect(80, 320, 30, 10); //Front calf //Pants fill(secondaryColour_R, secondaryColour_G, secondaryColour_B); rect(70, 355, 30, 25); quad(75, 335, 100, 350, 100, 380, 75, 380); //Shoes ellipse(20, 370, 12, 25); //Back ellipse(110, 330, 10, 20); //Front //Head fill(skinColour_R, skinColour_G, skinColour_B); ellipse(170, 360, 30, 40); //Arm ellipse(150, 370, 30, 25); //Shoulder ellipse(120, 370, 40, 20); //Arm ellipse(100, 370, 14, 14); //Hand } //End of outer IF } void drawHurdle(){ hurdleOriginX -= hurdleSpeed; //Supports fill(175); quad(hurdleOriginX-30, 297, hurdleOriginX-20, 302, hurdleOriginX-20, 360, hurdleOriginX-30, 360); //Left rect(hurdleOriginX-20, 355, 10, 5); quad(hurdleOriginX+20, 310, hurdleOriginX+30, 315, hurdleOriginX+30, 380, hurdleOriginX+20, 380); //Right rect(hurdleOriginX+30, 375, 10, 5); //Bar fill(0, 172, 228); //Blu-ish quad(hurdleOriginX-40, 300, hurdleOriginX+40, 320, hurdleOriginX+40, 345, hurdleOriginX-40, 320); if(hurdleOriginX > playerCollisionSpanX1 && hurdleOriginX < playerCollisionSpanX2){ //Hurdle is within the collision span if(isJumping){ //println("Success"); } else{ //println("HIT"); //For testing phase = 3; //End the game /* Print player's score to the console * Don't spell "hurdles" as plural if you only cleared a single hurdle. */ if(hurdlesCleared == 1){ // println("Round " + roundNumber + ": You cleared <" + hurdlesCleared + "> hurdle"); } else{ println("Round " + roundNumber + ": You cleared <" + hurdlesCleared + "> hurdles"); } /* Check if player beat their old score * If so, acknowledge it. */ if(hurdlesCleared > bestCleared){ println("''FOLKS, IT LOOKS LIKE WE HAVE A NEW RECORD!!!''"); bestCleared = hurdlesCleared; } hurdleOriginX = 450; //Reset the hurdle hurdlesCleared = 0; //Reset the score roundNumber++; } } if(hurdleOriginX == 0){ //If the hurdle is going offscreen, hurdleOriginX = 450; //Send it back to the opposite side. hurdleSpeed = random(0.5, 2); //Randomly pick a speed for the next hurdle. hurdlesCleared++; } } void keyPressed(){ if(key == ' '){ //SPACE BAR if(phase == 1){ phase = 2; //Start the game } else if(phase == 2){ /* 0.5 seconds of landing lag. Prevents player from simply holding down the space bar - immediately jumping again after they land. * From testing however, even if you could spam jump, it doesn't always mean you'll pass the hurdle, because you'll land for at least one frame. */ if(millis() - millisAtJumpStart > 1250){ isJumping = true; millisAtJumpStart = millis(); } } else{ //phase 3 /*Selecting a new skin complexion*/ if((int)random(0, 2) == 0){ //Black skinColour_R = 134; skinColour_G = 76; skinColour_B = 0; } else{ //White skinColour_R = 255; skinColour_G = 224; skinColour_B = 186; } /*Selecting a new primary colour (for the shirt)*/ //Red if((int)random(0, 2) == 0){ //Some red primaryColour_R = 255; } else{ //No red primaryColour_R = 0; } //Green if((int)random(0, 2) == 0){ //Some green primaryColour_G = 255; } else{ //No green primaryColour_G = 0; } //Blue if((int)random(0, 2) == 0){ //Some blue primaryColour_B = 255; } else{ //No blue primaryColour_B = 0; } /*Selecting a new secondary colour (for the shorts and shoes)*/ //Red if((int)random(0, 2) == 0){ //Some red secondaryColour_R = 255; } else{ //No red secondaryColour_R = 0; } //Green if((int)random(0, 2) == 0){ //Some green secondaryColour_G = 255; } else{ //No green secondaryColour_G = 0; } //Blue if((int)random(0, 2) == 0){ //Some blue secondaryColour_B = 255; } else{ //No blue secondaryColour_B = 0; } phase = 1; //Restart the game } } }