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