//starting x and y coordinates for star killer float starkillerX = 200; float starkillerY = 200; //spawns planets on righthand side off screen for smoother transition float planetX = 420; float planetY; //stores if the planet is currently onsecreen boolean planetAlive = false; //store random colour values for planets float colourR; float colourG; float colourB; //x and y co-ordinates for the ray float rayX; float rayY; //set the total length of the ray float rayLengthFront = 0; float rayLengthBack = 25; //if the ray is being fired or not boolean fire = false; //stroke weight of the ray float rayThickness = 8; //the number of planet respawns required for fighter to spawn float spawnFighter = 4; //current number of planet respawns float spawnFighterCount = 0; //current difficulty of the game float resistanceLevel = 1; //progress to the next level - number of planets destroyed float changeLevel = 0; //number of planets needed to increse difficulty float resistanceChange = 6; //details definig the fighter dimensions float fighterY = -15; float fighterX; //controls respawn fuction for fighter boolean fighterAlive = false; //current number of lives - starts with 3 float lives = 3; //details for lives bar float livesX = 20; float livesY = 30; //Controls the game over screen boolean gameOver = false; //records the number of planets shot int score = 0; void setup() { //set canvas size size(400, 400); //set rectangle and elipses modes rectMode(CENTER); ellipseMode(CENTER); //set frame rate frameRate(60); } void draw() { background(3, 9, 23); drawStars(); //update/dynamic statements updateResistance(); fighterState(); planetState(); respawnFighter(); respawnPlanet(); shootRay(); updateLives(); moveStarkiller(); ///Draw Objects/// drawStarkiller(); drawPlanet(); drawResistanceFighter(); //initiates the UI drawLives(); //seperate from other update functions has UI text output updateScore(); //is rendered last so that it covers the screen checkGameOver(); } /*User Defined Variables Below*/ /////////////////////////// /////DYNAMIC VARIABLES///// ////////////////////////// void getPlanetCoordiantes() { //random Y position between 60 and 340 so that star killer can always reach planetY = random(60, 340); } void getPlanetColours() { //get random colour for planet colourR = random(0, 255); colourG = random(0, 255); colourB = random(0, 255); } void getFighterCoordintates() { //chooses x coordinated between 40 and 360 so that its always in range of star killer fighterX = random(40, 340); } //////////////////////////// /////MOVEMENT + UPDATES///// //////////////////////////// void moveStarkiller() { //change position of star killer when keys are pressed //cant move while shooting / moving while shooting enabled user to hit a planet they had missed //stops starkiller from moving off of the canvas if (keyPressed && fire==false) { ////move up if (key == 'w' && starkillerY-40>height-height || key == 'W' && starkillerY-40>height-height ||keyCode == UP && starkillerY-40>height-height) { starkillerY = starkillerY - 2; } //move down else if (key == 's' && starkillerY+40<height || key == 'S' && starkillerY+40<height ||keyCode == DOWN && starkillerY+40<height ) { starkillerY = starkillerY + 2; } //move right else if (key == 'd' && starkillerX+40<width || key == 'D' && starkillerX+40<width ||keyCode == RIGHT && starkillerX+40<width ) { starkillerX = starkillerX + 2; } //move left else if (key == 'a' && starkillerX-40>width-width || key == 'A' && starkillerX-40>width-width ||keyCode == LEFT && starkillerX-40>width-width ) { starkillerX = starkillerX - 2; } else if (fire == true) { println("can't move while shooting"); } } } //shootRay Adapted from Shape Shooter by Carsten Booth - 2017 Gallery void shootRay() { if (keyPressed) { //press spacebar to fire ray if (key == ' ') //cause ray to fire fire = true; } //if shooting has been set to true, create a laser based on the code-block below if (fire == true) { //match ray to Starkiller firing hole stroke(193, 41, 46); //make ray slightly smaller than firing hole strokeWeight(rayThickness); //Draw ray line rayX = starkillerX+25; rayY = starkillerY; line(rayX+rayLengthBack, rayY, rayX+rayLengthFront, rayY); //Create movement of ray. rayLengthBack disconnects ray from starkiller rayLengthFront = rayLengthFront + 10; rayLengthBack = rayLengthBack + 10; } //once ray touches end of screen reset it if (rayLengthFront >= 400) { fire = false; } //once ray goes offscreen reset ray if (fire == false) { rayLengthFront =0; rayLengthBack = 25; } } //checks if the planet has been destroyed void planetState() { //checks if the ray has hit the planet if (rayX + rayLengthFront >= planetX-20 && rayY <= planetY+20 && rayY >= planetY-20) { //setting to false allows planet to be reset planetAlive = false; //stops firing fire = false; //increases the score score++; //increases the difficulty changeLevel++; } else if (planetX+20<0) { //checks if planet has moved offscreen planetAlive = false; } } void respawnPlanet() { //boolean stops planet from constantly resetting if (planetAlive == false) { //resets planet X bak to left hand side of screen planetX=380; //new random Y position getPlanetCoordiantes(); //new pandom colour getPlanetColours(); //increases count till next fighter spawnFighterCount++; //planet is back onscreen planetAlive = true; } } void respawnFighter() { //checks to see if fighter can be respawned if (fighterAlive == false && spawnFighterCount >= spawnFighter) { //resets planet X back to left hand side of screen fighterY=-15; //new random location for fighter getFighterCoordintates(); //resets planet death counter spawnFighterCount=0; //fighter is now back on screen fighterAlive = true; } } //checks if fighter if offscreen void fighterState() { if (fighterY>=height) { fighterAlive = false; } } void updateLives() { //checks if fighter has collided with star killer if (fighterY+30 >= starkillerY-40 && fighterY+30 <= starkillerY+40 && fighterX+15 <= starkillerX+40 && fighterX+15 >= starkillerX-40 && fighterAlive==true) { //fighter is no longer active fighterAlive=false; //decreased lives lives--; //transports fighter offscreen till next respawn fighterY = 500; } } void checkGameOver() { //checks if player has lost all lives if (lives==0) { gameOver = true; } //displays a game over screen if (gameOver == true) { noStroke(); fill(3, 9, 23); rect(200, 200, 400, 400); fill(193, 41, 46); textSize(24); text("YOU have FAILED the First Order", 10, 180); textSize(16); text("Click to try Again", 130, 230); } } //displays and keeps number of planets destroyed void updateScore() { textSize(16); text("Planets Destroyed:"+score, 230, 35); } //updates difficulty level void updateResistance() { //checks if difficulty should be incresed if (changeLevel>=resistanceChange) { resistanceLevel++; //resets next difficulty incrementor changeLevel=0; } } //resets game //checks if game is over to avoid resetting while game is in progress //sets core variables back to default void mouseClicked() { if (gameOver==true) { lives = 3; resistanceLevel = 1; gameOver=false; score = 0; starkillerX=200; starkillerY=200; } } ///////////////////// //////DRAWINGS/////// //////////////////// void drawStarkiller() { //clean minimalist aesthetic noStroke(); //starkiller main planet fill(167, 181, 186); ellipse(starkillerX, starkillerY, 80, 80); //starkiller firing strip fill(94, 105, 115); ellipse(starkillerX+25, starkillerY, 20, 20); rect(starkillerX+7.5, starkillerY, 55, 10); //firing hole fill(193, 41, 46); ellipse(starkillerX+25, starkillerY, 10, 10); //notch in starkiller fill(3, 9, 23); rect(starkillerX+37.5, starkillerY, 5, 10); } //Code inspired by Touch the Stars by Saneliso Dube - 2018 Interactive Drawing //twinkiling effect created by change in size from sin and cos void drawStars() { ellipse(60, 10, (cos(20+frameCount/20.04)*5), (cos(20+frameCount/20.04)*5)); ellipse(370, 30, (sin(20+frameCount/20.65)*5), (sin(20+frameCount/20.65)*5)); ellipse(160, 120, (cos(20+frameCount/20.65)*5), (cos(20+frameCount/20.65)*5)); ellipse(20, 280, (cos(20+frameCount/22.33)*5), (cos(20+frameCount/22.33)*5)); ellipse(200, 390, (sin(20+frameCount/22.33)*5), (sin(20+frameCount/22.33)*5)); ellipse(260, 230, (cos(20+frameCount/14.33)*5), (cos(20+frameCount/14.33)*5)); ellipse(140, 340, (cos(20+frameCount/14.33)*5), (cos(20+frameCount/14.33)*5)); ellipse(260, 360, (sin(20+frameCount/14.33)*5), (sin(20+frameCount/14.33)*5)); ellipse(240, 160, (sin(20+frameCount/23.65)*5), (sin(20+frameCount/23.65)*5)); ellipse(270, 40, (cos(20+frameCount/23.65)*5), (cos(20+frameCount/23.65)*5)); ellipse(200, 180, (sin(20+frameCount/18.65)*5), (sin(20+frameCount/18.65)*5)); ellipse(360, 80, (cos(20+frameCount/20.04)*5), (cos(20+frameCount/20.04)*5)); ellipse(300, 200, (sin(20+frameCount/20.65)*5), (sin(20+frameCount/20.65)*5)); } void drawPlanet() { noStroke(); //makes planet move to the left planetX=planetX-resistanceLevel; fill(colourR, colourG, colourB); ellipse(planetX, planetY, 40, 40); } void drawResistanceFighter() { noStroke(); fill(235, 235, 211); triangle(fighterX, fighterY, fighterX+10, fighterY, fighterX+5, fighterY+30); //makes fighter move down the screen at twice the speed of planets fighterY=fighterY+resistanceLevel*2; } void drawLives() { //UI Bar noStroke(); fill(193, 41, 46, 128); rect(200, livesY, 400, 20); //spacing between lives circles int spacing = 0; //lives that have been drawn already float livesDrawn = 0; //continuously checks the the number of lives available //while loop displays same circle a bit to the right while (livesDrawn<lives) { noStroke(); fill(167, 181, 186); ellipse(livesX+spacing, livesY, 10, 10); livesDrawn++; spacing = spacing + 15; } }