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();
}








