Week 14: Final Project: Trash Removal

My Final Project Modified for WordPress

//Chuong Truong;
//cbtruong;
//FINAL PROJECT;
//Modified for WordPress;

//array that holds all existing trash objects;
var trashPieces = [];

//this array holds all of the indices of trash objects that have been clicked on - removed;
//then it uses the splice method of arrays to remove that object 
//and erase it from the trashPieces array;
//and the screen as well;
//this effectively removes it;
var trashPiecesRemoval = [];

//gameOver condition that is used for the game overall;
//when true it ends the game and transfers the screen to facts;
var gameOver = false;

//number of current trash objects on screen;
var trashNumCurrent = 0;

//number of trash objects removed;
var trashGone = 0;

//variables that holds the time;
//numSecondsPast is how many seconds have passed;
var numSecondsPast = 0;
//while numSecondsAllowed is how many seconds are left for the player;
//the initial number of seconds allowed for the player is 120 or 2 minutes;
//the reason for two seperate variables is more flexibility for time as a feature;
var numSecondsAllowed = 120;
//the frameCount variable needed for the timer Function that counts time;
var frameCount = 0;

//the variable that determines how many trash objects can be drawn at a time;
var spawnNum = 20;

function setup() {
    //modified canvas size;
    createCanvas(600, 600);
    //creates sea background;
    background(91, 161, 176);
    
    //creates the first initial trash objects;
    for (var l = 0; l < 20; l++){
        makeTrash(random(80, 520), random(80, 520), floor(random(5)), 
            floor(random(0,8)), floor(random(0,8)), random(360), true);
    }


    //sets the frameRate to 30;
    frameRate(30);
    
}

function draw() {
    //calls the display function;
    displays();
    
    //print method used for debugging, it shows how many seconds have passed;
    print(numSecondsPast);
    //increases the frameCount every iteration;
    frameCount++;

    //calls the countTime function that counts the time;
    countTime(frameCount);
    
    //This is the main checker for whether the game is over or not;
    //Namely, it checks for if the time left is 0 or not by way of comparing;
    //the number of seconds allowed - numSecondsAllowed;
    //and the number of seconds that have passed - numSecondsPast;
    //if there is still time, then gameOver is false;
    //And the game runs as usual;
    if (numSecondsAllowed > numSecondsPast){
        gameOver = false;
        //draws all of the existing trash objects;
        for (var m = 0; m < trashNumCurrent; m++){
            var pT = trashPieces[m];
            pT.drawFunction();
        }
    
        //removes any trash objects deemed nonexistant;
        //also uses background to reset the drawing board and removed previous 'drawings' of the object;
        for (var r = 0; r < trashPiecesRemoval.length; r++){
            background(91, 161, 176);
            trashGone++;
            trashPieces.splice(trashPiecesRemoval[r], 1);
        }

        //completely wipes out the trashPiecesRemoval array to allow it to be filled with indices again;
        while (trashPiecesRemoval.length > 0){
           trashPiecesRemoval.shift();
        }
        
        //calls the spawnMoreTrash function;
        spawnMoreTrash();
        }
        //if the time left is 0, then it calls the factScreen function that ends the game;
        else {
            factScreen(facts(floor(random(0, 9))));
    }

    //prints out the current trashPieces array length for debugging;
    trashNumCurrent = trashPieces.length;
    print(trashPieces.length);
    
    //this switch and case checks for the total amount of trash removed;
    //if it passes certain milestones, the spawnNum of trash increases with a one time added bonous of more time;
    switch (trashGone){
        case 40: spawnNum = 25; numSecondsAllowed + 60; break;
        case 80: spawnNum = 30; numSecondsAllowed + 50; break;
        case 120: spawnNum = 35; numSecondsAllowed + 40; break;
        case 1600: spawnNum = 40; numSecondsAllowed + 30; break;
    }

}

//draws the scoreboards, title, time left, and directions;
function displays (){
    stroke(1);
    strokeWeight(0.5);

    //code for top left display of trash removed and trash left;
    fill(255);
    rect(10, 10, 150, 45);

    fill(0);
    var trashNumDisplay = 'Trash Left: ' + trashNumCurrent;
    text(trashNumDisplay, 15, 45);
    var scoreDisplay = 'Trash Removed: ' + trashGone;
    text(scoreDisplay, 15, 25);

    //code for upper middle display of the title of the game;
    fill(240, 133, 11);
    rect(276.5, 15, 100, 35);
    
    fill(0);
    text("Trash-Pick-Up", 285.5, 35);

    //code for upper right display of time left for trash removal;
    fill(255);
    rect(510, 10, 80, 35);

    fill(0);
    var timeLeftDisplay = 'Time: ' + (numSecondsAllowed - numSecondsPast);
    text(timeLeftDisplay, 520, 32.5);

    //code that gives the game directions;
    fill(200, 186, 234);
    rect(60, 555, 480, 40);

    fill(0);
    var directions = 'Click on the red dots to remove the trash before time runs out!  Watch out for misclicks!';  
    var directions2 = 'If you do not see any trash but the trash left is not 0, hit any key to respawn them!';
    text(directions, 65, 570);
    text(directions2, 65, 585);
}


//All of the code below was originally in seperate files to ensure readability and ease of access;
//Due to WordPress, I had to combine all 4 files into 1;

//file that creates the trash objects;

//constructor for the trash object;
//it takes 6 numbers and a boolean value;
//xPost and yPos is the object's main position as it is the first vertex in a given object;
//each object is a randomly constructed shape made with the beginShape() and endShape() function;
//it then takes cPre, a random number that determines its color;
//After that comes the "random points" - which are random numbers added or subtracted to the starting vertex;
//These numbers are stored in an array;
//There are 2 sets of 8 different arrays, one for x and one for y;
//ang is the angling of each object;
//existBol is the boolean value that determines if the object still exists or not;
//it has a drawFunction, drawTrash which handles the drawing;
//it also has a changeFunction. mousePressed, which changes its state as an instance still on the screen;
//and as an existant object within any of the arrays;
function makeTrash (xPos, yPos, cPre, pointsPresetX, pointsPresetY, ang, existBol){
    var t = {x: xPos, y: yPos, col: cPre, 
        pXA: pointsPresetX, pYA: pointsPresetY,
        a: ang, e: existBol, 
        drawFunction: drawTrash, changeFunction: mousePressed};
    trashPieces.push(t);
}

//the drawTrash function is the drawFunction of each trash object;
function drawTrash (){
    //this initial condition decides if it is still on screen (being drawn);
    if (this.e == true){
        stroke(0);

        //switch and case for the color of a given trash object;
        switch (this.col) {
            case 0: fill(228, 200, 98); break;
            case 1: fill(169, 142, 144); break;
            case 2: fill(156, 161, 117); break;
            case 3: fill(135, 206, 250); break;
            case 4: fill(255, 255, 255); break;
        }
  
        //this creates each object, by using beginShape() and endShape(), with numbers that are added to the original vertex;
        //a 7 pointed shape is made;
        //Due to the presence of 8 arrays and a seperate number that determines which array is for x and for y, there are 64 possible combinations;
        //The numbers for each array set is entered and it returns an array to be used for each specific trash object;

        //for the x values added to the original vertex;
        switch(this.pXA){
            case 0: var x = [20, -30, 10, 50, -60, 70]; break;
            case 1: var x = [30, -40, 40, 20, 30, 50]; break;
            case 2: var x = [50, -60, 25, 65, -35, 40]; break;
            case 3: var x = [-30, 70, -30, 40, -25, 65]; break;
            case 4: var x = [20, 30, 10, -50, 60, 30]; break;
            case 5: var x = [60, -20, 35, 20, 45, -20]; break;
            case 6: var x = [-20, 30, 10, -50, 60, 30]; break;
            case 7: var x = [60, -20, 35, 20, 45, -20]; break;
        }
        //for the y values added to the original vertex;
        switch(this.pYA){
           case 0: var y = [40, 30, 10, -25, 30, 20]; break;
           case 1: var y = [35, 25, 10, 50, -70, -40]; break;
           case 2: var y = [20, -0, 10, -10, 40, 20]; break;
           case 3: var y = [-30, 50, 20, 25, 25, -30]; break;
           case 4: var y = [20, 35, -25, -35, 20, 10]; break;
           case 5: var y = [30, -45, 20, -45, 35, 40]; break;
           case 6: var y = [40, 35, 30, -40, 60, -50]; break;
           case 7: var y = [-50, -10, 20, 35, 40, 30]; break;
        }
    
        //with the color and vertex arrays determined, the actual shape is made;
        //it is put within a push and pop for extra variation by way of rotation;
        //the actual tricks for rotation are then applied;
        push();
        translate(this.x, this.y);
        rotate(radians(this.a));
        beginShape();
        vertex(0, 0);
        for (var i = 0; i < 8; i++){
            vertex(0 + x[i], 0+ y[i]);  
        }
        endShape(CLOSE);
        //an additional red circle is added at the original vertex to make it easier to click on;
        fill(255, 0, 0);
        circle(0, 0, 5);
        pop();
    }
}

//this function is the function that changes each object;
//it decides whether each object still exists or not after each click;
function mousePressed() {
    //I made the mouseX and mouseY coordinates into mX and mY respectively for easier typing;
    var mX = mouseX;
    var mY = mouseY;
    
    //the flag variable that becomes true if the player clicks on anything but a trash object's red dot;
    //it is false at the beginning to ensure that a new click is not automatically a misclick;
    var secondOff = false;

    //as the player clicks the mouse, a for loop checks the entire trashPieces array - which;
    //holds all of the existing trashPieces;
    //it checks whether mX and mY are close to the original x and y of any given trash;
    //if the distance is less than 30, then it sets the specific trash object to false;
    //it then pushes the object's index into the trashPiecesRemoval array;
    //this array holds all of the indices of trash objects that have been clicked on - removed;
    //then it uses the splice method of arrays to remove that object and erase it from the trashPieces array;
    //and the screen as well;
    //this effectively removes it;
    for (var i = 0; i < trashPieces.length; i++){
        var rI = i;
        pT = trashPieces[i];
        if (dist(mX, mY, pT.x, pT.y) < 10){
            pT.e = false;
            trashPiecesRemoval.push(rI);
        }
        //if the player clicks and does not remove a piece of trash, it sets the flag variable called secondOff;
        //this in turn makes the following if statement outside of the for loop execute, taking a second off the clock;
        else {
            secondOff = true;
        }
    }
    
    //this function takes a second off of the clock for misclicks;
    if (secondOff == true){
        numSecondsPast++;
    }
}

//this function spawns more trash everytime all of the trash has been removed and the trashPieces array is empty;
function spawnMoreTrash (){
    //it checks to see if the game is over;
    //if true it executes the rest of the code;
    if (gameOver != true){
        //it checks if trashPieces is empty;
        //if true, it creates more trash according to the spawnNum variable;
        if (trashPieces.length == 0){
            for (var l = 0; l < spawnNum; l++){
                makeTrash(random(80, 620), random(80, 520), floor(random(5)), 
                floor(random(0,8)), floor(random(0,8)), random(360), true);
            }
            //this adds more time once a new set of trash has been spawned;
            numSecondsAllowed = numSecondsAllowed + (spawnNum - 10);
            //this gives a change of randomly increasing the spawnNum as well;
            if (floor(random(51)) > 25){
                spawnNum += 2;
            }
        }
    }
}

//a vital function, the keyPress function resets the board;
//Once any key is pressed, the board is redrawn with the same amount of trash pieces left;
//as well as the same amount of time left;
//this is key as there are times where a glitch occurs where all but one or two trash pieces;
//are drawn - meaning they cannot progress as the time winds down;
//Due to not being drawn, the player unfairly loses due to the glitch;
//this keyPress function prevents this by redrawing the board with the same amount of time and trash;
function keyPressed(){
    //this variable is the total amount of trash that has to be redrawn, it is made 0;
    //to ensure that everytime it is called, the number of trash that needs to be redrawn is allowed to change;
    var trashLeftReset = 0;

    //This for loop does the same thing as the loop that removes clicked-on trash;
    //instead of specifically clicked on trash, it removes all of them;
    //It counts how many were removed;
    //Due to this being intended for trash objects that do not appear;
    //It initiates the first step of redrawing them on the board;
    //Therefore, if used for any other purpose, such as cheating, it does nothing but reset the board;
    for (var i = 0; i < trashPieces.length; i++){
        pT = trashPieces[i];
        trashPiecesRemoval.push(pT);
        //this variable offsets the fact that everytime trash is removed, the trash removal counter goes up;
        //this is to prevent cheating as well as the trashGone variable is key for other conditions;
        trashGone--;
        
        //for each piece of trash removed, the counter for trash that needs to be redrawn goes up as well;
        //this is for the following for loop that draws any undrawn trash objects;
        trashLeftReset++;
    }

    //this for loop does the second step of redrawing the board, namely drawing any unremoved and undrawn trash pieces;
    //albiet as a different object altogether;
    for (var l = 0; l < trashLeftReset; l++){
        makeTrash(random(80, 620), random(80, 520), floor(random(5)), 
        floor(random(0,8)), floor(random(0,8)), random(360), true);
    }
}

//separate code file that deals with writing out the facts after the player loses;

//the facts function itself takes a random number and then uses a case and switch for;
//the corresponding fact related to pollution in the ocean;
//I chose to use case and switch due to its simplicity;
function facts (inputNum){
    var factString = "";
    switch(inputNum) {
        case 0: factString = "We dump 8 million tons or 17.6 billion pounds of \nplastic into oceans every year."; return factString; break;
        case 1: factString = "Plastics are responsible for over 80% of the negative \neffects on sea animals."; return factString; break;
        case 2: factString = "By 2050, estimations say that there will be more \nplastic than fish in the ocean when it comes to \nweight alone."; return factString; break;
        case 3: factString = "Over 100,000 marine animals die from eating plastic \nor being trapped by it every year."; return factString; break;
        case 4: factString = "Plastic takes approximately 400 years to degrade\n - when it does in the ocean, more harmful chemicals\n are released."; return factString; break;
        case 5: factString = "Around 70% of ocean garbage are uncleanable \nbecause they sink into the seabed."; return factString; break;
        case 6: factString = "90% of seabirds have plastics in their stomachs."; return factString; break;
        case 7: factString = "300 million tons of plastic is created \nevery year - about 50% is single use."; return factString; break;
        case 8: factString = "Microplastics have been found in Arctic sea ice."; return factString; break;
    }     
}

//related to facts, it takes the fact string and uses it as text;
//this function is the function that causes the game to end;
//it draws the relevant screen and ends the game with a noLoop() call;
function factScreen (factInput){
    background(53, 56, 57);
    fill(255);
    strokeWeight(2);
    stroke(255, 0, 0);
    rect(200, 270, 300, 60);
    stroke(0);
    strokeWeight(0.5);
    fill(0);
    text(factInput, 210, 290);
    stroke(255);
    noLoop();
}


//facts cited from:
//https://www.conservation.org/stories/ocean-pollution-11-facts-you-need-to-know
//https://www.rubicon.com/blog/ocean-pollution-facts/
//https://www.conserve-energy-future.com/various-ocean-pollution-facts.php
//https://www.condorferries.co.uk/marine-ocean-pollution-statistics-facts
//https://www.ehn.org/ocean-plastic-pollution-2654378379/what-can-be-done


//code for the timer that is utilized in the game as a condition for losing;
//the function takes the input of the frameNumber - which is the count of;
//every iteration of the draw loop (the main loop of the game);
//everytime the frameNumber hits 60, numSecondsPast is increased by 1;
//the function also takes the a boolean variable called resetBoolean;
//if the boolean entered is true, it resets the global variable numSecondsPast to 0;
//this is to ensure that everytime a new timer is set, the number of seconds passed 
//is also reset;

function countTime (frameNumber){
    if ((frameNumber % 60) == 0){
        numSecondsPast++;
    }
}


//I got the inspiration for the timer from a program called "countdown timer"
//by user marynotari on the p5js.org site;
//the link for the code: https://editor.p5js.org/marynotari/sketches/S1T2ZTMp-

[Note, I have modified my Project to make it functional for WordPress, the original Canvas size was meant to be 700 by 600, but had to be changed to 600 to 600, therefore, many values regarding specific spots on the canvas has been changed.]

For inspiration, I ran through what I knew about climate change.
Rather than focusing on ways to combat it, I really wanted to tell the effects of it. So, I decided to make an interactive game that showed the depressing facts about ocean pollution. Most of the facts deal with plastics, which are the main objects of the game, the trash objects are supposed to represent.

The game is a simple score as high as possible before time runs out.
The player is given initially 20 trash pieces on a screen and must click on them (the red dots that is their origin as they are shapes made with the beginShape() function). By clicking on them, they are removed and once the number of trash that needs to be removed hits 0, a new set is spawned (if any are undrawn, clicking a key will spawn them in by redrawing the board). Furthermore, there is a timer, so if time runs out (and it always will) the player loses. If any of their clicks are not on the red origin of a trash object, then they have a second deducted from their time. Once losing, they face a black screen with a single text block that tells a fact about ocean pollution.

The fact that the trash is hard to click on is meant to show how hard it is to clean up/fight ocean pollution once it has made its way fully into the ocean. Furthermore, the time limit and countdown are meant to show that we really need to fix ocean pollution now. Finally, the spawning of trash (with the number of a set increasing certain times) is meant to show how the problem is becoming worse and worse. Overall, the program is meant to show that ocean pollution is something that we must fix now because the problem is truly getting worse and harder to solve.

If I had more time, I would have added extra features like making it so that trash can “dissappear” meaning that they are no longer removable/clean-upable, just like in real life as trash in the ocean sink to the seafloor and are impossible to remove. I would’ve also found a way for “true” randomization of the trash, as right now the trash is 7-point polygons that have a set number of versions (64). True randomization is a variable number of points in each polygon and where those points are relation to the original vertex.

I hope you enjoyed my project!

I got the ocean pollution facts from:
https://www.conservation.org/stories/ocean-pollution-11-facts-you-need-to-know
https://www.rubicon.com/blog/ocean-pollution-facts/
https://www.conserve-energy-future.com/various-ocean-pollution-facts.php
https://www.condorferries.co.uk/marine-ocean-pollution-statistics-facts
https://www.ehn.org/ocean-plastic-pollution-2654378379/what-can-be-done

Leave a Reply