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