/* Program by Daniel Fraser, 991502630. Inspired by Space Invaders. Number of aliens reduced to 9. Shapes simplified Using the tank, you must defeat the 9 enemy aliens. Use A & D to move left and right. Press space to fire a projectile. If the aliens touch the bottom of the screen, you lose the game and must refresh */ //Player control and projectile booleans boolean left = false; boolean right = false; boolean space = false; boolean proj = false; //Alien movement booleans boolean alienLeft = false; boolean alienRight = false; boolean alienDown = false; //"is-active" booleans for aliens boolean act1 = true; boolean act2 = true; boolean act3 = true; boolean act4 = true; boolean act5 = true; boolean act6 = true; boolean act7 = true; boolean act8 = true; boolean act9 = true; //Won/lost game state booleans boolean won = false; boolean lost = false; //floats for all CENTER positions float playerX; float playerY; float projX; float projY; float ax1, ay1; float ax2, ay2; float ax3, ay3; float ax4, ay4; float ax5, ay5; float ax6, ay6; float ax7, ay7; float ax8, ay8; float ax9, ay9; //Score counter, used in tandem with won boolean int score; //Initializes all starting positions for players and aliens. Also initializes score and initial alien movement void setup() { size(400, 400); playerX = width/2; playerY = 370; ax1 = width/2 - 40; ax2 = width/2; ax3 = width/2 + 40; ax4 = ax1; ax5 = ax2; ax6 = ax3; ax7 = ax1; ax8 = ax2; ax9 = ax3; ay1 = 50; ay2 = ay1; ay3 = ay1; ay4 = 90; ay5 = ay4; ay6 = ay4; ay7 = 130; ay8 = ay7; ay9 = ay7; alienRight = true; score = 0; } void draw() { background(0); playerPos(); rendBackground(); rendPlayer(); //Continue gameplay if the game is neither won nor lost if (!won && !lost) { moveAliens(); if (space) shootProjectile(); if (proj) { projY-=10; rendProj(); } //If the score limit is reached, play "win" function on next frame. If you've lost, play the "lose" function checkAllHits(); } else if (won) { winGame(); } else if (lost) { loseGame(); } drawAllAliens(); } //A&D to move left & right. Spacebar to shoot projectile. Will only function if gameplay is in progress void keyPressed() { if (key == 'a' && (!won && !lost)) left = true; else if (key == 'd' && (!won && !lost)) right = true; else if (key == ' ' && proj == false && (!won && !lost)) space = true; } void keyReleased() { if (key == 'a') left = false; //stop going left else if (key == 'd') right = false; //stop going right else if (key == ' ') space = false; //stop shooting } //Move the player if certain keys have been pressed void playerPos() { if (left && playerX>15) playerX-=2; else if (right && playerX<width-15) playerX+=2; } //Render the tank player in the new position. If the game has been won, the player will glow random colours. If lost, glows dark reds void rendPlayer() { rectMode(CENTER); noStroke(); if (won) fill(random(255), random(255), random(255)); else if (lost) fill(random(200), 0, 0); else fill (255); rect(playerX, playerY, 30, 30); rect(playerX, playerY-10, 15, 40); } //Renders the gradient and stars using loops void rendBackground() { noStroke(); rectMode(CENTER); for (int i = 0; i<height; i++) { fill (0, 0, i); rect(width/2, i+100, width, 1); } for (int i = 50; i<width; i+=50) { for (int j = 0; j<height/1.5; j+=50) { fill(random(255)); rectMode(CENTER); rect(i, j, 2, 2); } } } //Updates the projectile's position to the start and calls the renderer function void shootProjectile() { proj = true; projX = playerX; projY = playerY-30; rendProj(); } //Renders the projectile. If it goes offscreen, turn off render boolean (proj) void rendProj() { rectMode(CENTER); noStroke(); fill(255); rect(projX, projY, 10, 20); if (projY<0) proj = false; } //Draws each "active" alien void drawAllAliens() { if (act1 == true) drawAlien(ax1, ay1, 0); if (act2 == true) drawAlien(ax2, ay2, 0); if (act3 == true) drawAlien(ax3, ay3, 0); if (act4 == true) drawAlien(ax4, ay4, 1); if (act5 == true) drawAlien(ax5, ay5, 1); if (act6 == true) drawAlien(ax6, ay6, 1); if (act7 == true) drawAlien(ax7, ay7, 2); if (act8 == true) drawAlien(ax8, ay8, 2); if (act9 == true) drawAlien(ax9, ay9, 2); } //Draws an alien based on the given coordinates and "type": Ellipse, rectangle, and triangle. Makes use of switch for each type void drawAlien(float x, float y, int type) { rectMode(CENTER); fill(255); noStroke(); switch(type) { case 0: ellipse(x, y, 20, 20); noFill(); stroke(0, 255, 0); break; case 1: rectMode(CENTER); rect(x, y, 20, 20); break; case 2: triangle(x-10, y+5, x, y-15, x+10, y+5); noFill(); stroke(0, 255, 0); break; } } /*Moves all aliens based on current direction. Initially moves left. Goes down a bit when it hits the edge then goes opposite direction. If any alien makes it to the bottom of the screen (while active), the "lost" boolean is set and the game is lost. Game updates to "lost" state on next draw */ void moveAliens() { if (alienRight) { ax1++; ax2++; ax3++; ax4++; ax5++; ax6++; ax7++; ax8++; ax9++; if (ax3>width) { alienRight=false; alienDown=true; } } else if (alienLeft) { ax1--; ax2--; ax3--; ax4--; ax5--; ax6--; ax7--; ax8--; ax9--; if (ax1<0) { alienLeft=false; alienDown=true; } } else if (alienDown) { ay1+=5*10; ay2+=5*10; ay3+=5*10; ay4+=5*10; ay5+=5*10; ay6+=5*10; ay7+=5*10; ay8+=5*10; ay9+=5*10; if ((ay1>380 && (act1 || act2 || act3)) || (ay4>380 && (act4 || act5 || act6)) || (ay7>380 && (act7 || act8 || act9))) lost = true; if (ax1<0) alienRight = true; else if (ax3>width) alienLeft = true; } } /*Checks each alien for a collision with the projectile. rectRectIntersect taken from https://www.openprocessing.org/sketch/8005# If an alien is shot, it is made inactive, the projectile is disabled, and the score is increased. If the score becomes greater than 9 (i.e all aliens are defeated), the game state is changed to "won" on next draw */ void checkAllHits() { if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax1-10, ay1-10, ax1+10, ay1+10) == true && act1 == true) { act1 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax2-10, ay2-10, ax2+10, ay2+10) == true && act2 == true) { act2 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax3-10, ay3-10, ax3+10, ay3+10) == true && act3 == true) { act3 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax4-10, ay4-10, ax4+10, ay4+10) == true && act4 == true) { act4= false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax5-10, ay5-10, ax5+10, ay5+10) == true && act5 == true) { act5 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax6-10, ay6-10, ax6+10, ay6+10) == true && act6 == true) { act6 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax7-10, ay7-10, ax7+10, ay7+10) == true && act7 == true) { act7 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax8-10, ay8-10, ax8+10, ay8+10) == true && act8 == true) { act8 = false; proj = false; projY = height+20; score++; } if (rectRectIntersect(projX-5, projY-10, projX+5, projY+10, ax9-10, ay9-10, ax9+10, ay9+10) == true && act9 == true) { act9 = false; proj = false; projY = height+20; score++; } if (score>=9) won = true; } //Lose game state. Text is displayed to the screen. Both the text and player are now rendered in a dark red glow void loseGame() { fill(random(200), 0, 0); textSize(82); text("YOU LOSE", 0, height/2); } //Win game state. Text is displayed to the screen. Both the text and player are now rendered in a random glow void winGame() { fill(random(255), random(255), random(255)); textSize(94); text("YOU WIN", 0, height/2); } //Taken from https://www.openprocessing.org/sketch/8005# boolean rectRectIntersect(float left, float top, float right, float bottom, float otherLeft, float otherTop, float otherRight, float otherBottom) { return !(left > otherRight || right < otherLeft || top > otherBottom || bottom < otherTop); }