Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/////////////////////////////////
//   Pyravliki - Drew Godden   //
//      Assignment #2          //
//  Student Number - 991469858 //
//      October 2, 2017        //
/////////////////////////////////

//Pyravliki means "rocket" in Greek (at least, according to Google Translate) :)

//Initialize harlowSolid as a font
PFont harlowSolid;

//Initialize variables that determine start button properties
int startX = 150;
int startY = 250;
int startW = 100;
int startH = 50;

float scanLinesY = -20;

//Initialize variables that determine player-controlled square properties
int playerX = width/2;
int playerY = height/2;
int playerW = 20;
int playerH = 20;

//Initialize variables for tracking score
int score = 0;
int millisOnGameStart = millis();

//Initialize variables that determine width and height for all missiles
int missileW = 5;
int missileH = 20;

//Initialize minimum and maximum speeds for all missiles
int missileMinSpd = 4;
int missileMaxSpd = 10;

//Initialize variables that determine minimum and maximum missile positions
int topMinDelay = -200;
int topMaxDelay = -400;
int bottomMinDelay = 600;
int bottomMaxDelay = 800;

//Initialize variables for missiles that move down, vertically
int missile0Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile0X = (int) random(0, width + 15);
int missile0Y = (int) random(topMinDelay, topMaxDelay);

int missile1Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile1X = (int) random(0, width + 15);
int missile1Y = (int) random(topMinDelay, topMaxDelay);

int missile2Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile2X = (int) random(0, width + 15);
int missile2Y = (int) random(topMinDelay, topMaxDelay);


//Initialize variables for missiles that move up, vertically
int missile3Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile3X = (int) random(0, width + 15);
int missile3Y = (int) random(bottomMinDelay, bottomMaxDelay);

int missile4Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile4X = (int) random(0, width + 15);
int missile4Y = (int) random(bottomMinDelay, bottomMaxDelay);

int missile5Spd = (int) random(missileMinSpd, missileMaxSpd);
int missile5X = (int) random(0, width + 15);
int missile5Y = (int) random(bottomMinDelay, bottomMaxDelay);

//Initialize state booleans
boolean startGame = false;
boolean gameOver = false;
boolean resetPhase = false;

void setup()
{
  //Load harlowSolid as the default font for this project
  harlowSolid = loadFont("HarlowSolid-48.vlw");
  textFont(harlowSolid);

  //Create the window's size: 400x400
  size(400, 400);
}

void draw()
{
  background(20);
  noStroke();
  fill(0, 255, 255);
  scanLines();

  //During the title screen, the "startGame" state is false
  if (startGame == false)
  {
    startScreen();
    startButton();
    millisOnGameStart = millis();
  }

  //If the game has started and the player has not yet lost, call the functions that are used for gameplay
  if (startGame == true && gameOver == false)
  {
    noCursor();
    drawPlayer();

    drawMissile0();
    drawMissile1();
    drawMissile2();
    drawMissile3();
    drawMissile4();
    drawMissile5();

    hitDetection();
    scoreCounter();
  }

  //If the player loses the game, bring them to the Game Over screen
  if (gameOver == true)
  {
    gameOverScreen();
    resetButton();
    resetMissiles();
  }

  //The reset phase ensures that all gameplay elements have been reset before play resumes
  if (resetPhase == true)
  {
    resetScore();
    resetPhase = false;
  }
}

//When the mouse is clicked in the specific position of a button while that button's state is active, change the state of the game according to the button's function
void mouseClicked()
{
  if (mouseX >= 150 && mouseX <= 250 && mouseY >=250 && mouseY <= 300 && startGame == false)
  {
    startGame = true;
  }

  if (mouseX >= 10 && mouseX <= 50 && mouseY >= 350 && mouseY <= 390 && gameOver == true)
  {
    gameOver = false;
    resetPhase = true;
    startGame = true;
  }
}

//Draw scan lines that move downwards gradually in the background
void scanLines()
{
  //Create scan line visual elements
  stroke(0, 255, 255, 5);
  strokeWeight(8);

  //Draw scan lines horizontally across the screen continuously until the bottom of the screen is reached
  for (int i = 0; i <= 400; i+=20)
  {
    line(0, scanLinesY + i, width, scanLinesY + i);
  }

  //Have scan lines move downwards gradually
  scanLinesY += 0.8;

  //If a scan line moves to a position greater than or equal to 20, a scan line has moved off of the screen. When this occurs, draw a new scan line at the top of the screen in order for the effect to be continuous
  if (scanLinesY >= 20)
  {
    scanLinesY = -20;
  }
}

//Draw the Start Screen visual elements
void startScreen()
{
  rect(80, 203, 220, 3);

  //The 'P' in "Pyravliki" appears larger than all other letters
  textSize(80);
  text("P", 90, 200);

  textSize(50);
  text("yravliki", 140, 200);

  //Added rectangles for visual flare
  rect(170, 148, 110, 3);
  rect(170, 153, 110, 3);
  rect(170, 158, 110, 3);
}

//Draw the start button visual
void startButton()
{
  rect(startX, startY, startW, startH, 5);
  fill(20);

  //Draw the "Start" text within the button
  textSize(28);
  text("Start", startX + 19, startY + 14, startW, startH);
  fill(0, 255, 255);
}

//Draw score counter text for when the game is running
void scoreCounter()
{
  fill(0, 255, 255, 180);
  textSize(40);

  //The player's score is the number of milliseconds that have passed since the game's start divided by 100.
  //The milliseconds passed since the game's start is calculated by subtracting the milliseconds that have passed since the applications start from the milliseconds that had passed until the player hit either the "Start" or "Reset" buttons
  score = (millis() - millisOnGameStart)/100;
  text(score, 20, 50);
}

//Draw the visual elements of the Game Over screen
void gameOverScreen()
{
  textSize(40);
  fill(0, 255, 255);
  text("Game Over", 108, 150);
  text("Final Score:", 91, 210);

  //Final score is displayed to the player
  textSize(48);
  text(score, 170, 280);
}

//Reset the missiles back to their original values so that they aren't on screen before the player has a chance to react when starting a new game
void resetMissiles()
{
  missile0Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile0X = (int) random(0, width);
  missile0Y = (int) random(topMinDelay, topMaxDelay);

  missile1Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile1X = (int) random(0, width);
  missile1Y = (int) random(topMinDelay, topMaxDelay);

  missile2Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile2X = (int) random(0, width);
  missile2Y = (int) random(topMinDelay, topMaxDelay);

  missile3Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile3X = (int) random(0, width);
  missile3Y = (int) random(bottomMinDelay, bottomMaxDelay);

  missile4Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile4X = (int) random(0, width);
  missile4Y = (int) random(bottomMinDelay, bottomMaxDelay);

  missile5Spd = (int) random(missileMinSpd, missileMaxSpd);
  missile5X = (int) random(0, width);
  missile5Y = (int) random(bottomMinDelay, bottomMaxDelay);
}

//Draw the visual elements of the reset button
void resetButton()
{
  //The cursor reappears so that the player can see the mouse while attempting to click the reset button
  cursor();
  rect(10, 350, 40, 40, 5);
  fill(20);
  triangle(15, 370, 40, 355, 40, 385);
}

//Reset the score back to zero so that score values do not carry between attempts
void resetScore()
{
  score = 0;
  millisOnGameStart = millis();
}

//Draw the player-controlled square
void drawPlayer()
{
  fill(0, 255, 255);
  rect(playerX, playerY, playerW, playerH);

  //The player-controlled square follows the mouse's position gradually at a rate divided by five
    playerX += (mouseX - playerX)/5;
    playerY += (mouseY - playerY)/5;
}

//Draw Missile 0 - a missile that travels downwards
void drawMissile0()
{
  fill(0, 255, 255);
  rect(missile0X, missile0Y, missileW, missileH);
  missile0Y += missile0Spd;

  //If Missile 0 leaves the screen, reset it so that it travels downwards again based on random parameters
  if (missile0Y > height + missileH)
  {
    missile0Spd = (int) random(missileMinSpd, missileMaxSpd);
    missile0Y = (int) random(topMinDelay, topMaxDelay);
    missile0X = (int) random(20, 380);
  }
}

//Draw Missile 1 - a missile that travels downwards
void drawMissile1()
{
  fill(0, 255, 255);
  rect(missile1X, missile1Y, missileW, missileH);
  missile1Y += missile1Spd;

  //If Missile 1 leaves the screen, reset it so that it travels downwards again based on random parameters
  if (missile1Y > height + missileH)
  {
    missile1Spd = (int) random(missileMinSpd + 1, missileMaxSpd + 1);
    missile1Y = (int) random(topMinDelay, topMaxDelay);
    missile1X = (int) random(20, 380);
  }
}

//Draw Missile 2 - a missile that travels downwards
void drawMissile2()
{
  fill(0, 255, 255);
  rect(missile2X, missile2Y, missileW, missileH);
  missile2Y += missile2Spd;

  //If Missile 2 leaves the screen, reset it so that it travels downwards again based on random parameters
  if (missile2Y > height + missileH)
  {
    missile2Spd = (int) random(missileMinSpd, missileMaxSpd);
    missile2Y = (int) random(topMinDelay, topMaxDelay);
    missile2X = (int) random(20, 380);
  }
}

//Draw Missile 3 - a missile that travels upwards
void drawMissile3()
{
  fill(0, 255, 255);
  rect(missile3X, missile3Y, missileW, missileH);
  missile3Y -= missile3Spd;

  //If Missile 3 leaves the screen, reset it so that it travels upwards again based on random parameters
  if (missile3Y < 0 - missileH)
  {
    missile3Spd = (int) random(missileMinSpd, missileMaxSpd);
    missile3Y = (int) random(bottomMinDelay, bottomMaxDelay);
    missile3X = (int) random(20, 380);
  }
}

//Draw Missile 4 - a missile that travels upwards
void drawMissile4()
{
  fill(0, 255, 255);
  rect(missile4X, missile4Y, missileW, missileH);
  missile4Y -= missile4Spd;

  //If Missile 4 leaves the screen, reset it so that it travels upwards again based on random parameters
  if (missile4Y < 0 - missileH)
  {
    missile4Spd = (int) random(missileMinSpd, missileMaxSpd);
    missile4Y = (int) random(bottomMinDelay, bottomMaxDelay);
    missile4X = (int) random(20, 380);
  }
}

//Draw Missile 5 - a missile that travels upwards
void drawMissile5()
{
  fill(0, 255, 255);
  rect(missile5X, missile5Y, missileW, missileH);
  missile5Y -= missile5Spd;

  //If Missile 5 leaves the screen, reset it so that it travels upwards again based on random parameters
  if (missile5Y < 0 - missileH)
  {
    missile5Spd = (int) random(missileMinSpd, missileMaxSpd);
    missile5Y = (int) random(bottomMinDelay, bottomMaxDelay);
    missile5X = (int) random(20, 380);
  }
}

//Test whether the boundary of any missile has entered the boundary of the player (collision)
//If a collision is detected at any point, the Game Over state is triggered
void hitDetection()
{
  if (missile0X + missileW >= playerX && 
    missile0X <= playerX + playerW && 
    missile0Y + missileH >= playerY && 
    missile0Y <= playerY + playerH)
  {
    gameOver = true;
  }

  if (missile1X + missileW >= playerX && 
    missile1X <= playerX + playerW && 
    missile1Y + missileH >= playerY && 
    missile1Y <= playerY + playerH)
  {
    gameOver = true;
  }

  if (missile2X + missileW >= playerX && 
    missile2X <= playerX + playerW && 
    missile2Y + missileH >= playerY && 
    missile2Y <= playerY + playerH)
  {
    gameOver = true;
  }

  if (missile3X + missileW >= playerX && 
    missile3X <= playerX + playerW && 
    missile3Y + missileH >= playerY && 
    missile3Y <= playerY + playerH)
  {
    gameOver = true;
  }

  if (missile4X + missileW >= playerX && 
    missile4X <= playerX + playerW && 
    missile4Y + missileH >= playerY && 
    missile4Y <= playerY + playerH)
  {
    gameOver = true;
  }

  if (missile5X + missileW >= playerX && 
    missile5X <= playerX + playerW && 
    missile5Y + missileH >= playerY && 
    missile5Y <= playerY + playerH)
  {
    gameOver = true;
  }
}