From my last about the midterm until now, time for submission I had to change a few things. The biggest change was how the game would operate. Initially the plan was to have the shooter in the middle of the screen and have a pointer that would change location based on the location of the mouse in the window, however I changed this to have the shooter moving from side to side as a not to have the user/player switch between the mouse and the keyboard for now the player can play the entirely from the keyboard.
Objective of the game
Try to get as many points as possible while keeping the number of cases as low as possible within 2 minutes/
Game Operation
The keys used for the operation of the game are:
1,2,3,m, space bar and the left and right arrow keys.
The space bar will shoot the fighting tool that is currently selected, this can seen in the shooter icon. Keys 1,2 and 3 can be used to switch between the fighting tools when you’re in “fight” mode. Keys 1,2 and 3 can be used to buy more fighting tools when you are in buy mode. You can switch modes by pressing the m button.
The difference between the fighting tool is number of points you get when you shoot the virus down and the speed of the fighting tool.
Speed of Handwash < Speed of face mask < Speed of face shield.
Shooting the virus down with a handwash will get you 1 points, shooting it down with facemask will get you 3 points and the shield will get you 5 points.
You can use the points to buy more tools. Buying more handwash will cost 1 point, face masks cost 2 points/mask, and face shields cost 3 points/shield.
The number of cases will go up if the virus goes below the window.
import processing.sound.*; //create new game Game game; // arrayList to store corona virus images ArrayList <CoronaVirus> coronaList; ArrayList <Fighter> activeFighters; //sound files SoundFile error; SoundFile scaryBg; SoundFile collision; SoundFile newCase; //image PImage virus; // misc vars String errorMessage = ""; void setup() { size(1280, 720); game = new Game(); //init game coronaList = new ArrayList<CoronaVirus>(0); activeFighters = new ArrayList<Fighter>(0); for (int i=0; i<4; i++) { coronaList.add(new CoronaVirus()); } virus = loadImage("virus.png"); error = new SoundFile(this, "error.mp3"); scaryBg = new SoundFile(this, "scaryBg.mp3"); collision = new SoundFile(this, "collide.mp3"); newCase = new SoundFile(this, "dead.mp3"); } void draw() { if (game.state==-2) { startScreen(); } else if (game.state==0 || game.state==1) { background(211, 211, 211); // clear background to avoid trails game.drawGameStats(); // show the game statistics game.shooter(); // draw the shooter displayError(); //display error messages displayCost(); // display cost of buying playBGMusic(); // play background music updateCorona(); // update the position and display the virus moveFighters(); //move the fighting tools on the screen checkCollisions(); //check for collision checkCoronaPosition(); // check for off screen viruses checkFighterPosition(); // check for off screen fighting tool newViruses(); // generate new viruses game.moveShooter(); // move the shooter game.updateTime(); // countdown time } else if (game.state==-1) { gameOver(); } }
import processing.sound.*; //create new game Game game; // arrayList to store corona virus images ArrayList <CoronaVirus> coronaList; ArrayList <Fighter> activeFighters; //sound files SoundFile error; SoundFile scaryBg; SoundFile collision; SoundFile newCase; //image PImage virus; // misc vars String errorMessage = ""; void setup() { size(1280, 720); game = new Game(); //init game coronaList = new ArrayList<CoronaVirus>(0); activeFighters = new ArrayList<Fighter>(0); for (int i=0; i<4; i++) { coronaList.add(new CoronaVirus()); } virus = loadImage("virus.png"); error = new SoundFile(this, "error.mp3"); scaryBg = new SoundFile(this, "scaryBg.mp3"); collision = new SoundFile(this, "collide.mp3"); newCase = new SoundFile(this, "dead.mp3"); } void draw() { if (game.state==-2) { startScreen(); } else if (game.state==0 || game.state==1) { background(211, 211, 211); // clear background to avoid trails game.drawGameStats(); // show the game statistics game.shooter(); // draw the shooter displayError(); //display error messages displayCost(); // display cost of buying playBGMusic(); // play background music updateCorona(); // update the position and display the virus moveFighters(); //move the fighting tools on the screen checkCollisions(); //check for collision checkCoronaPosition(); // check for off screen viruses checkFighterPosition(); // check for off screen fighting tool newViruses(); // generate new viruses game.moveShooter(); // move the shooter game.updateTime(); // countdown time } else if (game.state==-1) { gameOver(); } }
class Fighter { int type = -1; // 0 is handwash, 1 is mask, 2 is shield int speed = -1; int positionX = -1; int positionY = -1; PImage img; //methods //update position void updatePosition() { positionY -= speed; showFighter(); } void fighterImage() { //println(type); switch(type) { case 0: { // handwash img = loadImage("handwash.png"); speed = 3; break; } case 1: { // facemask img = loadImage("mask.png"); speed = 5; break; } case 2: { // faceshield img = loadImage("shield.png"); speed = 7; break; } } } void showFighter() { image(img, positionX, positionY, 30, 30); } }
class Game { // attributes int points = 0; int cases = 0; int state = -2; // 0->shooting | 1-> buying | -1 -> gameOver | -2-> game not started int fightingTool = 0; // 0-handwash, 1-mask, 2-shield int time = 120; PImage maskImg = loadImage("mask.png"); PImage handwashImg = loadImage("handwash.png"); PImage shieldImg = loadImage("shield.png"); int timeDisplay = 0; int shooterPosition = width/2; int shooterDirection = 0; float shooterSpeed = 2; // fighting tools // handwash attr int handwash = 20; // facemask attr int masks = 14; // faceshield attr int shields = 6; //methods void incrementPoints(int type) { if (type == 0) { points += 1; } else if (type == 1) { points += 3; } else if (type == 2) { points += 5; } } void incrementCases() { cases+=1; } void incrementMasks() { masks+=1; } void decrementMasks() { masks-=1; } void incrementShields() { shields+=1; } void decrementShields() { shields-=1; } void incrementHandwash() { handwash+=1; } void decrementHandwash() { handwash-=1; } void decrementFighters(){ switch(fightingTool){ case 0:{ decrementHandwash(); break; } case 1:{ decrementMasks(); break; } case 2:{ decrementShields(); break; } } } void changeState() { //println("changing state"); if (state==0) { state=1; } else if (state==1) { state=0; } } void updateTime() { if (time==0) { state=-1; } if (frameCount%60==0 && state!=-1) { time-=1; if (timeDisplay==0) { timeDisplay = 1; } else if (timeDisplay==1) { timeDisplay=0; } } if (points==0 && handwash==0 && masks==0 && shields==0){ state=-1; } } void drawGameStats() { textSize(12); color(0, 0, 0); imageMode(CENTER); pushStyle(); //draw handwash image(handwashImg, 70, 30, 30, 30); //150,30,30,30 text(handwash+" x", 25, 30);//110,30 // draw mask image(maskImg, 150, 30, 30, 30); text(masks+" x", 110, 30); // draw faceshield image(shieldImg, 230, 30, 30, 30); text(shields+" x", 190, 30); popStyle(); //display time pushStyle(); textSize(30); if (timeDisplay==1) { fill(0, 0, 0); text(time, width-100, height-30); } else if (timeDisplay==0) { fill(255, 255, 0); text(time, width-100, height-30); } popStyle(); // game mode pushStyle(); int rectWidth = 100; int rectHeight = 30; int cornerRadius = 10; noFill(); rect(width/2-rectWidth/2, 20, rectWidth, rectHeight, cornerRadius, cornerRadius, cornerRadius, cornerRadius); if (state==0) { pushStyle(); textAlign(CENTER); textSize(25); fill(255, 255, 0); text("FIGHT", width/2, 45); popStyle(); } else if (state==1) { //display buy pushStyle(); textAlign(CENTER); textSize(25); fill(0, 255, 0); text("BUY", width/2, 45); popStyle(); } else if (state==-1) { //display gameover pushStyle(); textAlign(CENTER); textSize(18); fill(255, 0, 0); text("Game Over", width/2, 43); popStyle(); } popStyle(); //display points pushStyle(); fill(0, 0, 0); textSize(25); text(points+" points", width-300, 45); text(cases+" cases", width-150, 45); popStyle(); } void drawFightingTool(int x, int y, int imgWidth, int imgHeight) { pushStyle(); imageMode(CENTER); if (fightingTool==0) { // draw handwash image(handwashImg, x, y, imgWidth, imgHeight); } else if (fightingTool == 1) { //draw mask image(maskImg, x, y, imgWidth, imgHeight); } else if (fightingTool == 2) { //draw shield image(shieldImg, x, y, imgWidth, imgHeight); } popStyle(); } void changeFightingTool(int tool) { fightingTool = tool; //println(fightingTool); } void shooter() { pushStyle(); fill(255, 255, 255); circle(shooterPosition, height, 100); game.drawFightingTool(shooterPosition, height-20, 40, 40); popStyle(); } void moveShooter() { if (shooterSpeed<=2) { shooterDirection=0; shooterSpeed=2.1; } if (shooterSpeed>2) { shooterPosition += shooterDirection*shooterSpeed; } } }
// to interact with game void keyPressed() { //println(keyCode); switch(keyCode) { case 32: { // space bar pressed need to create a new fighter add to list and reduce the number from game class if (game.fightingTool==0 && game.handwash>0) {//check number of handwash Fighter tempFighter = new Fighter(); tempFighter.type = game.fightingTool; tempFighter.positionX = game.shooterPosition; tempFighter.positionY = height-30; tempFighter.fighterImage(); activeFighters.add(tempFighter); game.decrementFighters(); } else if (game.fightingTool==1 && game.masks>0) {//check number of masks Fighter tempFighter = new Fighter(); tempFighter.type = game.fightingTool; tempFighter.positionX = game.shooterPosition; tempFighter.positionY = height-30; tempFighter.fighterImage(); activeFighters.add(tempFighter); game.decrementFighters(); } else if (game.fightingTool==2 && game.shields>0) {//check number of shields Fighter tempFighter = new Fighter(); tempFighter.type = game.fightingTool; tempFighter.positionX = game.shooterPosition; tempFighter.positionY = height-30; tempFighter.fighterImage(); activeFighters.add(tempFighter); game.decrementFighters(); } break; } case 37: { //move left game.shooterDirection = -1; if (game.shooterSpeed<10) { game.shooterSpeed*=1.1; } break; } case 39: { //move right game.shooterDirection = 1; if (game.shooterSpeed<10) { game.shooterSpeed*=1.1; } break; } case 49: { //handwash if (game.state==0) { game.changeFightingTool(0); } else if (game.state==1) { //buy more handwash if (game.points>=1) { //check if you have enough points game.points-=1; game.handwash+=1; } else { triggerErrorSound(); errorMessage = "Not Enough Points"; } } break; } case 50: { //facemask if (game.state==0) { game.changeFightingTool(1); } else if (game.state==1) { //buy more masks if (game.points>=2) { //check if you have enough points game.points-=2; game.masks+=1; } else { triggerErrorSound(); errorMessage = "Not Enough Points"; } } break; } case 51: { //faceshield if (game.state==0) { game.changeFightingTool(2); } else if (game.state==1) { //buy more handwash if (game.points>=3) { //check if you have enough points game.points-=3; game.shields+=1; } else { triggerErrorSound(); errorMessage = "Not Enough Points"; } } break; } case 77: { game.changeState(); break; } default: { triggerErrorSound(); errorMessage = "Invalid Control"; break; } } } void keyReleased() { if (keyCode==37 || keyCode==39) { game.shooterSpeed = 0.8; } } void flashMessage(String msg, color c, int size, int hOffset) { pushStyle(); fill(c); textSize(size); text(msg, 10, height-hOffset); popStyle(); } void triggerErrorSound() { if (!error.isPlaying()) { error.play(); } } void updateCorona() { for (int i=0; i<coronaList.size(); i++) { coronaList.get(i).updatePosition(height); coronaList.get(i).dispVirus(); } } void displayError() { if (error.isPlaying()) // // display error message { color errorColor = color(255, 0, 0); // color of error message flashMessage(errorMessage, errorColor, 15, 25); // display error message } } void displayCost() { if (game.state==1) { // display cost of buying more items String msg = "Handwash 1 Facemask 2 Faceshield 3"; // message string color c = color(53, 50, 56); // color of message flashMessage(msg, c, 18, 10); // display message } } void playBGMusic() { if (!scaryBg.isPlaying()) { // play bgMusic scaryBg.play(); } } void moveFighters() { //activeFighters for (int i=0; i<activeFighters.size(); i++) { activeFighters.get(i).updatePosition(); } } void checkCollisions() { //println("checking collision"); // two for loops. Check as virus against each fighter // if collision rem both fighter and virus from arraylist // increment point accordingly // if fighter above screen remove from array list // if virus below screen increment cases and rem from arraylist for (int i=0; i<coronaList.size(); i++) { println(coronaList.size()); CoronaVirus tC = coronaList.get(i); int size = tC.size; //println(size); for (int j=0; j<activeFighters.size(); j++) { Fighter tF = activeFighters.get(j); if (tF.positionX>tC.positionX && tF.positionX<tC.positionX+size) { // this mean the fighter is within the image if (tF.positionY>tC.positionY && tF.positionY<tC.positionY+size) { // this means the fighter is within the image coronaList.remove(i); activeFighters.remove(j); game.incrementPoints(tF.type); if (!collision.isPlaying()){ collision.play(); } game.points+=1; } } } } } void checkCoronaPosition(){ for(int i=0;i<coronaList.size();i++){ CoronaVirus tC = coronaList.get(i); if (tC.positionY>height){ game.cases+=1; if(!newCase.isPlaying()){ newCase.play(); } coronaList.remove(i); } } } void checkFighterPosition(){ for(int i=0;i<activeFighters.size();i++){ Fighter tF = activeFighters.get(i); if (tF.positionY<0){ activeFighters.remove(i); } } } void newViruses(){ if (frameCount%7==0 && frameCount%9==0 && frameCount%4==0){ coronaList.add(new CoronaVirus()); } } void gameOver(){ // this should display the previous game stats background(110,125,171); int size = 50; pushStyle(); textSize(24); int moveItemsHorizontal = 100; image(game.handwashImg,width/2-120+moveItemsHorizontal,height/2-240,size,size); text(game.handwash,width/2-80+moveItemsHorizontal,height/2-230); image(game.maskImg,width/2-120+moveItemsHorizontal,height/2-160,size,size); text(game.masks,width/2-80+moveItemsHorizontal,height/2-150); image(game.shieldImg,width/2-120+moveItemsHorizontal,height/2-80,size,size); text(game.masks,width/2-80+moveItemsHorizontal,height/2-70); textSize(32); textAlign(CENTER); text("Points "+game.points,width/2,height/2+30); text("Cases "+game.cases,width/2,height/2+80); popStyle(); restartButton(); } void restartButton(){ int buttonYPosition = 200; int rectWidth = 250; int rectHeight = 70; pushStyle(); rectMode(CENTER); fill(9,129,74); if (mouseX>width/2-rectWidth/2 && mouseX<width/2+rectWidth/2 && mouseY>height/2+buttonYPosition-rectHeight/2 && mouseY<height/2+buttonYPosition+rectHeight/2){ fill(9,160,74); if (mousePressed){ resetGame(); fill(9,100,74); } } rect(width/2,height/2+buttonYPosition,rectWidth,rectHeight,30); textAlign(CENTER); fill(0,0,0); textSize(40); text("RESTART",width/2,height/2+buttonYPosition+15); popStyle(); } void resetGame(){ game = new Game(); coronaList = new ArrayList<CoronaVirus>(0); activeFighters = new ArrayList<Fighter>(0); game.state = 0; for (int i=0; i<4; i++) { coronaList.add(new CoronaVirus()); } } void startScreen(){ background(110,125,171); image(virus,20,20,500,500); instructions(); startButton(); } void startButton(){ int moveButton = 85; int buttonYPosition = 200; int rectWidth = 250; int rectHeight = 70; pushStyle(); rectMode(CENTER); fill(9,129,74); if (mouseX>width/2-rectWidth/2 && mouseX<width/2+rectWidth/2 && mouseY>height/2+buttonYPosition-rectHeight/2+moveButton && mouseY<height/2+buttonYPosition+rectHeight/2+moveButton){ fill(9,160,74); if (mousePressed){ game.state=0; fill(9,100,74); } } rect(width/2,height/2+buttonYPosition+moveButton,rectWidth,rectHeight,30); textAlign(CENTER); fill(0,0,0); textSize(40); text("START",width/2,height/2+buttonYPosition+15+moveButton); popStyle(); } void instructions(){ // Title pushStyle(); String title = "Pandemic"; fill(178,103,0); stroke(178,103,0); strokeWeight(3); textAlign(CENTER); textSize(48); text(title,width/2,60); popStyle(); //objective heading pushStyle(); String objective = "Objective"; fill(0,0,0); textAlign(LEFT); textSize(32); text(objective,width/2,150); popStyle(); //objective text pushStyle(); String objectiveText = "Try to get your points as high as possible while keeping the number of the cases as low as possible"; fill(0,0,0); textAlign(LEFT); textSize(18); text(objectiveText,width/2+50,180, width/2-70,250); popStyle(); //instruction heading pushStyle(); String instruction = "Instructions"; fill(0,0,0); textAlign(LEFT); textSize(32); text(instruction,width/2,280); popStyle(); //objective text String line1 = "1. Move the shooter across the screen by using the left and right arrow keys.\n"; String line2 = "2. The icon shown in the shooter will be what you will be shooting down the virus with.\n"; String line3 = "3. Shooting the virus down with different tools will yield different points.\n"; String line4 = "4. The tools which yield greater points are also more expensive to acquire.\n"; String line5 = "5. You can choose the tool that you’re fighting with by pressing 1,2 or 3. 1 will select the handwash, 2 will select facemask and 3 will select a face shield.\n"; String line6 = "6. You can acquire more tools by pressing m to go into buying mode and then pressing 1,2 or 3 to acquire more tools. A hand wash will cost 1 point, a face mask will cost 2 points and a face shield will cost 3 points.\n"; String line7 = "7. Number of cases will increase is the virus goes below the screen."; pushStyle(); String instructionText = line1+line2+line3+line4+line5+line6+line7; fill(0,0,0); textAlign(LEFT); textSize(15); text(instructionText,width/2+50,300, width/2-70,700); popStyle(); }