Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/**
 * 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
    }
  }
}