Final Project

This program is a Covid-19 version of whack-a-mole called put-on-a-mask. The idea was inspired by an online game that my friends and I played during the pandemic called Covidopoly, a Covid-19 version of the board game Monopoly. Like this game, I wanted to make some light out of this dark situation we are in a make a fun, easy, time-passing game that will (hopefully) keep making you play until the pandemic is over.
To play is simple: the player must put masks on the viruses as fast as they can. There will be a total of 4 viruses on the screen at all times and once a virus is successfully clicked (accompanied by a “pop” sound), it will regenerate in a random color to a random position. If the player misses or takes too long to click a virus, they will get a strike– an accumulation of 3 strikes will end the game. The virus that was on the screen for too long will disappear on its own and regenerate in a new random color and position. Every 20 points, the player will level up which makes the time it takes a virus to disappear on its own shorter.
If I had more time, I would like to add more complex elements to the game like making the viruses move around, add more viruses to the screen after a certain amount of levels, or add more clickable elements for bonus points or strike reductions.

sketch
var covidviruses = [];
var covidImageLinks = ["https://i.imgur.com/iUnzt1x.png", 
                        "https://i.imgur.com/V9cdbDy.png", 
                        "https://i.imgur.com/OjUptCF.png", 
                        "https://i.imgur.com/heDuTxd.png",
                        "https://i.imgur.com/PoNLrQ1.png",
                        "https://i.imgur.com/oIF3cp7.png",
                        "https://i.imgur.com/jc8muyt.png",
                        "https://i.imgur.com/X6MPvtK.png"]
var mask;
var coronavirusSound;
var popSound;
var clickSound;
var covidX = [150, 200, 300, 350];
var covidY = [300, 150, 200, 250];
var strike = 0;
// array of virus objects
var virus = [];
var page = 1;
var score = 0;
var ageIncrease = 1;
var maxScore = 0;
var gameLevel = 1;
var angle = 20;

function preload() {
    // load pictures (different color viruses)
    for(var i = 0; i < covidImageLinks.length; i ++) {
        covidviruses[i] = loadImage(covidImageLinks[i]);
    }
    mask = loadImage("https://i.imgur.com/DdBChjv.png");
    coronavirusSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/coronavirus.wav");
    popSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/pop.wav");
    clickSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/click.wav")
}

function setup() {
    createCanvas(480, 480);
    useSound();
    // create array of objects of 4 starter viruses (location, size, color, age)
    for(var i = 0; i < 4; i ++) {
        virus[i] = new Object();
        virus[i].x = covidX[i];
        virus[i].y = covidY[i];
        virus[i].color = floor(random(0, 8));
        virus[i].size = 90;
        virus[i].age = 0;
     }
     frameRate(40);
     noStroke();
}

function soundSetup() { 
    coronavirusSound.setVolume(.5);
    popSound.setVolume(.5);
    clickSound.setVolume(.5);
}


function draw() {
    // title page 
    if(page == 1) {
        cursor();
        createTitlePage();
    }
    // game
    if(page == 2) {
        noCursor();
        background("#BFEDFF");
        // draw 4 viruses to begin
        for(var i = 0; i < 4; i ++) {
            image(covidviruses[virus[i].color], virus[i].x, virus[i].y, virus[i].size, virus[i].size);
            // add virus age
            virus[i].age += ageIncrease;
            // if virus has been unclicked for 200 frames --> strike + new virus replacement
            if(virus[i].age == 200) {
                makeNewVirus(i);
                strike += 1;
            }
        }   
        // 3 misses --> game over
        if(strike == 3) {
        // go to end page
            page = 3;
        }

        // mask on cursor
        imageMode(CENTER);
        image(mask, mouseX, mouseY, 90, 90);
        
        updateScore();

        // level up every 20 points and increase aging rate (so virus disappears faster)
        if(score%20 == 0 & score > maxScore) {
            ageIncrease += 1;
            maxScore = score;
            gameLevel += 1;
        }
    }

    // end page
    if(page == 3) {
        cursor();
        createEndPage();
    }

    // help page
    if(page == 4) {
        cursor();
        createHelpPage();
    }
}

function mousePressed() {
    // thresholds of a success click for viruses
    var d = [];
    for(var i = 0; i < 4; i ++) {
        d[i] = dist(mouseX, mouseY, virus[i].x, virus[i].y);
    }

    // title page
    if(page == 1) {
        // play  button --> reset everything
        if(mouseX > 190 & mouseX < 290 && mouseY > 305 && mouseY < 355) {           
            // go to game page
            clickSound.play();
            strike = 0;
            score = 0;
            ageIncrease = 1;
            maxScore = 20;
            gameLevel = 1;
            page = 2;
        }
        if(mouseX > 165 & mouseX < 315 && mouseY > 135 && mouseY < 285){
            // sound effect
            coronavirusSound.play();
        }
        if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
            clickSound.play();
            page = 4;
        }
    }

    // game page
    else if(page == 2) {
        // if clicks are successes for any 4 of the viruses --> make pop sound, score increase by 1, new virus replacement
        if (d[0] < 45) {
            popSound.play();
            makeNewVirus(0);
            score += 1;
        }
        else if (d[1] < 45) {
            popSound.play();
            makeNewVirus(1);
            score += 1;
        }
        else if(d[2] < 45) {
            popSound.play();
            makeNewVirus(2);
            score += 1;
        }
        else if(d[3] < 45) {
            popSound.play();
            makeNewVirus(3);
            score += 1;
        }
        else { // a miss
            strike += 1;
        }
    }

    // end page
    else if(page == 3) {
        // play again button --> reset everything
        if(mouseX > 125 & mouseX < 355 && mouseY > 290 && mouseY < 370) {
            clickSound.play();
            strike = 0;
            score = 0;
            ageIncrease = 1;
            maxScore = 20;
            gameLevel = 1;
            page = 2;
        }
        // go back to main page
        if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
            clickSound.play();
            page = 1;
        }
    }

    // help page
    else if(page == 4) {
        // play  button --> reset everything
        if(mouseX > 190 & mouseX < 290 && mouseY > 305 && mouseY < 355) {           
            // game page
            clickSound.play();
            strike = 0;
            score = 0;
            ageIncrease = 1;
            maxScore = 20;
            gameLevel = 1;
            page = 2;
        }
        // return to main page
        if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
            clickSound.play();
            page = 1;
        }
    }
        
}

// replace clicked viruses or missed viruses 
function makeNewVirus(index) {
    covidX[index] = random(90, 390);
    covidY[index] = random(135, 390);

    virus[index].x = covidX[index];
    virus[index].y = covidY[index];
    virus[index].color = floor(random(0, 8));
    virus[index].size = 90;
    virus[index].age = 0;

}

// title page (page 0)
    // button to play
    // button to go to help page
    // interactive graphic (makes sound)
function createTitlePage() {
    background("#D7C9FF");
    // play button
    if(mouseX > 190 & mouseX < 290 && mouseY > 305 && mouseY < 355) {     
        fill("pink");
    }
    else{
        fill("white");
    }

    rectMode(CENTER);
    rect(width/2, 330, 100, 50);
    
    // help button
    if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
        fill("pink");
    }
    else{
        fill("white");
    }
    rect(width/2, 390, 200, 50);

    textSize(30);
    textAlign(CENTER);

    // text, box labels
    fill("black");
    text("put on a mask!", width/2, height/4);
    text("play!", width/2, 340);
    text("how to play", width/2, 400);
    textSize(10);
    text("click on me!", width/2, 280);

    // animation using transformation
    // viruses moving around the borders
    imageMode(CORNER);
    virusBorder();

    // sound effect virus
    // mouse hover --> rotate
    push();
    translate(240, 210);
    if(mouseX > 165 & mouseX < 315 && mouseY > 135 && mouseY < 285){
        rotate(radians(angle));
    }
    imageMode(CENTER);
    image(covidviruses[6], 0, 0, 150, 150);
    pop();
    angle += 5;
    
}

// page 3
function createEndPage() {
    background("#D7C9FF");    
    
    // play button
    if(mouseX > 125 & mouseX < 355 && mouseY > 290 && mouseY < 370) {
        fill("pink");
    }
    else {
        fill("white");
    }
    rectMode(CENTER);
    rect(width/2, 330, 200, 50);
    
    // return to main page
    if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
        fill("pink");
    }
    else {
        fill("white");
    }
    rect(width/2, 390, 200, 50);

    // text, button labels
    fill("black");
    textSize(30);
    textAlign(CENTER);
    text("game over!", width/2, 150);
    textSize(20);
    text("Score: " + str(score), width/2, 200);
    text("Highest Level: " + str(gameLevel), width/2, 230);
    textSize(30);
    text("play again!", width/2, 340);
    text("main page", width/2, 400);

    imageMode(CORNER);
    virusBorder();
}

// keep track of score, strikes, level on game page
function updateScore() {
    // print current score, strikes, and level at top
    textSize(20);
    textAlign(CENTER);
    text("Score: " + str(score), width/2, 50);
    text("Strikes: " + str(strike), width/2, 70);
    text("Level " + str(gameLevel), width/2, 90);
}

// border pattern
function virusBorder() {
    for(var i = 0; i < width; i += 40) {
        image(covidviruses[floor(random(0, 8))], i, 0, 40, 40);
        image(covidviruses[floor(random(0, 8))], i, 440, 40, 40);
        image(covidviruses[floor(random(0, 8))], 0, i, 40, 40);
        image(covidviruses[floor(random(0, 8))], 440, i, 40, 40);
    }
}

// help page, page 4
function createHelpPage() {
    background("#D7C9FF");
    rectMode(CENTER);

    // play button
    if(mouseX > 190 & mouseX < 290 && mouseY > 305 && mouseY < 355) {     
        fill("pink");
    }
    else{
        fill("white");
    }
    rect(width/2, 330, 100, 50);
    
    // return to home button
    if(mouseX > 140 & mouseX < 340 && mouseY > 365 && mouseY < 415) {
        fill("pink");
    }
    else{
        fill("white");
    }
    rect(width/2, 390, 200, 50);

    // text, labels
    fill("black");
    textSize(30);
    textAlign(CENTER);
    // page button
    text("play!", width/2, 340);
    // help button
    text("main page", width/2, 400);

    text("how to play:", width/2, 120);
    textSize(15);
    text("like whack-a-mole but covid edition! click on the viruses as they appear and cover them with masks! make sure to be fast because the higher the score, the faster they disappear! the game ends after you get 3 misses!", 
        width/2, 300, 300, 300);
    
    imageMode(CORNER);
    virusBorder();
}

Leave a Reply