Week 15 – Final Project

My project is a simple interactive and informative game based on the theme of Covid-19. The setting takes place in a store with racks that display different supplies people use to prevent the spread of the disease. The main problem I realize these days is that people don’t seem to know which supplies and masks are necessary/appropriate during the pandemic. When you run my program, you should drag the objects in order from numbers 1-12 to either the shopping bag or the trash can. You should place the supply on the shopping bag if you think the object is necessary/effective during the pandemic, and place the supply on the trash can if you think the object is not necessary/effective during the pandemic. You will be able to see texts that explain whether the supplies are helpful or not in preventing Covid-19 when you place them onto the shopping bag or trash can. Also, Christmas season is coming. In celebration of the holiday, I’ve added some Christmas lights to the shop, like how real stores do during the holiday season. If I had more time, I would like to find out other ways to drag objects without having them collect multiple objects when they are overlapped in similar locations on canvas. Although it isn’t a problem in running my program and playing the game, adding codes that help objects be selected one by one despite overlapped locations would be great if I had more time to work on the project.

sketch
//Stefanie Suk
//ssuk@andrew.cmu.edu
//15-104 Section D

//Covid-19 Object Variables
var dentalMask = makedentalMask();
var n95Mask = maken95Mask();
var spongeMask = makespongeMask();
var clothMask = makeclothMask();
var homemadeMask = makehomemadeMask();
var bandanaMask = makebandanaMask();
var thermometer = makeThermometer();
var waterBottle = makewaterBottle();
var toiletPaper = maketoiletPaper();
var soap = makeSoap();
var lowSanitizer = makelowSanitizer();
var highSanitizer = makehighSanitizer();

//Shopping bag and Trash Can Variables
var shoppingBag = makeshoppingBag();
var trashCan = maketrashCan();

//Array of Covid-19 supplies
//Array of Shopping bag and Trashcan 
var covidObjects = [dentalMask, n95Mask, spongeMask, clothMask, homemadeMask, bandanaMask, 
                    thermometer, waterBottle, toiletPaper, soap, lowSanitizer, highSanitizer];
var bagandTrash = [shoppingBag, trashCan];

//offset variable for mouse press and drag supplies
var offsetX;
var offsetY;

//Objects for Covid-19 supplies, Shopping bag, and Trashcan with specific datas
function makeshoppingBag() {
    var shoppingBag = {
        imageUrl: "https://i.imgur.com/WdeIUp0.png",       //imageURL: url of object images
        positionX: 75,                                     //positionX: X position of objects on canvas
        positionY: 375,                                    //positionY: Y position of objects on canvas
    }
    return shoppingBag;
}

function maketrashCan() {
    var trashCan = {
        imageUrl: "https://i.imgur.com/5jjADwl.png",
        positionX: 330,
        positionY: 375,
    }
    return trashCan;
}

function makedentalMask() {
    var dentalMask = {
        imageUrl: "https://i.imgur.com/Lsg9xeK.png",
        imagex: 45,
        imagey: 25,
        positionX: 41,
        positionY: 167,
        informationTwo: "Dental Masks, "
                        + "Dental masks are effective in preventing Covid-19.",                                //informationTwo: texts when placed on trashcan
        information: "Dental Masks, Effective. "
                    + "Dental masks are designed to prevent the spread of droplets and splatters. "
                    + "Wearing surgical masks can reduce the spread of respiratory infection."
                    + "*Important* Surgical masks are designed to be used only once."                      //information: texts when placed on shopping bag
    }
        return dentalMask;
}

function maken95Mask() {
    var n95Mask = {
        imageUrl: "https://i.imgur.com/b5hh3hx.png",
        imagex: 45,
        imagey: 25,
        positionX: 106,
        positionY: 167,
        informationTwo: "N95 Masks, N95 masks are effective in preventing Covid-19.",
        information: "N95 Masks, Effective. N95 is the most protective mask against coronavirus and other respiratory "
                    + "diseases. It filters out 95% of particles from the air."
    }
    return n95Mask;
}

function makespongeMask() {
    var spongeMask = {
        imageUrl: "https://i.imgur.com/KhnI7An.png",
        imagex: 45,
        imagey: 25,
        positionX: 171,
        positionY: 169,
        informationTwo: "Sponge Mask, Not Effective. Sponge mask, or neoprene mask, may be designed to be comfortable, but "
                        + "is not effective in preventing the spread of Covid-19 disease. "
                        + "*Tips* Adding replaceable filer can help with the mask's effectiveness.",
        information: "Sponge Mask, Sponge masks are not effective in preventing Covid-19."
    }
    return spongeMask;
}

function makeclothMask() {
    var clothMask = {
        imageUrl: "https://i.imgur.com/SierEPM.png",
        imagex: 45,
        imagey: 25,
        positionX: 41,
        positionY: 242,
        informationTwo: "Effective, Cloth Masks bought in stores are effective in preventing Covid-19.",
        information: "Cloth Mask, Effective. A typical store-bought cloth mask is approximately 50% protective, but "
                    + "depending on its construction and quality, it can protect the virus to about 80-95%."
    }
    return clothMask;
}

function makehomemadeMask() {
    var homemadeMask = {
        imageUrl: "https://i.imgur.com/scSV8qR.png",
        imagex: 45,
        imagey: 25,
        positionX: 106,
        positionY: 242,
        informationTwo: "Handmade Mask, Not Effective. A single-layered handmade mask only filters 1% of particles "
                        + "from air. A two-layered cotton mask can filter only about 35% of particles. *Tips* More "
                        + "layers with more dense woven fabrics can increase the protection.",
        information: "Not Effective, Handmade Masks are not effective in preventing Covid-19."
    }
    return homemadeMask;
}

function makebandanaMask() {
    var bandanaMask = {
        imageUrl: "https://i.imgur.com/QX6uDBJ.png",
        imagex: 45,
        imagey: 25,
        positionX: 171,
        positionY: 242,
        informationTwo: "Bandanas, Not Effective. Covering your mouth and nose with a bandana provides little "
                        + "protection against droplets and does not filter particles from air.",
        information: "Not Effective, Bandanas are not effective in preventing Covid-19."
    }
    return bandanaMask;
}

function makeThermometer() {
    var thermometer = {
        imageUrl: "https://i.imgur.com/qbeSsFP.png",
        imagex: 30,
        imagey: 40,
        positionX: 285,
        positionY: 160,
        informationTwo: "Effective, Thermometers are effective in preventing Covid-19.",
        information: "Thermometer, Effective. Using a thermometer to check your body temperature daily is always "
                    + "important in preventing the spread of Covid-19. *Important* Make sure to check your body temperature does not go over 37.8C."
    }
    return thermometer;
}

function makewaterBottle() {
    var waterBottle = {
        imageUrl: "https://i.imgur.com/0h5YpiF.png",
        imagex: 20,
        imagey: 45,
        positionX: 359,
        positionY: 156,
        informationTwo: "Not Effective, Water. Suggestions are that drinking every 15 minutes would wash any virus down the throat, but there are at "
                        + "least thousands of viruses that we come into contact with and it’s highly unlikely you would wash all that virus down. "
                        + "Thus, the primary way the virus is transmitted is through respiratory droplets in the air.",
        information: "Not Effective, Drinking water is not effective in preventing Covid-19."
    }
    return waterBottle;
}

function maketoiletPaper() {
    var toiletPaper = {
        imageUrl: "https://i.imgur.com/pxMwAgb.png",
        imagex: 35,
        imagey: 35,
        positionX: 415,
        positionY: 161,
        informationTwo: "Toilet Papers, Not effective. There is absolutely no reason to buy toilet papers for preventing Covid-19. Stop stockpiling "
                        + "toilet papers, because they don’t help you prevent the spread of Covid-19.",
        information: "Not Effective, Toilet Papers are not effective in preventing Covid-19."
    }
    return toiletPaper;
}

function makeSoap() {
    var soap = {
        imageUrl: "https://i.imgur.com/JQBa2uV.png",
        imagex: 40,
        imagey: 30,
        positionX: 285,
        positionY: 239,
        informationTwo: "Effective, Soaps are effective in preventing Covid-19.",
        information: "Soaps, Effective. Washing your hands regularly with soap and water break germs up and remove them, which is one of the most "
                    + "effective ways to prevent Covid-19 from spreading."
    }
    return soap;
}

function makelowSanitizer() {
    var lowSanitizer = {
        imageUrl: "https://i.imgur.com/YdnSXSO.png",
        imagex: 20,
        imagey: 45,
        positionX: 359,
        positionY: 231,
        informationTwo: "40% Alcohol Sanitizers, Not Effective. Sanitizers with 40% alcohol doesn’t really help with disinfection. *Important* "
                        + "Not only sanitizers, but any alcohol solutions that contain less than 70% alcohol is ineffective.",
        information: "Not Effective, Sanitizers with 40% alcohol are not effective in preventing Covid-19."
    }
    return lowSanitizer;
}

function makehighSanitizer() {
    var highSanitizer = {
        imageUrl: "https://i.imgur.com/YZihMaD.png",
        imagex: 20,
        imagey: 45,
        positionX: 424,
        positionY: 231,
        informationTwo: "Effective, Sanitizers with 70% alcohol are effective in preventing Covid-19.",
        information: "70% Alcohol Sanitizers, Effective. Sanitizers (or any alcohol solutions) with 70% alcohol or more are "
                    + "perfect for disinfecting your hands and objects."
    }
    return highSanitizer;
}

function preload() {
    //Preload background image
    backgroundImage = loadImage("https://i.imgur.com/uRLr2HC.png");
    //Preload object images, push objects to new array
    bagandtrashImages = [];
    for (var i = 0; i < bagandTrash.length; i++) {
        bagandtrashImages.push(loadImage(bagandTrash[i].imageUrl));
    }
    covidobjectImages = [];
    for (var i = 0; i < covidObjects.length; i++) {
        covidobjectImages.push(loadImage(covidObjects[i].imageUrl));
    }
}

function setup() {
    createCanvas(500, 600);
    frameRate(10); //Frame rate for christmas lights
}

function draw() {
    //load images of background, covid objects, bag and trash 
    background(220);
    image(backgroundImage, 0, 0, 500, 600);

    for (var i = 0; i < bagandTrash.length; i++) {
        image(bagandtrashImages[i], bagandTrash[i].positionX, bagandTrash[i].positionY, 90, 100);
    }
    for (var i = 0; i < covidObjects.length; i++) {
        image(covidobjectImages[i], covidObjects[i].positionX, covidObjects[i].positionY, covidObjects[i].imagex, covidObjects[i].imagey);
        //drag object with mouse
        if (covidObjects[i].drag) {
            covidObjects[i].positionX = offsetX + mouseX;
            covidObjects[i].positionY = offsetY + mouseY;
        }
        //When objects placed in specific locations (bag and trashcan), text appears
        if ((covidObjects[i].positionX > 65) & (covidObjects[i].positionX < 145)) {
            if ((covidObjects[i].positionY > 400) && (covidObjects[i].positionY < 460)) {
                noStroke();
                fill(163, 160, 72);
                rect(3, 502, 486, 100);
                fill(0);
                text(covidObjects[i].information, 20, 520, 460, 70);                          //texts appear when placed on shopping bag
            }
        }

        if ((covidObjects[i].positionX > 310) & (covidObjects[i].positionX < 395)) {
            if ((covidObjects[i].positionY > 365) && (covidObjects[i].positionY < 465)) {
                noStroke();
                fill(163, 160, 72);
                rect(3, 502, 486, 100);
                fill(0);
                text(covidObjects[i].informationTwo, 20, 520, 460, 70);                       //texts appear when placed on trashcan
            }
        }
    }

    //lightbulbs on ceiling for Christmas holiday season
    for (var i = 5; i < 600; i = i+13) {
        push();
        translate(i, 5);
        makelightBulb();
        pop();
    }
}

function mousePressed() {
    //drag covid objects with mouse when mousepressed
    //drag when mouse pressed in specific range of object
    for (var i = 0; i < covidObjects.length; i++) {
        if (mouseX > covidObjects[i].positionX - 25 & mouseX < covidObjects[i].positionX + 25 && mouseY > covidObjects[i].positionY - 25 && mouseY < covidObjects[i].positionY + 25) {
            offsetX = covidObjects[i].positionX - mouseX;
            offsetY = covidObjects[i].positionY - mouseY;
            covidObjects[i].drag = true;
        }
    }
}

function mouseReleased() {
    for (var i = 0; i < covidObjects.length; i++) {
        covidObjects[i].drag = false;
    }
}

function makelightBulb() {
    //variables for lightbulb colors
    var lightColor;
    var lightVariations;

    //red, green, blue, yellow randomly used
    lightColor = floor(random(1, 5));
    if (lightColor === 1) {
        lightVariations = [255, 0, 0];
    }
    if (lightColor === 2) {
        lightVariations = [0, 255, 0];
    }
    if (lightColor === 3) {
     lightVariations = [0, 0, 255];
    }
    if (lightColor === 4) {
     lightVariations = [255,255,0];
    }

    //left side of canvas, square lightbulbs
    //right side of canvas, circle lightbulbs
    fill(lightVariations);
    if (mouseX > width/2) {
        ellipse(5, 5, 7, 7);
    } else {
        rect(2, 2, 7, 7);
    }
}

Final Project: Covid Clicker

Our program is an interactive fight the coronavirus game. Within this game the player must tap on the coronavirus particles attacking the hospital in order to try to create and distribute the vaccine. As the players score increases the
particles spawn at a higher rate making the game harder to win. Once the screen and player are about to be overtaken by the virus the screen will start to flash red indicating the player is close to losing. Once there are 30 or more corona
virus particles on the screen the player has become infected and loses. Losing triggers the game to bring the player to the loser page. In order to win the game the player must click on 100 individual particles filling up the bar on the right side of the game. Once this occurs the player has created and distributed the vaccine bringing them to the winner page. If we had more experience in code we would have liked to have been able to make the virus particles more complex and life like while having the mouse pressed function work on only the virus. With more time and knowledge this might have been accomplished.

sketchDownload
var counter = 0;
var viruses = [];
var newVirusLikelihood = 0.05;
var cars = [];


function setup() {
    createCanvas(480, 480);
    frameRate(10);
}

function draw() {
    push();
    background1();
    pop();
    //gives a flashing warning if there are more than 20 objects
    //Lucas and Anthony
    if(viruses.length > 20){
        if(frameCount % 4 == 0){
            background(255, 0, 0, 100);
        }
        else{
            push();
            background1();
            pop();
        }
    }
    //The following if statements increase the spawn rate at certain scores
    //(Lucas)
    if(counter == 5){
        newVirusLikelihood = .07
    }
    if(counter == 10){
        newVirusLikelihood = .12
    }
    if(counter == 25){
        newVirusLikelihood = .17
    }
    if(counter == 50){
        newVirusLikelihood = .23
    }
    //Creates a progress bar to a vaccine (Lucas)
    fill(0, 255, 0);
    rect(width - 10, 0, 10, counter * height / 100);

    fill(255);
    //displays how many viruses have been "cleansed" (Lucas)
    text("Score = " + counter.toString(), 10, 10, 70, 80);
    updateAndDisplayViruses();
    bounceViruses();
    addNewVirusesWithSomeRandomProbability();
    print(counter.toString());
    //End Screen if the player loses (Lucas)
    if(viruses.length >= 30){
        //erase();
        background(0);
        textAlign(CENTER);
        textSize(26);
        text("You Lose: COVID-19 Has Taken Over", width / 2, height / 2)
        noLoop();
    }
    //End Screen if the player wins (Lucas)
    if(counter == 100){
        background(255);
        push();
        fill(0);
        textAlign(CENTER);
        textSize(26);
        text("You Win: A Vaccine Has Been Distributed", width / 2, height / 2)
        pop();
        noLoop();

    }
}

//The following code was done by Lucas until indicated
function updateAndDisplayViruses(){
    // Update the virus positions, and display them.
    for (var i = 0; i < viruses.length; i++){
        viruses[i].move();
        viruses[i].display();
    }
}
//makes the viruses bounce off the edges of the canvas
function bounceViruses(){
    for(var i = 0; i < viruses.length; i++){
        //determines if a virus is on the left or right and switches direction
        //accordingly
        if(viruses[i].x + viruses[i].breadth / 2 >= width ||
        viruses[i].x - viruses[i].breadth / 2 <= 0){
            viruses[i].speedX = -viruses[i].speedX
        }
        //determines if a virus is on the top or bottom and switches direction
        //accordingly
        if(viruses[i].y + viruses[i].breadth / 2 >= height ||
        viruses[i].y - viruses[i].breadth / 2 <= 0){
            viruses[i].speedY = -viruses[i].speedY
        }
    }
}


function addNewVirusesWithSomeRandomProbability() {
    // Adds a virus based upon a probability
    if (random(0,1) < newVirusLikelihood) {
        viruses.push(makeVirus(random(20, width - 20),
        random(20, height - 20)));
    }
}

// method to update position of virus every frame
function virusMove() {
    this.x += this.speedX;
    this.y += this.speedY;
}

function virusDisplay() {
    //colors the viruses randomly
    push();
    fill(this.clr);
    push();
    translate(this.x, this.y);
    circle(0, 0, this.breadth);
    pop();
    pop();
}

function makeVirus(startLocationX, startLocationY){
    var virus = {x: startLocationX,
               y: startLocationY,
               breadth: random(20, 80), //size of virus
               //random color of each virus
               clr: color(random(255), random(255), random(255)),
               //random speeds of virus
               speedX: random(-5, 5),
               speedY: random(-5, 5),
               move: virusMove,
               display: virusDisplay}
    return virus;
}

function mousePressed(){
    var vBefore = [];
    var vAfter = [];
    var vFinal = [];
    var v = viruses;
    for(var i = 0; i < viruses.length; i++){
        //conditions for mouse to be inside a virus
        if(mouseX > viruses[i].x - viruses[i].breadth / 2 & mouseX <
            viruses[i].x + viruses[i].breadth/2 && mouseY < viruses[i].y +
            viruses[i].breadth / 2 && mouseY > viruses[i].y -
            viruses[i].breadth / 2){
                //viruses up until the clicked object
                vBefore = viruses.slice(0, i);
                //viruses after the clicked object
                vAfter = v.slice(i + 1);
                //combines the two arrays of objects (eliminating the clicked
                //one)
                vFinal = vBefore.concat(vAfter);
                counter += 1
                viruses = vFinal
        }
    }
}
//The following code was done by Anthony
function background1(){   //joining background helper functions into one
  background(135,206,235);
  push()
  hospital();
  pop()
  push()
  updateAndDisplayCars();
  removeCarsThatHaveSlippedOutOfView();
  addNewCarsWithSomeRandomProbability();
  pop()
}

function hospital(){
  translate(0,-50);
  rect(100,250,100,230);    //creating the hospital building
  rect(200,200,200,280);
  rect(240,150,120,50);
  push();
  noStroke();
  fill(255,0,0);    //red cross on the top
  rect(295,160,10,30);
  rect(285,170,30,10)
  pop();
  push();
  fill(0,0,255);
  for(x=115;x<185;x+=30){   //windows
    for(y=255;y<460;y+=30){
      square(x,y,15);
    }
  }
  for(x=215;x<390;x+=30){
    for(y=210;y<400;y+=30){
      square(x,y,15);
    }
  }
  rect(300,450,20,30);    //doors
  rect(280,450,20,30);
  pop();
  push()
  fill(64);
  rect(0,480,480,50);   //street
  pop()
}

function updateAndDisplayCars(){
    // Update the cars' positions, and display them.
    for (var i = 0; i < cars.length; i++){
        cars[i].move();
        cars[i].display();
    }
}

function removeCarsThatHaveSlippedOutOfView(){
    //defines if a car is off the canvas, recreates the array to keep
    //cars still on canvas and remove ones that have moved off
    var carsToKeep = [];
    for (var i = 0; i < cars.length; i++){
        if (cars[i].x + cars[i].breadth > 0) {
            carsToKeep.push(cars[i]);
        }
    }
    cars = carsToKeep;
}


function addNewCarsWithSomeRandomProbability() {
    // Adds a car based upon a probability
    var newCarLikelihood = 0.02;
    if (random(0,1) < newCarLikelihood) {
        cars.push(makeCar(width));
    }
}


// method to update position of tree every frame
function carMove() {
    this.x += this.speed;
}

function carDisplay() {
    //colors the car randomly
    fill(this.clr);
    push();
    translate(this.x, 440);
    //body of the car
    rect(0, 0, this.breadth, 30);
    //windows as roof of the car
    fill(255, 255, 255, 50);
    quad(15, 0, this.breadth*.25, -20, this.breadth*.75,
         -20, this.breadth-5, 0);
    //wheels
    fill(0);
    circle(20, 25, 25);
    circle(80, 25, 25);
    pop();
}

function makeCar(startLocationX){
    var car = {x: startLocationX,
               breadth: 100, // length of car
               //random color of each car
               clr: color(random(255), random(255), random(255)),
               //random speeds of cars
               speed: random(-5, -10),
               move: carMove,
               display: carDisplay}
    return car;
}

Fight the Corona virus final project

I worked on this project with Lucas Bittig. Our program is an interactive fight the coronavirus game. Within this game the player must tap on the coronavirus particles attacking the hospital in order to try to create and distribute the vaccine. As the players score increases the particles spawn at a higher rate making the game harder to win. Once the screen and player are about to be overtaken by the virus the screen will start to flash red indicating the player is close to losing. Once there are 30 or more corona virus particles on the screen the player has become infected and loses. Losing triggers the game to bring the player to the loser page. In order to win the game the player must click on 100 individual particles filling up the bar on the right side of the game. Once this occurs the player has created and distributed the vaccine bringing them to the winner page. If we had more experience in code we would have liked to have been able to make the virus particles more complex and life like while having the mouse pressed function work on only the virus. With more time and knowledge this might have been accomplished.

sketchDownload
var counter = 0;
var viruses = [];
var newVirusLikelihood = 0.05;
var cars = [];


function setup() {
    createCanvas(480, 480);
    frameRate(10);
}

function draw() {
    push();
    background1();
    pop();
    //gives a flashing warning if there are more than 20 objects
    //Lucas and Anthony
    if(viruses.length > 20){
        if(frameCount % 4 == 0){
            background(255, 0, 0, 100);
        }
        else{
            push();
            background1();
            pop();
        }
    }
    //The following if statements increase the spawn rate at certain scores
    //(Lucas)
    if(counter == 5){
        newVirusLikelihood = .07
    }
    if(counter == 10){
        newVirusLikelihood = .12
    }
    if(counter == 25){
        newVirusLikelihood = .17
    }
    if(counter == 50){
        newVirusLikelihood = .23
    }
    //Creates a progress bar to a vaccine (Lucas)
    fill(0, 255, 0);
    rect(width - 10, 0, 10, counter * height / 100);

    fill(255);
    //displays how many viruses have been "cleansed" (Lucas)
    text("Score = " + counter.toString(), 10, 10, 70, 80);
    updateAndDisplayViruses();
    bounceViruses();
    addNewVirusesWithSomeRandomProbability();
    print(counter.toString());
    //End Screen if the player loses (Lucas)
    if(viruses.length >= 30){
        //erase();
        background(0);
        textAlign(CENTER);
        textSize(26);
        text("You Lose: COVID-19 Has Taken Over", width / 2, height / 2)
        noLoop();
    }
    //End Screen if the player wins (Lucas)
    if(counter == 100){
        background(255);
        push();
        fill(0);
        textAlign(CENTER);
        textSize(26);
        text("You Win: A Vaccine Has Been Distributed", width / 2, height / 2)
        pop();
        noLoop();

    }
}

//The following code was done by Lucas until indicated
function updateAndDisplayViruses(){
    // Update the virus positions, and display them.
    for (var i = 0; i < viruses.length; i++){
        viruses[i].move();
        viruses[i].display();
    }
}
//makes the viruses bounce off the edges of the canvas
function bounceViruses(){
    for(var i = 0; i < viruses.length; i++){
        //determines if a virus is on the left or right and switches direction
        //accordingly
        if(viruses[i].x + viruses[i].breadth / 2 >= width ||
        viruses[i].x - viruses[i].breadth / 2 <= 0){
            viruses[i].speedX = -viruses[i].speedX
        }
        //determines if a virus is on the top or bottom and switches direction
        //accordingly
        if(viruses[i].y + viruses[i].breadth / 2 >= height ||
        viruses[i].y - viruses[i].breadth / 2 <= 0){
            viruses[i].speedY = -viruses[i].speedY
        }
    }
}


function addNewVirusesWithSomeRandomProbability() {
    // Adds a virus based upon a probability
    if (random(0,1) < newVirusLikelihood) {
        viruses.push(makeVirus(random(20, width - 20),
        random(20, height - 20)));
    }
}

// method to update position of virus every frame
function virusMove() {
    this.x += this.speedX;
    this.y += this.speedY;
}

function virusDisplay() {
    //colors the viruses randomly
    push();
    fill(this.clr);
    push();
    translate(this.x, this.y);
    circle(0, 0, this.breadth);
    pop();
    pop();
}

function makeVirus(startLocationX, startLocationY){
    var virus = {x: startLocationX,
               y: startLocationY,
               breadth: random(20, 80), //size of virus
               //random color of each virus
               clr: color(random(255), random(255), random(255)),
               //random speeds of virus
               speedX: random(-5, 5),
               speedY: random(-5, 5),
               move: virusMove,
               display: virusDisplay}
    return virus;
}

function mousePressed(){
    var vBefore = [];
    var vAfter = [];
    var vFinal = [];
    var v = viruses;
    for(var i = 0; i < viruses.length; i++){
        //conditions for mouse to be inside a virus
        if(mouseX > viruses[i].x - viruses[i].breadth / 2 & mouseX <
            viruses[i].x + viruses[i].breadth/2 && mouseY < viruses[i].y +
            viruses[i].breadth / 2 && mouseY > viruses[i].y -
            viruses[i].breadth / 2){
                //viruses up until the clicked object
                vBefore = viruses.slice(0, i);
                //viruses after the clicked object
                vAfter = v.slice(i + 1);
                //combines the two arrays of objects (eliminating the clicked
                //one)
                vFinal = vBefore.concat(vAfter);
                counter += 1
                viruses = vFinal
        }
    }
}
//The following code was done by Anthony
function background1(){   //joining background helper functions into one
  background(135,206,235);
  push()
  hospital();
  pop()
  push()
  updateAndDisplayCars();
  removeCarsThatHaveSlippedOutOfView();
  addNewCarsWithSomeRandomProbability();
  pop()
}

function hospital(){
  translate(0,-50);
  rect(100,250,100,230);    //creating the hospital building
  rect(200,200,200,280);
  rect(240,150,120,50);
  push();
  noStroke();
  fill(255,0,0);    //red cross on the top
  rect(295,160,10,30);
  rect(285,170,30,10)
  pop();
  push();
  fill(0,0,255);
  for(x=115;x<185;x+=30){   //windows
    for(y=255;y<460;y+=30){
      square(x,y,15);
    }
  }
  for(x=215;x<390;x+=30){
    for(y=210;y<400;y+=30){
      square(x,y,15);
    }
  }
  rect(300,450,20,30);    //doors
  rect(280,450,20,30);
  pop();
  push()
  fill(64);
  rect(0,480,480,50);   //street
  pop()
}

function updateAndDisplayCars(){
    // Update the cars' positions, and display them.
    for (var i = 0; i < cars.length; i++){
        cars[i].move();
        cars[i].display();
    }
}

function removeCarsThatHaveSlippedOutOfView(){
    //defines if a car is off the canvas, recreates the array to keep
    //cars still on canvas and remove ones that have moved off
    var carsToKeep = [];
    for (var i = 0; i < cars.length; i++){
        if (cars[i].x + cars[i].breadth > 0) {
            carsToKeep.push(cars[i]);
        }
    }
    cars = carsToKeep;
}


function addNewCarsWithSomeRandomProbability() {
    // Adds a car based upon a probability
    var newCarLikelihood = 0.02;
    if (random(0,1) < newCarLikelihood) {
        cars.push(makeCar(width));
    }
}


// method to update position of tree every frame
function carMove() {
    this.x += this.speed;
}

function carDisplay() {
    //colors the car randomly
    fill(this.clr);
    push();
    translate(this.x, 440);
    //body of the car
    rect(0, 0, this.breadth, 30);
    //windows as roof of the car
    fill(255, 255, 255, 50);
    quad(15, 0, this.breadth*.25, -20, this.breadth*.75,
         -20, this.breadth-5, 0);
    //wheels
    fill(0);
    circle(20, 25, 25);
    circle(80, 25, 25);
    pop();
}

function makeCar(startLocationX){
    var car = {x: startLocationX,
               breadth: 100, // length of car
               //random color of each car
               clr: color(random(255), random(255), random(255)),
               //random speeds of cars
               speed: random(-5, -10),
               move: carMove,
               display: carDisplay}
    return car;
}

Week 15: Final Project

sketch
/*
15-104
FINAL PROJECT
*/

/*
COLLABORATORS:
NICHOLAS WONG
SECTION A 
nwong1@andrew.cmu.edu

RACHEL KIM
SECTION C
rachelki@andrew.cmu.edu
*/


//Every function has a comment before it showing who did the majority of the code: Nick, Rachel, or both of us.
//For functions that we did together, specific blocks, statements, and expressions are commented to show who did them.

//Player properties
var gravity = 0.4;
var defaultSpeed = 2;
var jumpForce = 10;
var constantSpeed = 2;
var playerStartPos = 300;
var walkImage = [];

//Stage properties
var stagePos = 0;
var stageSpeed = 2;

//Game state properties
var points = 0;
var gameOver = false;
var startGame = false;

//Game object lists
var platforms = [];
var covids = [];


//Background object lists
var backgroundBuildings = [];
var backgroundObjects = [];
var clouds = [];

//Building images
var housesA;
var housesB;
var supermarket;

//Background images
var cloud;
var sky;
var ground;

//Misc Images
var lampPost;
var streetSign;
var covidImage;


 //Preload images - Rachel Kim
function preload(){
 
    // These URLs are for the individual walk cycle images,
    var filenames = [];
    filenames[0] = "https://i.imgur.com/URNRJvg.png";
    filenames[1] = "https://i.imgur.com/dt8xXHQ.png";
    filenames[2] = "https://i.imgur.com/jmhE5QQ.png";
    filenames[3] = "https://i.imgur.com/twdsSdv.png";
    filenames[4] = "https://i.imgur.com/HWf5XmA.png";
    filenames[5] = "https://i.imgur.com/45onU9z.png";
    filenames[6] = "https://i.imgur.com/ey2SDeI.png";
    filenames[7] = "https://i.imgur.com/cG56PdF.png";
    filenames[8] = "https://i.imgur.com/533xGwE.png";
 
    for (var i = 0; i < filenames.length; i++) 
    {
    	walkImage[i] = loadImage(filenames[i]);
    }

    //loading images for use

    //Background elements
    lampPost = loadImage("https://i.imgur.com/zEDU732.png");
    streetSign = loadImage("https://i.imgur.com/TJ9H37E.png");
    housesA = loadImage("https://i.imgur.com/cwlJyQN.png");
    housesB = loadImage("https://i.imgur.com/lmhZBn8.png");
    supermarket = loadImage("https://i.imgur.com/Q0iAh9M.png");

    //Further background elements
    cloud = loadImage("https://i.imgur.com/4SgU4y8.png");
    sky = loadImage("https://i.imgur.com/34BWtmE.png");
    ground = loadImage("https://i.imgur.com/qLiqpgd.png");


    //Covid obstacles
    covidImage = loadImage("https://i.imgur.com/eJskXy6.png");
}

//Setup Function - Both Rachel and Nick
function setup()
{
	createCanvas(600, 400);
	rectMode(CENTER);
	textAlign(CENTER);
	translate(width/2,height/2)

	pl1 = new createPlayer(50,250,0); //Create a new player at (50,250) - Nick Wong


	//Unless otherwise noted, everything within the dashed lines was done by Rachel Kim:
	//---------------------------------------------------------------------------------------------------------

	//Create buildings
	for (let i = 0; i < 60; i++)
	{
		backgroundBuildings.push(createBuildings(500*i, 120, round(random(0,2))));
	}

	//Create street items
	for (let i = 0; i < 100; i++)
	{
		backgroundObjects.push(createStreetItems(400*i, 335, round(random(0,1))))
	}

	//Create clouds
	for(let i = 0; i < 50; i++)
	{
		clouds.push(createClouds(500*i, random(100,0), random(0,1)));
	}

	//Create platforms
	for (let i = 0; i < 100; i++)
	{
		var colour = color(random(50,150),150,random(50,150));
		platforms.push(createPlatform(100*i + 300, random(100,290), random(50,120), random(20,15), colour));
	}

	//Create covid obstacles
	for (let i = 0; i < 100; i++)
	{
		covids.push(createCovid(random(350,750)*i + 800, random(150,275)));
	}

	//-----------------------------------------------------------------------------------------------------------
	// ***Note***
	// The reason why we are not procedurally generating objects on the fly
	// as the screen scrolls and instead instantiating everything in setup
	// is because it messes with collision detection sometimes.
}

//Main update function - Both Rachel And Nick
function draw()
{
	//Background sky and ground - Rachel Kim
	image(sky, 0, 0, width, height)
	image(ground, 0 , 240, width, height/2);

	//Point calculation and display - Nick Wong
	points = round(-stagePos/10);
	textSize(14);
	text("Points: " + points.toString(), 35,25);

	//Unless otherwise noted, everything within the dashed lines was done by Nick Wong:
	//------------------------------------------------------------------------------------------------------------
	if(!gameOver & startGame)
	{
		push();
		stagePos -= defaultSpeed; //Set scroll speed to default speed
		translate(stagePos + playerStartPos,0); //Translate entire canvas by scroll speed

		drawBackground(); //Draw background - by Rachel Kim


		pl1.update(); //Update player
		pl1.display(); //Update player display

		//Update canvas display
		for(let i = 0; i < platforms.length; i++)
		{
			platforms[i].display();
		}

		//Update covid obstacle display
		for(let i = 0; i < covids.length; i++)
		{
			covids[i].display();
		}
		pop();

		//Increase scroll and movement speed if total points is a multiple of 300
		if(points % 300 == 0 & points > 0)
		{
			defaultSpeed += 0.5;
			constantSpeed += 0.5;
		}
	}
	//---------------------------------------------------------------------------------------------------------------
	//Game over screen - Rachel Kim
	else if(gameOver)
	{
		push();
		translate(width/2, height/2);
		textSize(32);
		fill(0);
		text("Game Over!", 10,0); 
		textSize(18);
		text("You scored " + points.toString() + " points!", 10,30);
		text("Press [Space] to restart");
		pop();
	}
	//Start game screen (only shows up once) - Nick Wong
	else if(!startGame)
	{
		push();
		translate(width/2, height/2);
		textSize(32);
		fill(0);
		text("Press [Space] to Start", 10,0);
		pop();
	}
	
}


//Draw background elements - Rachel Kim
function drawBackground()
{
	//Loop through and draw clouds
	for (let i = 0; i < clouds.length; i++)
	{
		clouds[i].display();
		clouds[i].update();
	}
	//Loop through and draw buildings
	for (let i = 0; i < backgroundBuildings.length; i++)
	{
		backgroundBuildings[i].display();
	}
	//Loop through and draw signs and lamps
	for (let i = 0; i< backgroundObjects.length; i++)
	{
		backgroundObjects[i].display();
	}

	//Draw ground
	push();
	fill(141,156,141);
	noStroke();
	rectMode(CORNERS);
	rect(-width, height - 100, width*100, height);
	pop();
}

//Animate player character - Rachel Kim
function drawPlayer() //Loop through walk images
{
	//Loop through at 1/5 speed
	if (frameCount % 5 == 0)
	{
		this.index++
	}

	//Reset image when it reaches end of list
	if(this.index >= 7)
	{
		this.index = 0;
	}

	image(walkImage[this.index],this.x,this.y - this.height/2,this.width,this.height)
}

//Update player - Both Rachel and Nick
function updatePlayer()
{	
	//Game over if player falls off stage - By Rachel Kim
	if(this.x <= -stagePos - playerStartPos)
	{
		gameOver = true;
	}

	//Game over if player touches a covid particle - By Nick Wong
	for(let i = 0; i < covids.length; i++)
	{
		if(this.x + this.width/2 >= covids[i].x - covids[i].width/2 & this.x - this.width/2 <= covids[i].x + covids[i].width/2 && 
			this.y + this.height/2 >= covids[i].y - covids[i].height/2 && this.y - this.height/2 <= covids[i].y + covids[i].height/2)
		{
			gameOver = true;
		}
	}

	//Unless otherwise noted, everything within the dashed lines was done by Nick Wong:
	//-------------------------------------------------------------------------------------------------------------------------------------------

	this.y += this.dy; // Add y velocity to y position

	//Check if player is on ground (not platforms)
	if(this.y > height - 100 - this.height/2)
	{
		//Set y velocity to 0 and y position to top of ground rect
		this.dy = 0;
		this.y = height - 100 - this.height/2;
		this.grounded = true;
	}
	else
	{
		this.grounded = false;
	}
	

	//Calculate x speed
	let previousLoc = this.x //Store previous x position
	this.x += constantSpeed; //Add speed
	let currentLoc = this.x //Store current x position
	this.dx = currentLoc - previousLoc; //The difference between previous and current is dx

	//Check platform collisions (still a bit buggy)
	for(let i = 0; i < platforms.length; i++)
	{
		//Check boundary of player is colliding with boundary of platform
		if(this.x + this.width/2 >= platforms[i].x - platforms[i].w/2 & this.x - this.width/2 <= platforms[i].x + platforms[i].w/2)
		{

			//Check boundary of player is colliding with boundary of platform
			if(this.y + this.height/2 > platforms[i].y - platforms[i].h/2 && this.y - this.height/2 < platforms[i].y + platforms[i].h/2)
			{
				//Check if colliding with side of platform
				if(this.dx > 0 && this.dy == 0)
				{
					constantSpeed = 0;
				}

				//Check if below platform
				if(this.dy < 0) //If player is traveling up, player touch bottom of platform
				{
					if(this.y - this.height/2 > platforms[i].y)
					{
						this.y = platforms[i].y + platforms[i].h/2 + this.height/2 + 2; //Set position to bottom of platform
						this.dy = 0 //Y speed to 0
					}

				}
				//Check if on top of platform
				if(this.dy > 0) //If player is traveling down, player touch top of platform
				{
					if(this.y + this.height/2 < platforms[i].y)
					{
						this.y = platforms[i].y - platforms[i].h/2 - this.height/2 + 2; //Set position to top of platform
						this.dy = 0; //Set Y speed to 0
						this.onPlatform = true; //On platform is true (can jump)

					}

				}

			}
			else
			{
				this.onPlatform = false //On platform is not true if not colliding
				constantSpeed = defaultSpeed; //Set player speed to default
			}
			
		}
	}
	this.dy += gravity; //Add gravity
	//-------------------------------------------------------------------------------------------------------------------------------------------
}

//Create player - Nick Wong
function createPlayer(px,py,pdy)
{
	var player = {x: px, y: py, dx: 0, dy: pdy, width: 25, height:45, grounded: false, onPlatform: false, index: 0, display: drawPlayer, update: updatePlayer}

	return player;
}


//Create platform - Nick Wong
function createPlatform(px,py,pw,ph,colour)
{
	var platform = {x: px, y: py, w: pw, h: ph, colour: colour, display: drawPlatform}

	return platform;
}

//Draw platform - Nick Wong
function drawPlatform()
{
	push();
	noStroke();
	fill(this.colour);
	rectMode(CENTER);
	rect(this.x, this.y, this.w, this.h);
	pop();
}

//Create Covid obstacle - Nick Wong
function createCovid(cx, cy)
{
	var cvd = {x: cx, y: cy, width: 20, height: 20, display: drawCovid}
	return cvd;
}

//Create Covid obstacle - Nick Wong
function drawCovid(cx, cy)
{
	push();
	image(covidImage, this.x, this.y, this.width, this.height);
	pop();
}

//Create buildings - Rachel Kim
function createBuildings(bx, by, i)
{
	var bdg = {x: bx, y: by, index: i, display: drawBuilding}
	return bdg;
}

//Render buildings - Rachel Kim
function drawBuilding()
{
	var buildings = [housesA, housesB, supermarket]
	image(buildings[this.index], this.x, this.y);
}

//Create lamps and signs - Rachel Kim
function createStreetItems(bx, by, i)
{
	var items = {x: bx, y: by, index: i, display: drawStreetItems}
	return items;
}

//Render lamps and signs - Rachel Kim
function drawStreetItems()
{
	push();
	scale(0.5,0.5); //Scale because too big
	var streetItems = [streetSign,lampPost]
	image(streetItems[this.index], this.x, this.y);
	pop();
}

//Create clouds - Rachel Kim
function createClouds(bx, by, s)
{
	var cld = {x: bx, y: by, speed: s, display: drawCloud, update: updateCloud}
	return cld
}

//Render clouds - Rachel Kim
function drawCloud()
{
	image(cloud, this.x, this.y);
}

//Add speed to clouds - Nick Wong
function updateCloud()
{
	this.x -= this.speed;
}

//Reset game by setting all values and lists to default - Nick Wong
function resetGame()
{
	covids = [];
	platforms = [];
	clouds = [];
	backgroundBuildings = [];
	streetItems = [];
	stagePos = 0;
	defaultSpeed = 2;
	constantSpeed = 2;
	setup();
	startGame = true;
	gameOver = false;
}

//Spacebar input - Both Rachel and Nick
function keyPressed()
{
	//Spacebar is pressed
	if(keyIsDown(32))
	{
		//Check if not in air - Nick Wong
		if(pl1.grounded || pl1.onPlatform)
		{
			pl1.dy -= jumpForce; //Jump if player is not in the air
		}

		//Reset game if game over - Rachel Kim
		if(gameOver)
		{
			resetGame();
		}

		//Start game if first time opening - Rachel Kim
		if(!startGame)
		{
			resetGame();
		}

	}
}




For the final project, we wanted to create a side-scrolling game that related to Covid-19. In order to start the game, the only thing that the user needs to do is press the space bar in order for the player to jump. This type of game presents a screen that continuously scrolls while the player jumps to avoid obstacles. Two obstacles that the player faces are Covid-19 particles and platforms. The more obstacles the player overcomes, the speed of the game also increases as well. Once the player fails to avoid the Covid-19 particles or overcome the platforms, the player loses the game, and the “Game Over” screen would show up. In order to restart the game, the user would have to press the space bar. Overall, we both thought it would be fun to create a side-scrolling game for the final project of this course.

Throughout the process of this project, we faced a few challenges such as dynamic collision detection and graphical elements. Therefore, with time constraints, we were not able to play-test the game as much as we wanted to. Although there are a couple of flaws to the game, we had fun being able to create a side-scrolling game with colorful visuals. If we had more time, we would have refined the dynamic collision detection system, added in a more specific algorithm for creating obstacles and platforms, and fix the colors of the graphical elements. Additionally, we would also think about incorporating power-ups (masks, hand sanitizer, etc.) and sound as well.

Final Project

peachsketchfinal
//Sarah Kwok Section B
//sarahkwo


var walkImage = []; //holds sprite walk cycle  
var People = []; //holds randomly sprouting museum-goers
var yloc = 300; //y location of walking figure
var z = 600; //month image x coordinate
var months = []; //holds images for each of the months
var imageWidth = 300; 
var imageHeight = 175;
var r = 0; //x location of rope
var imageLoc = 100; //image y coordinate
var monthfiles = []; //loads month images
var monthindex = 0; // keeps track of which month function is at
var monthnames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]
//emotions matching the events
var emotions = ["R.I.P.", ":(", "!!!", ":0", "bzzz", "BLM", "take off!","prayers","R.I.P.","lol","SAVED", ":)"]
//news headlines matching events 
var commentary = ["Basketball icon Kobe Bryant passes away in tragic accident", 
"Wildfires ravage forests and wildlife around the world",
"Coronavirus is declared a global pandemic", 
"The Pentagon releases never seen before UFO footage",
"Killer Hornets found in Seattle!",
"Black Lives Matter protests sweep the nation",
"SpaceX launches first commercial flight",
"Warehouse explosion devastates Beirut",
"Supreme Court Justice Ruth Bader Ginsburg passes away",
"President Cheeto gets COVID-19",
"Joe Biden wins the 2020 Presidential Election",
"Several promising vaccines emerge. The future seems bright."]

function preload(){

rope = loadImage("https://i.imgur.com/Opiv3O8.png")
frame = loadImage("https://i.imgur.com/ZNqHge9.png")
thoughtbubble = loadImage("https://i.imgur.com/BLov0ZV.png")
	
    //walk cycle sprite images
    var filenames = [];
    filenames[0] = "http://i.imgur.com/svA3cqA.png";
    filenames[1] = "http://i.imgur.com/jV3FsVQ.png";
    filenames[2] = "http://i.imgur.com/IgQDmRK.png";
    filenames[3] = "http://i.imgur.com/kmVGuo9.png";
    filenames[4] = "http://i.imgur.com/jcMNeGq.png";
    filenames[5] = "http://i.imgur.com/ttJGwkt.png";
    filenames[6] = "http://i.imgur.com/9tL5TRr.png";
    filenames[7] = "http://i.imgur.com/IYn7mIB.png";

    for (var i = 0; i < filenames.length; i++) {
        walkImage[i] = loadImage(filenames[i]);
    }

    //images for each month
    monthfiles[0] = "https://i.imgur.com/IzzQZ2Z.jpg"
    monthfiles[1] = "https://i.imgur.com/RY8heXd.jpg"
    monthfiles[2] = "https://i.imgur.com/6HM3WnG.jpg"
    monthfiles[3] = "https://i.imgur.com/oBki9og.png"
    monthfiles[4] = "https://i.imgur.com/asttHaY.jpg"
    monthfiles[5] = "https://i.imgur.com/z1d6yIB.jpg"
    monthfiles[6] = "https://i.imgur.com/Acilo1q.jpg"
    monthfiles[7] = "https://i.imgur.com/E1mWLZS.jpg"
    monthfiles[8] = "https://i.imgur.com/UkKfRWx.jpg"
    monthfiles[9] = "https://i.imgur.com/14WgN8Z.jpg"
    monthfiles[10] = "https://i.imgur.com/EWo1aiy.jpg"
    monthfiles[11] = "https://i.imgur.com/vW73ESI.jpg"

for (var j = 0; j < monthfiles.length; j++){
	months[j] = loadImage(monthfiles[j]);
}

}

//sprite character walks in place w/ scrolling background 
function stepCharacter (){

    if (this.imageNumber < 7){
    	this.imageNumber ++
    }
    else {
    	this.imageNumber = 0
    }
}

function drawCharacter (){
	image(walkImage[this.imageNumber], this.x, this.y);
}

function makeCharacter(px, py, pdx, pdy) {
    p = {x: px, y: py,
         imageNumber: 0,
         stepFunction: stepCharacter,
         drawFunction: drawCharacter
        }
        return p;
}

var characters = [];

function setup() {

    createCanvas(600, 500);
    frameRate(25)
    textAlign(CENTER)
    textSize(18);
    textStyle(BOLDITALIC);
    textFont('Georgia');
       var p = makeCharacter(100, yloc,5,1) 
       characters.push(p);

    for (var i = 0; i < 5; i++){
        var rx = random(width);
        var ry = random(height/5*3, height);
        People[i] = makePeople(rx, ry);
    }
}


function draw() {

background(122, 24, 49)
fill(61, 29, 7)
    rect(0,height/4*3, width, height);
fill(0)
//update and draws sprite character

//when the image disappears off the left side of canvas, the x location is reset for next image
//after December scrolls past, cycle loops, and program never ends
if (z <  -imageWidth) {
	z = width
	if (monthindex == months.length-1){
		monthindex = 0
	}
	else {monthindex ++}
}

z -= 5


//cycles through array of month images 
	image(frame, z-20, imageLoc -20, imageWidth+40, imageHeight+40)
	image(months[monthindex], z, imageLoc, imageWidth, imageHeight) 
    fill(222, 197, 109)
    stroke(222, 197, 109)
    rect(z-125, imageLoc+imageHeight -25, 110, 35)
    fill(0)
	text(monthnames[monthindex],z - 70, imageLoc+imageHeight)
    noStroke()

//rope scrolls, and, when rope image leaves canvas, redraws on other side 
if (r < -600){
    r = -5
    }

r -= 5

image(rope, r,height/4*3-65)

//update sprite walks
push();
    p.stepFunction();
    p.drawFunction();
pop();

//people (other people at the museum) randomly spawn
    updatePeople();
    removePeople();
    addNewPeople(); 

//if mouse is pressed, corresponding headline appears at top of screen and sprite character reacts
    if (mouseIsPressed){

        image(thoughtbubble, 150, yloc - 55, 90,80)
        text(emotions[monthindex], 195, yloc-25)
        fill(255)
        text(commentary[monthindex], width/2,50)
        noFill()
    }

}

//people move at same rate as background scrolls, making it seem as though they are standing
function updatePeople(){
    for (var i = 0; i < People.length; i++){
        People[i].move();
        People[i].display();
    }
}

function removePeople(){
    var PeopleToKeep = [];
    for (var i = 0; i < People.length; i++){
        if (People[i].x + People[i].breadth > -50) {
            PeopleToKeep.push(People[i]);
        }
    }
    People = PeopleToKeep; 
}

function addNewPeople() {
    var newPeopleLikelihood = 0.05; 
    if (random(0,1) < newPeopleLikelihood) {
        People.push(makePeople(width, random(height/5*3, height)));
    }
}

function PeopleMove() {
    this.x += this.speed;
}
  
//randomly translate canvas and call object at these locations to draw people
//the other people are random indexes called from sprite walkimage array   
function PeopleDisplay() { 
    push();
    translate(this.x, this.y);
   image(walkImage[this.randomImage], this.breadth, this.nsize)
    pop();
}


function makePeople(birthLocationX, birthLocationY) {
    var People = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -5.0,
                nsize: round(random(20,40)),
                randomImage: floor(random(8)),
                move: PeopleMove,
                display: PeopleDisplay}
    return People;
}

My program is an animation with some user interactivity. It depicts a character walking through a museum that is representative of the year 2020. Each month is marked by an image of a major event that took place that month. While the character walks, if the viewer presses the mouse, a text description corresponding to each event appears as well as a thought bubble and reaction from the walking figure. On a coding level, I was inspired by the scrolling landscapes, and thought I could apply it in a more layered and complex way. Going through the indices of the array (to change the months) while also timing the scrolling (and corresponding further with the ropes) was much more difficult than I had expected! On a conceptual level, I was inspired to create the Museum of 2020 after my sister was shocked remembering that the murder hornets emerged this year, rather than a longer time ago. It has been a long year marred by unprecedented events, and I thought it would be interesting to revisit these moments that defined the world. If I had more time, I would have wanted to try introducing a more three dimensional element, such as manipulating camera views in order to show different aspects/perspectives/rooms of the museum. I also think it would be difficult to try to pause the program and have the sprite figure turn to each of the images and consider each one.

Final Project: Santa and Rudolph Take on COVID-19

For my project, I wanted to do a Christmas themed game that still demonstrated the severity of COVID-19. For example, the starting screen gives context to the situation, in which all of Santa’s reindeer, except Rudolph, are sick with COVID-19. Therefore, Rudolph is calling on the user to help guide him and Santa through the sky to collect presents and avoid COVID-19.

How the user plays the game: The user plays by clicking on the “START” button on the start screen. This will then take the user to the game, where they will move their mouse up and down to avoid the floating COVID particles, and come in contact with the floating presents in the sky. The user will die and be sent to the “Game Over” screen if they come into contact with the COVID-19 particles floating in the sky. The user will be sent to the “Winner” screen if they can successfully collect 15 presents without touching COVID-19.

I specifically made my code to respond to clicks on a starting button and collisions with presents and COVID-19 particles. For the mouse interaction, I mapped the Y location of the mouse to a smaller range of Y values because I wanted the mouse to not be able to go off of the bottom edge of the canvas too easily, especially because the mountains conceal some of the view. By mapping it, I found that the mouse interaction would have to be in a very far Y location (past 480, the height of the canvas) in order to go off of the screen, and I thought this was better for user control, as the mouse can be very sensitive.

If I had more time, I would have liked to included some audio that made a subtle ‘clink’ noise when collecting presents, and more Christmas-like audios, because what is December without Christmas songs? I would have also like to have more control of how quickly and how frequently the COVID-19 particles and presents were generated. Sometimes they tend to overlap slightly, or the objects tend to be placed so close together that it is hard to collect a present without touching COVID-19 due to lack of space. Overall, I am pleased with this project. 🙂

sketch
//Annie Kim
//anniekim@andrew.cmu.edu
//Section B
//Final Project

/* 
WHAT FULFILLED EACH REQUIREMENT FROM MY PROJECT:
ARRAYS : arrays used for the snowy mountains, snow, presents, and covid
USER-DEFINED OBJECT : presents, covid, snow, and snowflakes (on end screen)
CONDITIONAL PROGRAMMING : if/else for snowflakes on winner screen, if for start button, etc
LOOPS : used for snow, mountains, presents, covid, etc
USER-DEFINED FUNCTION : the snowflake function called in winner screen
TRANSFORMATIONS : rotating covid particle on start screen
*/


/* ~~GLOBAL VARIABLES~~*/ 
//making the snow landscape:
var hillvalue = []; //array for values
var noiseParam = 0;
var noiseStep = 0.009; //rounding the hill values
//start screen alternating to game:
var mode = 0; 
//images variable stated:
var tree; //holds tree png image
var rudolph; //holds rudolph png image
var santa; //holds santa png image
var covid; //holds covid png image
//snow falling (object):
var snow = []; 
var numSnow = 1000;
//rotation
var angle = 0;
//covid particles
var covidGerm = [];
var newCovidLikelihood = 0.015;
//gift "particles"
var gifts = [];
var newGiftLikelihood = 0.02;
//to slow Santa and sled from going off of the screen
var mouseYmapped;
//present counter
var collected = 0;


function preload() { //preloading images that I drew
	tree = loadImage("https://i.imgur.com/gr2EEki.png");
	rudolph = loadImage("https://i.imgur.com/9zvf4hQ.png");
	santa = loadImage("https://i.imgur.com/1oJP4Sx.png");
	covid = loadImage("https://i.imgur.com/RW2zPYi.png");
	present = loadImage("https://i.imgur.com/dZPuHKd.png");
	snowflake = loadImage("https://i.imgur.com/MJawG90.png");
	ripSanta = loadImage("https://i.imgur.com/0c4yP1h.png");
}

function setup() {
    createCanvas(600, 480);
    background(24, 41, 81);
    //setup for the snowy mountains
    for (var i = 0; i <= width/5; i ++) {
    	var n = noise(noiseParam); //value from 0 to 1
    	var value = map(n, 0, 1, height/2, height); 
    	hillvalue.push(value);
    	noiseParam += noiseStep;
    }
    //setup for the snow falling
    for (var j = 0; j < numSnow; j++) {
    	var s = makeSnow(random(0, 600), random(-100, 480), random(-3, 3), 0);
    	snow.push(p);
    }
    frameRate(10);
} 


function draw() {
	//different screen modes
	if (mode == 0) {
		startScreen();
	}
	if (mode != 0) {
		gameStart();
		hills();
	}
} 


function startScreen() { //start screen of the game
	textAlign(CENTER, CENTER);
	textSize(20);
	textFont("GeorgiaBOLD");
	background(24, 41, 81);
	fill(255);
	//instructions and context
	text("The other reindeer are all sick with COVID-19.", width/2, 40);
	text("Press the START button to help Santa and Rudolph on Christmas night!", width/2, 80);
	fill(255);
	text("Move your mouse up and down to guide Santa, and his sled", width/2, 120);
	text("away from COVID-19, and collect the presents!", width/2, 160);
	text("COLLECT 15 PRESENTS TO WIN!", width/2, 200);
	//start button shape
	fill(157, 214, 232);
	noStroke(); 
	rect(210, 400, 180, 65);
	fill(255);
	rect(220, 410, 160, 45);
	fill(0);
	textSize(35);
	text("START", width/2, 435);
	image(tree, -6, 202, 230, 300);
	image(rudolph, 370, 198, 230, 320);
	//rotating covid particle image
	push();
	translate(300, 310);
	rotate(radians(angle));
	image(covid, -85, -85, 170, 170);
	angle -= 5;
	push();
} 


function gameStart() {
    mouseYmapped = map(mouseY, 0, 480, -100, 200);
	fill(24, 41, 81);
	rect(0, 0, 600, 480);
	hills();
	//BOX THAT IS THE "COLLECTED" AREA BEHIND SANTA AND SLED:
	noStroke();
	fill(24, 41, 81); 
	rect(25, mouseYmapped + 15, 230, 110);
	//cue falling snow
	snowingSnowflakes();
	//counter sign
	fill("white");
	strokeWeight(1);
	textSize(30);
	textFont("Times New Roman");
	text("Collected : " + collected, 300, 25);
	image(santa, 0, mouseYmapped, 270, 150);
	//adding "floating" covid particles and presents
	addNewGiftsWithSomeRandomProbability();
	updateAndDisplayGifts();
	updateAndDisplayCovid();
	addNewCovidWithSomeRandomProbability();
} 


function gameOver() {
	fill(0);
	rect(0, 0, 600, 480);
	fill("red");
	stroke("red");
	textSize(60);
	textFont("Times New Roman");
	//game over sign
	text("GAME OVER!", width/2, height/2);
	textSize(30);
	textAlign(LEFT);
	//reminder to refresh to play again
	text("Refresh to play again!", 5, 30);
	//santa's grave image
	image(ripSanta, 200, 12, 270, 200);
}


function gameWin() {
	fill(24, 41, 81);
	rect(0, 0, 600, 480);
	fill("green");
	stroke("green");
	textSize(60);
	textFont("Times New Roman");
	//game winner sign
	text("WINNER!", width/2, height/2 - 100);
	//reminder to refresh to play again
	text("Refresh to play again!", width/2, height/2 - 30);
	//use of snowflakes for decoration
	snowflakes(100, 90);
	snowflakes(300, 60);
	snowflakes(500, 90);

}


function mousePressed() {
	//helps move user from start to game stage
	if (mouseX > 210 & mouseX < 390) {
		if (mouseY > 395 && mouseY < 470) {
			mode = (mode + 1);
		}
	} 
} 


function hills() {
	if (hillvalue.length > 80) { //making hills moves
		hillvalue.shift();
		frameRate(8);
		for (var i = 0; i < width / 5; i ++) {
			var n = noise(noiseParam);
			var value = map(n, 0, 1, height/2, height);
			hillvalue.push(value);
			noiseParam += noiseStep;
		}
	}
	fill(248);
	noStroke();
	beginShape(); //making the hills randomly
	for (var i = 0; i < width/5; i ++) {
		vertex(i*5, hillvalue[i]);
	}
	vertex(width + 150, height);
	vertex(0, height);
	endShape();
} 


function makeSnow(px, py, pdx, pdy) {//snow object
	p = {x: px, y: py,
		dx: pdx, dy: pdy,
		age: 0,
		size : random(1, 4),
		color: color(255),
		stepFunction: snowStep,
		drawFunction: snowDraw
	}
	return p;
} 

//specifying the object
function snowDraw() {
	stroke(this.color);
	strokeWeight(this.size);
	point(this.x, this.y);
} 

//making the snowflakes "bounce" subtly off of the edges 
//of the canvas so they dont disappear off of the screen
function snowStep() {
	this.age++;
	this.x += this.dx;
	this.y += this.dy;
	if (this.x > width) {
		this.dx = -this.dx;
	} else if (this.x < 0) {
		this.dx = - this.dx;
	}
} 

//snowflakes in the background of game screen
function snowingSnowflakes() {
	for (var i = 0; i < numSnow; i ++) {
		var s = snow[i];
		s.stepFunction();
		s.drawFunction();
	}
}

//adding to covid array 
function updateAndDisplayCovid() {
	for (var i = 0; i < covidGerm.length; i++) {
		covidGerm[i].move();
		covidGerm[i].display();
		//deleting covid from array once touched
		//and triggering game over screen when touched
		if (covidGerm[i].x < 255 & covidGerm[i].x > 25) {
			if (covidGerm[i].y < mouseYmapped + 110 && covidGerm[i].y > mouseYmapped + 15) {
				covidGerm.splice(i, 5);
				gameOver();
				noLoop();
			} 
		}
		//if user wins, delete covid from array to make it not show
		if (collected == 15) {
			covidGerm.splice(i, 10);
			noLoop();
		}
	}
}

//randomly making covid particles with a probability
function addNewCovidWithSomeRandomProbability() {
	if (random(0,1) < newCovidLikelihood) {
		covidGerm.push(makeCovid(random(600, 650), random(0, 270)));
	}
} 


function moveCovid() { //speed of covid movement
	this.x += this.speed;
} 


function drawCovid() { //covid scaled size and x/y location
	image(covid, this.x, this.y, 45, 45);
} 


function makeCovid(locationX, locationY) {//covid object
	var covidGerm = {x: locationX,
	y: locationY,
	speed: random(-5, -8),
	move: moveCovid,
	display: drawCovid
	}
	return covidGerm;
} 

//updating and adding to array of presents
function updateAndDisplayGifts() {
	for (var i = 0; i < gifts.length; i ++) {
		gifts[i].move();
		gifts[i].display();
		//deleting present from array once touched
		if (gifts[i].x < 255 & gifts[i].x > 25) {
			if (gifts[i].y < mouseYmapped + 110 && gifts[i].y > mouseYmapped + 15) {
				gifts.splice(i, 1);
				collected += 1;
				//if user wins, game win screen shows
				if (collected == 15) { 
					gameWin();
					noLoop();
					gifts.splice(i, 10);
				}
			}
		}
	}
}

//adding presents randomly
function addNewGiftsWithSomeRandomProbability() {
	if (random(0,1) < newGiftLikelihood) {
		gifts.push(makeGifts(random(600, 650), random(0, 270)));
	}
}


function moveGifts() { //presents moving speed
	this.x += this.speed;
}


function drawGifts() { //drawing presents at this scale and x/y location
	image(present, this.x, this.y, 55, 55);
}


function makeGifts(locationX, locationY) { //present object
	var gifts = {x: locationX,
		y: locationY,
		speed: random(-10, -7),
		move: moveGifts,
		display: drawGifts
	}
	return gifts;
}


function snowflakes(x, y) { //my user-defined function
	var w;
	var h;
	//if snowflake is on the lefthand third of canvas, make it 
	//size 130
	if (x < 200) {
		w = 130;
		h = 130;
		//if snowflake is in middle of canvas, make it size 100
	} else if (x > 200 & x < 400) {
		w = 100;
		h = 100;
		//if snowflake is on righthand third of canvas, make it
		//size 130
	} else {
		w = 130;
		h = 130;
	}
	imageMode(CENTER);
	image(snowflake, x, y, w, h);
}


















Final Project: An Animated Rant

For my final project I was inspired by the Facebook page Zoom memes for self quarantines. Over the course of the past semester I’ve found posts that I really resonated with. Although it is a meme page – there are a lot of references to mental health and how the current pandemic and other social issues are affecting our lives beyond the Zoom classroom stress. My project uses mainly black and white colors to reflect the seriousness of the issue and to address topics of funny conversations as something bigger than that and in dire need of attention.

Beyond being a student, I also work full-time so life was getting difficult to balance. So I also found aspects of this rant to encompass elements of work from home life as well and that I do understand both sides of the story.

Now to get into how the program works. It is an interactive “flip book” where you can interact with certain pages with your cursor. Simply moving the cursor along the x and y axis of certain pages reveals new elements or changes existing one. Each of the interactions are in place to put emphasis on certain aspects of the text components but some are only animations. If I had more time to flush out some more details – I would have liked to add flame element to the last page. I think that additional interaction would have also made it more engaging.

Please feel free to interact with it below 🙂

sketch

//Helen Cheng
//helenc1@andrew.cmu.edu
//Final Project
//Section C

// text verses
var page1 = ["i'm tired.", "school is hard.", " navigating life", "during a pandemic", "is hard."]
var page2 = ["staring at a screen from ", "morning to night is hard on my eyes.",
"my vision is becoming fuzzy"];
var page3 = ["paying attention during a Zoom lecture is hard.",
"i already couldn't pay attention in person."]
var page4 = ["doing homework is hard.", "i'm not procrastinating",
"i have 3 homeworks,", "an exam,", "and a project,", "all due on the same day",
"i have to choose which one i don't want to", "'procrastinate on this time.'"];
var page5 = ["it feels like", "i'm overwhelmed"];
var page6 = ["you might feel the same way too.", "so let's all just be kind"]
var page7 = ["has anyone stopped to ask us how we feel?"]
var page8 = ["i'm burnt out."];

// global variables
var pageTracker = 0;
var sentenceTracker = 0;

//for text avoidance function
var minMouseDist = 1000;

//var for helper functions
var floater = [];

function setup() {
    createCanvas(500, 500);
    background(0);
    frameRate(1);
    textAlign(LEFT);
    textFont("serif", 20);
    imageMode(CENTER);

    //setup for page 4 - mouse repelling letters
    //characters into array
    points = new Array(page4[1].length);
    for (var i = 0; i < points.length; i++) {
        points[i] = new Array(2);
    }
    var textW = textWidth(page4[1]);
    var s2 = "";
    // logs location of characters
    for (var i = 0; i < page4[1].length; i++){
        var charPosn = textWidth(s2);
        points[i][0] = createVector((width - textW) / 2 + textWidth(s2), height / 2);
        s2 = s2 + page4[1].charAt(i);
        console.log("s2: " + s2);
    }
    console.log(points);

    //setup for floaters
    for (var i = 0; i < 100; i++) {
        floater.push(makeFloaters(random(width), random(height), 
            random(30), color(random(255), 0, 0), random(-5, 5), random(-5, 5)));
    }
}


function draw() {
    background(0);
    fill(255);

    // starting screen with instructions
    if (pageTracker == 0) {
        textSize(42);
        text("new frustrations", 200, 250);
        textSize(20);
        text("an interactive rant: flip through with arrow keys", 50, 400);
        text("interact by moving your mouse", 50, 450);
        text(concat(str(pageTracker), "/8"), 450, 450);
    }

    //auto displays all strings in a simple animation
    else if (pageTracker == 1) {
        background(0);
        textSize(42);
        text(page1[sentenceTracker], 50, 250);
        textSize(20);
        text(concat(str(pageTracker), "/8"), 450, 450);
    
        if (sentenceTracker < 4) {
            sentenceTracker += 1;
        } 
   }
   //red floaters mimic tired eyes
   else if (pageTracker == 2) {
        frameRate(10);
        animation2();
        for (var i = 0; i < 100; i++) {
            floater[i].drawFunction();
            floater[i].moveFunction();
        }
   }
   //flashing letters makes text harder to read and references attention issues
   else if (pageTracker == 3) {
        animation3();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //red text avoids cursor to represent procrastination
   else if (pageTracker == 4) {
        animation4();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseY affects text size
   else if (pageTracker ==5) {
        animation5();
        textSize(20);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseX reveals two sides
   else if (pageTracker == 6)  {
        animation6();
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //mouseY turns a smile upside down
   else if (pageTracker == 7) {
        animation7();
        text(concat(str(pageTracker), "/8"), 450, 450);
   }
   //flashing red text simulates emergency or error text above toaster
   else if(pageTracker == 8) {
        animation8();
        textSize(20);
        fill(255);
        text(concat(str(pageTracker), "/8"), 450, 450);
   }

}

// the page turner 
function keyPressed() {
    background(0);
    if (keyCode === LEFT_ARROW) {
        pageTracker -= 1;
    }
    else if (keyCode === RIGHT_ARROW) {
        pageTracker += 1;
    }

}

//page 5 helper functions
function makeFloaters(x, y, s, c, dx, dy) {
    var floater = new Object();
    floater.x = x;
    floater.y = y;
    floater.size = s;
    floater.c = c;
    floater.dx = dx;
    floater.dy = dy;
    floater.drawFunction = drawFloaters;
    floater.moveFunction = moveFloaters;
    return floater;
}

function moveFloaters() {
    this.x += this.dx;
    this.y += this.dy; 
}

function drawFloaters() {
    fill(this.c);
    ellipse(this.x, this.y, this.size);
}

//page 2: random circles float across the screen to mimic tired eyes
function animation2() {
    fill(255);

    textFont("serif", 20);

    text(page2[0], 100, height/4);
    text(page2[1], 200, height/2);
    text(page2[2], 100, 3*height/4);

    text(concat(str(pageTracker), "/9"), 450, 450);
}


//page 3: moving in and out of focus mimics attention disorders
function animation3() {
    strokeWeight(0);

    fill(128 + sin(frameCount*0.2) * 128);

    text(page3[0], 50, height/3);
    text(page3[1], 50, height/2);
}

//page 4: all text displayed at once but is repelled by cursor
//to symbolize avoidance/procrastination
function animation4() {
    background(0);
    text(page4[0], 50, 50);
    for (var i = 2; i < 8; i++){
        if (i < 5) {
            text(page4[i], 50, 50*i);
        }
        else {
            text(page4[i], 50, 400+50*(i - 6));
        }
    }
    //repels text from cursor
    for(var i = 0; i < points.length; i++){
        var p = points[i][0];
        var p2 = createVector(0, 0);
        var mouseDist = dist(p.x, p.y, mouseX, mouseY);
    
        if(mouseDist < minMouseDist){
            p2 = createVector(p.x - mouseX, p.y - mouseY);   
            var distDifference = minMouseDist - mouseDist;
            p2.setMag(sqrt(distDifference));
    }
    points[i][1] = p2;
    //draws text
    fill(255, 0, 0);
    text(page4[1].charAt(i), p.x + p2.x, p.y + p2.y);
    }   
}

//page 5: text grows in size with mouse position
function animation5() {
    text(page5[0], 100, height/3);
    textSize(mouseY/4);
    text(page5[1], 100, height/2);
}

//page 6: text reveals to show the two sides/perspectives
function animation6() {
    fill(255);
    rect(0, 0, mouseX/2, 500);
    rect(500, height, mouseX/2, 500);
    fill(255);
    text(page6[0], 100, height/3);
    fill(0);
    text(page6[1], 100, height/2);
}

//page 7: smiley face turns from smile to frown
function animation7() {
    ellipse(200, 200, 50, 70);
    ellipse(300, 200, 50, 70);
    //smiles at top half, frowns at bottom half of canvas
    noFill();
    strokeWeight(5);
    stroke(255);
    if (mouseY < 250) {
        arc(250, 300, 100, 50+mouseY/5, 0, PI);
    }
    else {
        arc(250, 300, 100, mouseY/5, PI, 2*PI);
    }
    strokeWeight(0);
    fill(255);
    text(page7[0], 80, 100);
}

//page 8: toaster
function animation8() {
    rectMode(CENTER);
    var toaster = 300;
    //toaster side view
    fill(220);
    rect(width/2, height/2, 200, 100);
    ellipse(170, 210, 50, 30);
    ellipse(330, 210, 50, 30);
    rect(width/2, 300, 220, 20);
    rect(350, 230, 20, 10);
    fill(128 + sin(frameCount*0.2) * 128, 0, 0);
    
    textSize(40);
    text(page8[0], 140, 100);
}

Final Project: Monument to the Lost Year

The program that I created for the final project is the Memorial to the Lost Year, a group of digital monuments about the year 2020. I was inspired to create this memorial because I was reflecting on previous pandemics in world history and how we remember those today, and I was curious as to how future generations would reflect upon the Covid-19 Pandemic and the behavioral and cultural changes that came with it. Aesthetically, the collages I created as for each scene were inspired by the work of Cruz Garcia and Nathalie Frankowski and the collages I made while taking a class taught by them this summer.

A local host is needed to run the program. The program starts at a floor plan of the different areas. If the user clicks on the red marker associated with an area they are transported to that scene. At the Entrance Gallery, the user can flip through a selection of images related to life in the year 2020 by clicking the canvas. In the Zoom Monument Scene the user can place candles by clicking on the pedestal. At the Covid-19 Statue, the user is invited to focus on the spinning rings and to meditate or reflect on the pandemic. At the 2020 Election Memorial, users can click the Vote button to submit a mail-in ballot. To move between scenes, the user can press the left arrow key to return to the floor plan and then click on a different red marker.

If I had more time, I would have liked to add more exhibits to the memorial that covers more aspects of life in the year 2020.

monumentDownload

/*Image Sources:
	Zoom Monument Collage:
		Background: https://1.bp.blogspot.com/-clsypiRLZo4/XOPVE1F8TgI/AAAAAAAGZm4/3NzoNNpDCuo5w66qzYwf75csYIhacaj8QCLcBGAs/s1600/Worthington-Whittredge-Foothills-Colorado.jpg
		Zoom Logo: https://humtech.ucla.edu/wp-content/uploads/2018/08/zoom-560x560.png
		Pedestal: https://kingdomhigh.com/image/cache/data/orlandi/provence-riser-stand-pedestal-statue-base-15in-stone-statue-fs8216-orn-fs8216-200142557-700x700.jpg
	Covid-19 Statue Collage
		Background: https://www.thewadsworth.org/wp-content/gallery/hudson-river-school/copy_0_1868.3.jpg
		Sky: https://www.artfixdaily.com/images/fl/july2_cropsey1500x813.jpg
		virus: https://source.wustl.edu/wp-content/uploads/2018/12/flu.jpg
		column: https://victoriafrederick.files.wordpress.com/2014/09/loadbearing-polystone-columns-architectural-columns-roman-corinthian-fluted-columns.jpg
		marble texture: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.decomurale.ca%2Fwp-content%2Fuploads%2F2015%2F10%2FS_shutterstock_132172547.jpg&f=1&nofb=1
		Sound: https://freesound.org/people/HerbertBoland/sounds/78448/
	Election Memorial Collage:
		Background: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.thewadsworth.org%2Fwp-content%2Fgallery%2Fhudson-river-school%2F1948.190.jpg&f=1&nofb=1
		Biden Head: https://www.kindpng.com/picc/m/560-5606161_joe-biden-head-hd-png-download.png
		Trump Head: https://basicgestalt.files.wordpress.com/2017/07/trumphead2.png?w=356&h=509
		Bronze Texture 1: https://media.istockphoto.com/photos/bronze-metal-texture-background-picture-id453084961?k=6&m=453084961&s=612x612&w=0&h=AdlZR8A8q8ZXtdDb7aKmYY7rO0iS5Th3OLFKPLUPGFU=
		Bronze Texture 2: https://cdn.wallpapersafari.com/34/19/qP0HSo.jpg
	Image Gallery:
		Collage:
			Background: https://d2jf00asb0fe6y.cloudfront.net/hudson-river-school_05_0abb3e55e0fc49ea59240af9e6e1b9cd.jpg
			Brick Wall: https://jooinn.com/images/brick-wall-154.jpg
		Gallery Images:
			Pence Fly: https://www.india.com/wp-content/uploads/2020/10/mike-pence-debate-1602128479.jpg
			BLM Protest: https://milwaukeerecord.com/wp-content/uploads/2020/06/BLM_PRIDE_MKE_612020-23.jpg
			Biden-Kamala: https://i.dailymail.co.uk/1s/2020/08/21/05/32204630-8649691-Hand_in_hand_Kamala_Harris_and_Joe_Biden_joined_hands_in_the_air-a-16_1597985527220.jpg
			Masks: https://images.assettype.com/swarajya/2020-03/0d8cd05f-25be-4429-b1af-93495e880fef/EThrpG_UwAEEYuA.jfif?w=1280&q=100&fmt=pjpeg&auto=format
			Joe Exotic: https://www.licc.org.uk/app/uploads/2020/05/Tiger-King-Web-MJ-Edit-700x540.png
			Dr. Fauci: https://cspinet.org/sites/default/files/49809803361_8cb800f519_o.jpg
			White House Picket Signs: https://www.vidaenelvalle.com/news/politics-government/ijdvpj/picture247039187/alternates/LANDSCAPE_1140/319913bf2ae577f9ea2d18b8560f6f8b8b025745
			Trump vs Biden: https://stevechabot.com/blog/admin/wp-content/uploads/2020/05/052720-2033-05-500.jpg
			Zoom Meeting: https://d.newsweek.com/en/full/1580408/zoom-meeting.jpg
			Social Distancing: https://qual360.com/wp-content/uploads/2020/04/social-distancing.jpg
*/

var zoomMon;
var floor;
var covidStatue;
var candleColors = ["blue","white","black","green","red"];
var candles = [];
var sceneNumber = 0;
var wind;
var sceneEnter = false;
var election;
var ballots = [];
var wall;
var galleryLinks = ["https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/bidenkamala.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/blmprotest.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/fauci.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/joeexotic.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/masks.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/pencefly.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/socdist.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/trumpbiden.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/whitehousepicket.jpg",
					"https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/zoommeeting.jpg"];
var galleryImages = [];
var chooseImg;
var angle = 0;


function preload() {
    // call loadImage() and loadSound() for all media files here
    //Zoom Monument Scene Background
    zoomMon = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/zoommonument.jpg");
    //Starting Floor Plan
    floor = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/floorplan.jpg");
    //Covid-19 Statue Background
    covidStatue = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/covidstatue.jpg");
    //Wind Sound
    wind = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/wind.mp3");
    //Election Memorial Background
    election = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/election.jpg");
    //Image Gallery Background
    wall = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/imagewall.png");
    //Gallery Images
    for (var i = 0; i < galleryLinks.length; i++){
    	var g = galleryLinks[i];
    	galleryImages.push(loadImage(g));
    }


}



function setup() {
    // you can change the next 2 lines:
    createCanvas(400, 400);
    background(255);
    useSound();
    chooseImg = int(random(0,galleryImages.length));

}

function soundSetup() {
	wind.setVolume(.5);

}


function draw() {
	if (sceneNumber == 0){
		image(floor,0,0,400,400);
		//Zoom Monument Marker
		noStroke();
		fill("red");
		circle(150,170,10);
		//Covid statue marker
		circle(150,290,10);
		//Election Memorial Marker
		circle(250,290,10);
		//Entrance Gallery Marker
		circle(250,170,10);
		fill("black");
		text("Click a Marker to go to that Location",10,20);

	} else if (sceneNumber == 1) {
		zoomMonument();

	} else if (sceneNumber == 2) {
		if (sceneEnter == true){
			wind.loop();
			sceneEnter = false;
		}
		nineteenStatue();
	} else if (sceneNumber == 3){
		electionScene();
		noStroke();
		fill("yellow");
		text("Click 'VOTE!' to Cast Ballot",10,20);
		text("Press the Left Arrow to Return",10,30);
		text("2020 ELECTION MEMORIAL",width/2 + 40,height-20);
	} else if (sceneNumber == 4){
		gallery();
	}

	if (sceneNumber != 2){
		wind.stop();
	}
	if (sceneNumber != 3){
		//empty ballots array when you leave election memorial
		ballots = [];
	}
	if (sceneNumber != 1){
		//empty candles array when you leave zoom monument
		candles = [];
	}

}

function mousePressed(){
	//go to Zoom Monument
	if (mouseX >= 140 & mouseX <= 160 && mouseY >= 160 && mouseY <= 180 && sceneNumber == 0 ){
		sceneNumber = 1;
	}
	//go to Covid Statue
	if (mouseX >= 140 & mouseX <= 160 && mouseY >= 280 && mouseY <= 300 && sceneNumber == 0){
		sceneNumber = 2;
		sceneEnter = true;
	}
	//Candle Object Creation
	if (mouseX >= 132 & mouseX <= 245 && sceneNumber == 1){
		var ca = makeCandles(mouseX,302);
		candles.push(ca);
	}
	//go to Election Memorial
	if (mouseX >= 240 & mouseX <= 260 && mouseY >= 280 && mouseY <= 300 && sceneNumber == 0){
		sceneNumber = 3;
	}
	//Ballot object creation
	if(mouseX >= 5 & mouseX <= 45 && mouseY >= 305 && mouseY <= 345 && sceneNumber == 3){
		var mail = makeMailBallots();
		ballots.push(mail);
	}
	//go to Entrance Gallery
	if (mouseX >= 240 & mouseX <= 260 && mouseY >= 160 && mouseY <= 180 && sceneNumber == 0){
		sceneNumber = 4;
	}
	//Click through Image Gallery
	if (sceneNumber == 4){
		choosingImage();
	}


}

function keyPressed (){
	if (keyCode == LEFT_ARROW){
		sceneNumber = 0;
	}
}

function zoomMonument(){
		image(zoomMon,0,0);
		fill("yellow");
		text("Click Pedestal to Place Candle",10,20);
		text("Press the Left Arrow to Return",10,30);
		text("ZOOM MONUMENT",width/2 + 70,height-20);
		for (var i = 0; i < candles.length; i++){ 
			var c = candles[i];
			c.candleDraw();
		}
}

function nineteenStatue(){
	image(covidStatue,0,0);
	fill("white");
	text("Stare Into the Rings and Reflect",10,20);
	text("Press the Left Arrow to Return",10,30);
	text("COVID-19 STATUE",width/2 + 70,height-20);
	hypnoticRing();
}

function makeCandles(candleX,candleY){
	var candle = {x: candleX, y: candleY,
					candleDraw: drawCandles,
					color: candleColors[int(random(0,candleColors.length))]};
	return candle;
}

function drawCandles(){
	//candle base
	noStroke();
	fill(this.color);
	rect(this.x,this.y,5,-10);
	//flame
	fill("yellow");
	beginShape();
		vertex(this.x + 2.5,this.y - 10);
		curveVertex(this.x,this.y - 15);
		vertex(this.x + 2.5, this.y - 21);
		curveVertex(this.x + 5,this.y - 15);
	endShape();
}

function electionScene() {
	image(election,0,0,);
	voterBox();
	for (i = 0; i < ballots.length; i++){
		var b = ballots[i];
		b.drawMail();
		b.moveMail();
	}
}

function voterBox() {
	noStroke();
	fill(0,255,255);
	rect(0,400,50,-100);
	fill(0,90);
	square(0,300,50);
	fill("red");
	circle(25,325,40);
	fill(0);
	text("VOTE!",9,329);
}

function makeMailBallots() {
	var mail = {x: random(60,width - 20), y: 0,
				dy: random(3,5), color: color(random(0,255),random(0,255),random(0,255)),
				drawMail: mailDraw, moveMail: mailMove,};
	return mail;
}

function mailDraw() {
	strokeWeight(1);
	stroke(0);
	fill(this.color);
	rect(this.x,this.y, 20,10);
	noFill();
	triangle(this.x,this.y,this.x + 20, this.y, this.x + 10, this.y + 5);
}

function mailMove() {
	this.y += this.dy;
}

function gallery() {
	image(wall,0,0);
	fill("white");
	text("Click To Change Image Displayed",10,20);
	text("Press the Left Arrow to Return",10,30);
	text("ENTRANCE GALLERY",width/2 + 70,height-20);
	image(galleryImages[chooseImg],100,height*.5,150,150);
}

function choosingImage() {
	var randImg = 0;
	var newImage = 0;
	//make sure new image that shows isn't the same as the previous
	while(newImage < 1){
		randImg = int(random(0,galleryImages.length));
		if (randImg != chooseImg){
			chooseImg = randImg;
			newImage++;
		}
	}
	return chooseImg;
}

function hypnoticRing() {
	noFill();
	strokeWeight(2);
	var ringColors = [];
	for(var i = 0; i < 4; i++){
		var c = color(random(0,255),random(0,255),random(0,255));
		ringColors.push(c);
	}
	push();
		translate(width/2,height/2);
		stroke(ringColors[0]);
		circle(-20*cos(degrees(angle)),0,100);
		stroke(ringColors[1]);
		circle(20*cos(degrees(angle)),0,100);
		stroke(ringColors[2]);
		circle(-20*cos(degrees(angle)),50*sin(degrees(angle)),100);
		stroke(ringColors[3]);
		circle(20*cos(degrees(angle)),50*sin(degrees(angle)),100);
	pop();

	angle += 10;
}

Final Project: Spot the Difference

My project is a spot-the-difference game with three levels. To relate the project to 2020, I based my game loosely around the concept of isolation and distance.

My game is based off of online spot-the-difference games I used to play by a developer with the screen name “Ivory.” I was inspired by the moody atmosphere that Ivory was able to create using melancholy images and ambient music.

To play the game, simply click on the differences you find. Try to click precisely when making your guess. The number of remaining differences is shown in the top right corner. If you get stuck you can use the hint button for help, which has a short cooldown of 20 seconds. Try to win without any hints though!

sketch


var count = 0; //counter for effects timing

var hint; //variable to hold the "hint" object

var hintcooldown = 0;
var hinttimer = 0;

var scene1bg;
var scene1;    //variable to hold scene images
var scene2;
var scene3;

var scene = 1; //which scene (level) the player is currently on


var margin = 5;   //tolerence for guess clicks

var scene1DifferencesLinks = ["https://i.imgur.com/ohzNdw0.jpg", "https://i.imgur.com/I33D4yq.png", "https://i.imgur.com/4NeqeQR.png", "https://i.imgur.com/awJOkKc.png", "https://i.imgur.com/qLzzqz7.png", "https://i.imgur.com/QbUGoQQ.png", "https://i.imgur.com/a1iMYvd.png"];  //the "differences" are small .jpgs of edited pieces of the image. They will be placed on top of the image to create the "difference"
var scene2DifferencesLinks = ["https://i.imgur.com/f6goqZk.png", "https://i.imgur.com/YdMfKCs.png", "https://i.imgur.com/n3I5MAl.png", "https://i.imgur.com/EYIHAZV.png", "https://i.imgur.com/uu3811U.png", "https://i.imgur.com/e7dqm0J.png", "https://i.imgur.com/V4bhJe8.png"];
var scene3DifferencesLinks = ["https://i.imgur.com/tvCjM0d.png", "https://i.imgur.com/OhlyeMv.png", "https://i.imgur.com/Cr3qy7U.png", "https://i.imgur.com/RttUtn3.png", "https://i.imgur.com/y9AJnzC.png", "https://i.imgur.com/XqaebA2.png", "https://i.imgur.com/wF5Jwgm.png"];

var scene1Differences = [];
var scene2Differences = [];
var scene3Differences = [];

var scene1DifObjs = [];
var scene2DifObjs = [];
var scene3DifObjs = [];

var bgmusic;
var successnoise;

var difsremaining = 7; //tests how many difs left

function preload() {

    scene1bg = loadImage("https://i.imgur.com/oibVoIs.jpg");

    scene1 = loadImage("https://i.imgur.com/oehMn23.png");  //main images for the 3 scenes
    scene2 = loadImage("https://i.imgur.com/PsOlXha.png");
    scene3 = loadImage("https://i.imgur.com/lVsD9Nu.png");
    
    for(i=0; i<scene1DifferencesLinks.length; i++){
        scene1Differences[i] = loadImage(scene1DifferencesLinks[i]);
    }

    for(i=0; i<scene2DifferencesLinks.length; i++){
        scene2Differences[i] = loadImage(scene2DifferencesLinks[i]);
    }

    for(i=0; i<scene3DifferencesLinks.length; i++){
        scene3Differences[i] = loadImage(scene3DifferencesLinks[i]);
    }

    scene1DifObjs.push(makeDifference(scene1Differences[0], 467, 115, 12, 9));  //make the differences. Each difference object contains the x, y, w, and h of the difference. this is the information the rest of the program functions will need to figure out where to place the difference and when the difference is discovered
    scene1DifObjs.push(makeDifference(scene1Differences[1], 213, 15, 2, 11));
    scene1DifObjs.push(makeDifference(scene1Differences[2], 81, 26, 27, 13));
    scene1DifObjs.push(makeDifference(scene1Differences[3], 12, 211, 14, 20));
    scene1DifObjs.push(makeDifference(scene1Differences[4], 281, 329, 25, 26));
    scene1DifObjs.push(makeDifference(scene1Differences[5], 491, 250, 99, 6));
    scene1DifObjs.push(makeDifference(scene1Differences[6], 317, 195, 15, 11));

    scene2DifObjs.push(makeDifference(scene2Differences[0], 527, 219, 47, 8));
    scene2DifObjs.push(makeDifference(scene2Differences[1], 319, 252, 24, 17));
    scene2DifObjs.push(makeDifference(scene2Differences[2], 388, 185, 12, 43));
    scene2DifObjs.push(makeDifference(scene2Differences[3], 47, 339, 82, 33));
    scene2DifObjs.push(makeDifference(scene2Differences[4], 573, 81, 34, 40));
    scene2DifObjs.push(makeDifference(scene2Differences[5], 211, 158, 8, 93));
    scene2DifObjs.push(makeDifference(scene2Differences[6], 413, 352, 19, 16));

    scene3DifObjs.push(makeDifference(scene3Differences[0], 328, 209, 19, 21));
    scene3DifObjs.push(makeDifference(scene3Differences[1], 475, 30, 17, 41));
    scene3DifObjs.push(makeDifference(scene3Differences[2], 262, 293, 12, 53));
    scene3DifObjs.push(makeDifference(scene3Differences[3], -16, 155, 56, 64));
    scene3DifObjs.push(makeDifference(scene3Differences[4], 284, 183, 15, 13));
    scene3DifObjs.push(makeDifference(scene3Differences[5], 172, 298, 56, 60));
    scene3DifObjs.push(makeDifference(scene3Differences[6], 73, 274, 29, 21));


    
    bgmusic = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/104music.mp3");
    successnoise = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/success.wav");


}


function setup() {
    createCanvas(600, 800);
    useSound();
    scene1bg.resize(600, 400);
    frameRate(12);

    hint = {x: 0, y: 0, w: 1, h: 1, alph: 0, drawit: hintDraw, stepit: hintStep};
    
}


function soundSetup() { // setup for audio generation
    bgmusic.setVolume(0.3);
    successnoise.setVolume(1);


}


function draw() {
    // you can replace any of this with your own code:
    background(255);
    bgmusic.play();
    print(difsremaining);
    print(count);

    if(count % 3000 == 0){
        bgmusic.play();
    }

    if(difsremaining == 0){
        difsremaining = 7;
        if (scene == 1) {
            scene = 2;
        } else if (scene == 2){
            scene = 3;
        } else {
            scene = 4;
            count = 1;
        }
    }

    

    if (scene == 1){
        image(scene1bg, 0, 0);
        image(scene1bg, 0, height/2);
        push();
        fill(255, 255, 255, 20);
        rect(0, 0, 600, 800);
        pop();
        image(scene1, 0, 0);
        image(scene1, 0, height/2);  //draw two base scene images

        push();
        fill(255, 255, 255, 150);
        textSize(10);
        text("Differences remaining: " + difsremaining, 470, 15);
        //text("Differences remaining: " + difsremaining, 470, 415);
        pop();

        for(i=0; i<scene1DifObjs.length; i++){
            if(scene1DifObjs[i].found == false){
                scene1DifObjs[i].drawit();
            }
        
        }
        
    }

    if (scene == 2){
        image(scene2, 0, 0);
        image(scene2, 0, height/2);

        push();
        fill(255, 255, 255, 150);
        textSize(10);
        text("Differences remaining: " + difsremaining, 470, 15);
        //text("Differences remaining: " + difsremaining, 470, 415);
        pop();

        for(i=0; i<scene2DifObjs.length; i++){
            if(scene2DifObjs[i].found == false){
                scene2DifObjs[i].drawit();
            }
        
        }

    }

    if (scene == 3){
        image(scene3, 0, 0);
        image(scene3, 0, height/2);

        push();
        fill(255, 255, 255, 150);
        textSize(10);
        text("Differences remaining: " + difsremaining, 470, 15);
        //text("Differences remaining: " + difsremaining, 470, 415);
        pop();

        for(i=0; i<scene3DifObjs.length; i++){
            if(scene3DifObjs[i].found == false){
                scene3DifObjs[i].drawit();
            }
        
        }

    }

    if (hintcooldown > 0){
        push();
        textSize(10);
        fill(255, 255, 255, 150);
        text(hintcooldown, 540, 31);
    }
    if (hinttimer % 12 == 0){
        hintcooldown --;
    }



    hint.drawit(); //hint functions
    hint.stepit();

    drawhintbutton();

    if (scene == 4){
        push();
        image(scene3, 0, 0);
        image(scene3, 0, height/2);
        
        fill(0, 0, 0, count*2.5);
        rect(0, 0, width, height);

        fill(255, 255, 255, count*2.5);
        textSize(50);
        text("END", width/2-50, height/2-10);
        textSize(15);
        text("THANK YOU FOR PLAYING", 205, 450);
        pop();

    }


    
    


    
    if(scene != 4){
        fill(0, 0, 0, 255-count*2.5); //fades in from black

        rect(0, 0, width, height);

    }
  
 
   count++;
   hinttimer++;
}

function mousePressed() {

    if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
        givehint();
    }

    if(scene == 1) {
        for(i=0; i<scene1DifObjs.length; i++){
            if((scene1DifObjs[i].found == false) & (mouseX >= scene1DifObjs[i].x - margin && mouseX <= scene1DifObjs[i].x + scene1DifObjs[i].w + margin) && (mouseY >= scene1DifObjs[i].y - margin && mouseY <= scene1DifObjs[i].y + scene1DifObjs[i].h + margin)) {
                scene1DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene1Differences[i], scene1DifObjs[i].x, scene1DifObjs[i].y);

            }
            if((scene1DifObjs[i].found == false) & (mouseX >= scene1DifObjs[i].x - margin && mouseX <= scene1DifObjs[i].x + scene1DifObjs[i].w + margin) && (mouseY >= scene1DifObjs[i].y + 400 - margin && mouseY <= scene1DifObjs[i].y + 400 + scene1DifObjs[i].h + margin)) {
                scene1DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene1Differences[i], scene1DifObjs[i].x, scene1DifObjs[i].y);

            }
        }

    }
    print(scene1DifObjs[0].found);

    if(scene == 2) {
        for(i=0; i<scene2DifObjs.length; i++){
            if((scene2DifObjs[i].found == false) & (mouseX >= scene2DifObjs[i].x - margin && mouseX <= scene2DifObjs[i].x + scene2DifObjs[i].w + margin) && (mouseY >= scene2DifObjs[i].y - margin && mouseY <= scene2DifObjs[i].y + scene2DifObjs[i].h + margin)) {
                scene2DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene2Differences[i], scene2DifObjs[i].x, scene2DifObjs[i].y);

            }
            if((scene2DifObjs[i].found == false) & (mouseX >= scene2DifObjs[i].x - margin && mouseX <= scene2DifObjs[i].x + scene2DifObjs[i].w + margin) && (mouseY >= scene2DifObjs[i].y + 400 - margin && mouseY <= scene2DifObjs[i].y + 400 + scene2DifObjs[i].h + margin)) {
                scene2DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene2Differences[i], scene2DifObjs[i].x, scene2DifObjs[i].y);

            }
        }

    }

    if(scene == 3) {
        for(i=0; i<scene3DifObjs.length; i++){
            if((scene3DifObjs[i].found == false) & (mouseX >= scene3DifObjs[i].x - margin && mouseX <= scene3DifObjs[i].x + scene3DifObjs[i].w + margin) && (mouseY >= scene3DifObjs[i].y - margin && mouseY <= scene3DifObjs[i].y + scene3DifObjs[i].h + margin)) {
                scene3DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene3Differences[i], scene3DifObjs[i].x, scene3DifObjs[i].y);

            }
            if((scene3DifObjs[i].found == false) & (mouseX >= scene3DifObjs[i].x - margin && mouseX <= scene3DifObjs[i].x + scene3DifObjs[i].w + margin) && (mouseY >= scene3DifObjs[i].y + 400 - margin && mouseY <= scene3DifObjs[i].y + 400 + scene3DifObjs[i].h + margin)) {
                scene3DifObjs[i].found = true;
                successnoise.play();
                difsremaining--;
                flashDif(scene3Differences[i], scene3DifObjs[i].x, scene3DifObjs[i].y);

            }
        }

    }


    

}

function flashDif(img, x, y){   //difference flashes when found
    image(img, x, y);
    image(img, x, y + 400);
  
        img.style.visibility = 'visible';
        img.style.visibility = 'hidden';

    
}


function makeDifference(img, dx, dy, dw, dh) {          //create the difference image as an object
    var difFound = false;                               //keeps track of whether or not the difference has been found
    var dif = {difimage: img, x: dx, y: dy, w: dw, h: dh, drawit: differenceDraw, found: difFound}
    return dif;

}

function differenceDraw() {       //place the difference image on the screen
    image(this.difimage, this.x, this.y);

}

function drawhintbutton() {
    push();
    noStroke();
    if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
        fill(255, 255, 0, 40);
    } else {
        fill(255, 255, 255, 40);
    }
    
    rect(470, 20, 62, 16);
    push();
    if (mouseX>=470 & mouseX<=532 && mouseY>=20 && mouseY<=36 && hintcooldown<0) {
        fill(255, 255, 0, 170);
    } else {
        fill(255, 255, 255, 170);
    }
    textSize(10);
    text("Hint please!", 474, 31);
    pop();
    pop();
}

function givehint(){ //gives the player a hint based on which differences are not found
    if(scene == 1){
        for(i=0; i<=scene1DifObjs.length; i++){
            if(scene1DifObjs[i].found == false){
                hint.x = scene1DifObjs[i].x + random(-60, 60);
                hint.y = scene1DifObjs[i].y + random(-60, 60);
                hint.alph = 200;
                hintcooldown = 20;
                counttimer = 0;
                return;
            }
        }
    }

}

function hintDraw(){
    
    push();
    strokeWeight(2);
    fill(255, 255, 0, 0);
    stroke(255, 255, 0, this.alph);
    ellipse(this.x, this.y, 220, 220);
    pop();
}

function hintStep(){
    this.alph-= 2;
}






Final Project: Among Us Social Distancing Game

My final project is an Among Us-themed social distancing game. Among Us is an online multiplayer game that has gained significant popularity over the last several months during the quarantine. In my game, you play as a crewmate moving through the environment (the cafeteria environment from the Among Us game). Other crewmates are running past you and toward you and your goal is to socially distance from them by controlling your character’s movements with the keys. To make it easier to play within the blog the key controls are: W= up, A=left, S= down, and D= right, but in my submission, the character’s movements are controlled by the arrow keys. If one of the other crewmates enters your social distancing bubble (blue transparent circle around your character), you get a strike, and after five strikes you will lose the game. As you advance through the game, there will be more crewmates to avoid, requiring more skill and dexterity with the keys. You will win the game after successfully social distancing for one minute.
You can change your character’s color on the start screen by hitting enter. You can also click to advance to the instructions page and then again into gameplay. When the game is over you can click to play again. Overall, I am really happy with how this game turned out, but given more time I would add a settings page with a difficulty level selector and a sound option you can adjust before you play.

Social Distancing Game
var timer = 60;	//will hold seconds value for countdown (from 60 seconds)
var diams = [];	//holds diamond tiles of cafeteria floor
var lastOdd = false;	//boolean to determine when rows are eliminated
var startx = 270;	//starting x position for your character
var starty = 250	//starting y position for your character
var crewMate = makeCharacter(startx, starty, true);	//your character
var buddies = [];	//array to hold crewmates onscreen
var someoneInside = false	//is someone inside your social distancing bubble?
var counter = 0;	//how many strikes you have
var gameOver = false;	//did you lose?
var win = false;	//did you win?
var setting = 0;	//which screen you are on (0: starting, 1: instruction, 2: gameplay, 3: defeat, 4: victory)
//variables associated with choosing your character's color------------------------------------------------------------
var charcols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white']; 
var clr = 0;
var colChoice = 'red';	//this array will hold your character's color
//properties for stars on start screen---------------------------------------------------------------------------------
var starx = []; 
var stary = []; 
var stardx = [];
var starsize = [];
//preload game graphics------------------------------------------------------------------------------------------------
let img;
let winimg;
let startimg;
let instruct;

function preload() {
	img = loadImage('https://i.imgur.com/tMs0pNd.png');
	winimg = loadImage('https://i.imgur.com/ff97vVO.pngs');
	startimg = loadImage('https://i.imgur.com/Yy27NCE.png');
	instruct = loadImage('https://i.imgur.com/lIoslK6.png');
}

function setup() {
    createCanvas(600, 600);
    background(165,167,154);
    //set up the grid for the cafeteria floor tiles
    for (var row=0; row < 7; row++){
    	d_row = []
    	if (row % 2 == 0) {
    		for (var col=0; col < 6; col++){
    			if (col % 2 == 0) {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    			else {
    				d_row.push(bigDiamond(col*105+35, row*105+35)) 
    			}
    		}
    		diams.push(d_row)
    	}
    	else {
    		for (var col=0; col < 7; col++){
    			if (col % 2 == 0){
    				d_row.push(bigDiamond(col*105+35, row*105+35))
    			}
    			else {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    		}
    		diams.push(d_row)
    	}
    }
    //set up the array for the crew members that appear
    for (var i=0; i < 3; i++) {
    	buddies[i] = (makeCrew());
    }
    //set up arrays for stars on start screen
    for (var i=0; i<75; i++)  {
			starx[i]= random(width); 
			stary[i]= random(30, height-30); 
			stardx[i]= random(-5, -1);
			starsize[i] = random(3,8) 	
	}
    frameRate(10);
}

function draw() {
	var frameNum = frameCount
	if (setting == 0) {
		startScreen();
	}
	else if (setting == 1) {
		instructionPage();
	}
	else if (setting == 2) {
		gamePlay();
	}
	else if (setting == 3) {
		GameOver();
	}
	else if (setting == 4) {
		GameWon();
	}
	print('frameNum')
}

function mousePressed() {
	if (setting == 0) {	//proceed through the start screen and instructions to the actual gameplay
		setting = 1
	}
	else if (setting == 1) {	//enter gameplay
		setting = 2;	
	}
	//when the game ends, click to play again
	else if (setting == 3) {	
		gameReset()
		setting = 0
	}
	else if (setting == 4) {
		gameReset()
		setting = 0
	}
}
//display the start screen where you can change your character's color
function startScreen() {
	background(0)
	image(startimg, 0, 0, 600, 600);
	for (i=0; i<75; i++) {
		noStroke();
		fill(255);
		circle(starx[i], stary[i], starsize[i]);
		starx[i] += stardx[i]
	}
	starx.shift()	//shift array, moving first value
	stary.shift()
	starsize.shift()
	stardx.shift()
	var newX = 600; 
	var newY = random(30,height-30); 
	var newDX = random(-10, -5);
	var newSize = random(1,8)
	starx.push(newX);
	stary.push(newY);
	stardx.push(newDX);
	starsize.push(newSize);
	push();
	scale(3.75,3.75);
	translate(50,45)
	AmongUs1(colChoice)
	pop();
}
//pressing ENTER on the start screen will change your character's color
function keyPressed() {
	if (keyCode === ENTER & setting == 0){
	if (clr == 10) {
		clr=0
	}
	else {
		clr++; 
	}
	colChoice = charcols[clr]
	}	
}
//instructions: display the instructions for the game
function instructionPage() {
	background(0);
	image(instruct, 0, 0, 600, 600);
	for (i=0; i<75; i++) {
		noStroke();
		fill(255);
		circle(starx[i], stary[i], starsize[i]);
		starx[i] += stardx[i]
	}
	starx.shift()	//shift array, moving first value
	stary.shift()
	starsize.shift()
	stardx.shift()
	var newX = 600; 
	var newY = random(30,height-30); 
	var newDX = random(-10, -5);
	var newSize = random(1,8)
	starx.push(newX);
	stary.push(newY);
	stardx.push(newDX);
	starsize.push(newSize);
}
//reset the gameplay if you play again
function gameReset() {
	//resetting all sketch variables to original values
	frameNum = frameCount
    timer = 60;
	startx = 270;
	starty = 250
	crewMate = makeCharacter(startx, starty, true);	//starting position for your character
	buddies = [];
	someoneInside = false
	counter = 0;
	gameOver = false;
	win = false;
	charcols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white']; 
	clr = 0;
	colChoice = 'red';	//this array will hold your character's color
}
//GAMEPLAY--------------------------------------------------------------------------------------------------------------
function gamePlay() {
	if (timer == 0 & gameOver == false) {
		win = true
		setting = 4
	}
	background(165, 167, 154);
	displayDiamond();
	updateFloor();
	elimRow();
	updateRow();
	crewMate.draw();
	crewMate.update();
	updateRadius();
	drawbuddies();
	removebuddies();
	addMate();
	updatebuddies();
	StrikeCounter();
	Timer();
}
//crewmate constructor
function makeCharacter(x, y, right = true) {
	var c = getColor();
	var guy = {charx: x, chary: y, pos: 1, update: updateCharacter, draw: drawCharacter, col: c, facingRight: right}
	return guy;
}
//ACCESSORIES FOR YOUR CHARACTER---------------------------------------------------------------------------------------
//indicate how far away from others your character needs to be
function socialDistanceBubble(x,y,size) {
	noStroke();
	if (someoneInside == true) {	//if someone is inside your social distance bubble, your bubble turns red
		fill(200,0,0,.1*size)
	}
	else {
		fill(0,0,200,.1*size);
	}
	circle(x, y, size);
}
//function to draw shadow which will appear under your character
function Shadow(x,y) {
	noStroke();
	fill(60,60,60,200);
	ellipse(x, y, 70, 12)
}
//DISPLAY YOUR CHARACTER-----------------------------------------------------------------------------------------------
//display your character with x, y positions and color associated to them
//when you go left, your character will face left
function drawCharacter() {
	socialDistanceBubble(this.charx+30, this.chary+40, 220);
	Shadow(this.charx+30, this.chary+82)
	if (this.facingRight == false){
		push();
		scale(-1,1);
		if (this.pos == 1) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs1(colChoice);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs2(colChoice);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs3(colChoice);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs4(colChoice);
			pop();
		}
		else {
			push();
			translate(-1*this.charx-60, this.chary);
			AmongUs5(colChoice);
			pop();
		}
		pop();
	}
	if (this.facingRight == true) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary);
			AmongUs1(colChoice);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary);
			AmongUs2(colChoice);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary);
			AmongUs3(colChoice);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary);
			AmongUs4(colChoice);
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary);
			AmongUs5(colChoice);
			pop();
		}
	}
}
//UPDATE YOUR CHARACTER'S POSITION-----------------------------------------------------------------------------
//update the among us character function drawn so the guy looks like he is walking
//you can control your character with the arrow keys
//your character cannot travel outside the boundaries of the screen
function updateCharacter(){
	if (keyIsDown(65) & this.charx > 20) {	//"A"
    	this.facingRight = false
    	this.charx -= 10;
  	}
  	if (keyIsDown(68) & this.charx < 540) {	//"D"
    	this.facingRight = true
    	this.charx += 10;
  	}
  	if (keyIsDown(87) & this.chary > 5) {	//"W"
    	this.chary -= 10;
  	}
  	if (keyIsDown(83) & this.chary < 520) {	//"S"
    	this.chary += 10;
  	}
	if (this.pos == 5){
		this.pos = 1;
	}
	else {
		this.pos += 1;
	}
}
//CHECK IF SOMEONE IS INSIDE YOUR SOCIAL DISTANCING BUBBLE------------------------------------------------------------
//update position of crewmate relative to your character
function updateRadius() {
	var inRad = false
	for (var i = 0; i < buddies.length; i++) {
		d = dist(buddies[i].charx, buddies[i].chary, crewMate.charx, crewMate.chary);
		if (d < 110) {
			inRad = true;
		}
	}
	if (inRad == true) {
		if (someoneInside ==  false) {
			counter++;
			if (counter == 5) {
				gameOver = true
				setting = 3
			}
			if (timer == 0 & counter < 5 && gameOver == false) {
				win = true
				setting = 4
			}
		}
		someoneInside = true;
	}
	else {
		someoneInside = false;
	}
}
//GAME FEATURES-------------------------------------------------------------------------------------------------------
//displays the strikes in the bottom left
function StrikeCounter() {	
	stroke(255)
	fill(0)
	strokeWeight(3)
	rect(20,550,160,35);
	noStroke()
	textStyle(BOLD);
	textSize(32);
	fill('#bf0000');	//dark red color for the X's
	if (counter == 1) {
		text('X', 40, 570);
	}
	if (counter == 2) {
		text('X', 40, 570);
		text('X', 70, 570);
	}
	if (counter == 3) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
	}
	if (counter == 4) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
		text('X', 130, 570);
	}
	if (counter == 5) {
		text('X', 40, 570);
		text('X', 70, 570);
		text('X', 100, 570);
		text('X', 130, 570);
		text('X', 160, 570);
	}
}
//display game timer in bottom right corner (countdown from 60 seconds)
function Timer() {
	var frameNum = frameCount
	stroke(255)
	fill(0);
	if (timer <= 10) {
		//noStroke();
		fill('#bf0000')
		textStyle(BOLD)
	}
	textFont('Arial Narrow')
	textAlign(CENTER, CENTER);
  	textSize(32);
  	text(timer, width-25, 570);
  	if (frameNum % 10 == 0) { 
    	timer --;
  	}
}
//displays when game is lost
function GameOver() {
	if (gameOver == true) {
		image(img, 0, 0, 600, 600);
		push();
		scale(5,5);
		translate(25,20)
		Dead1(colChoice)
		pop();
		textFont('Arial Narrow')
		textStyle(NORMAL)
		textAlign(CENTER, CENTER);
	  	textSize(35);
	  	fill(255)
	  	noStroke();
		text('Click to play again', width/2, 550)
		setting = 3
	}
}
//displays when game is won
function GameWon() {
	if (win == true) {
		image(winimg, 0, 0, 600, 600);
		push();
		scale(5,5);
		translate(25,25)
		AmongUs1(colChoice)
		pop();
		textFont('Arial Narrow')
		textStyle(NORMAL)
		textAlign(CENTER, CENTER);
	  	textSize(35);
	  	fill(255)
	  	noStroke();
		text('Click to play again', width/2, 550)	
		setting = 4
	}
}
//CREW (PROPERTIES OF OTHER CREWMATES)-----------------------------------------------------------------------------------
//display crew with x, y positions and color associated to them
function drawCrew() {
	if (this.fig == 0) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary)
			AmongUs1(this.col);
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary)
			AmongUs2(this.col);
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary)
			AmongUs3(this.col);
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary)
			AmongUs4(this.col);
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary)
			AmongUs5(this.col);
			pop();
		}
	}
	else {
		push();
		translate(this.charx, this.chary)
		Dead1(this.col);
		pop();
	}
}
//updates crewmate positions with different speeds (to go down canvas if walking and up if dead)
function updateCrew() {
	if (this.fig == 0) {
		this.chary += this.speed;
		if (this.pos == 5) {
			this.pos = 1;
		}
		else {
			this.pos += 1
		}
	}
	else {
		this.chary -= this.speed;
	}
}
//choose a random x position for newly generated crewmates
function getX() {
	var x = random(20, 530)
	if (x >= 160) {
		x += 70;
	}
	else {
		x -= 20;
	}
	return x;
}
//choose starting position at top of canvas for walking crewmates and bottom for dead crewmates so it looks like they are all moving with the screen
function start(f) {
	if (f == 0) {
		return 0
	}
	else {
		return 600
	}
}
//return a random speed from the array, to be assigned to individual crewmate
function getVelocity(status) {
	if (status == 0){
		return Math.floor(random(1,6));
	}
	else {
		return 5;
	}
}
//return a random color from the array, to be assigned to individual crewmate
//other crewmates will not have the same color as your character
function getColor() {
	var cols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white'];
	var index = Math.floor(Math.random() * cols.length); 
	while (colChoice == cols[index]) {
		index = Math.floor(Math.random() * cols.length)
	}
	return cols[index]
}
//assign object properties to the crew (crewmates onscreen)
function makeCrew() {
	var x = getX();
	var f = Math.floor(random(0,2));
	var y = start(f);
	var v = getVelocity(f);
	var c = getColor();
	var crew = {charx: x, chary: y, speed: v, update: updateCrew, pos: 1, fig: f, draw: drawCrew, col: c}
	return crew
}
//draw new crewmates
function drawbuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].draw();
	}
}
//update position of new crewmates
function updatebuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].update();
	}
}
//remove crewmates as they pass offscreen
function removebuddies() {
	keep = []
	for (var i=0; i < buddies.length; i++){
		if (buddies[i].chary +600 > 0) {
			keep.push(buddies[i])
		}
	}
	buddies = keep;
}
//add new crewmates with a probability based on the stage (increasing difficulty every 15 seconds)
function addMate() {
	var threshold;
	if (60>timer & timer>=45) {
		threshold = 0.02
	}
	if (45>timer && timer>=30) {
		threshold = 0.045
	}
	if (30>timer && timer>=15) {
		threshold = 0.055
	}
	if (15>timer && timer>=0) {
		threshold = 0.06
	}
	if (random(0,1) < threshold) {
		buddies.push(makeCrew())
	}
}
//CHARACTER DRAWING-----------------------------------------------------------------------------------------------------
//draw all the stages of walking for one crewmate
function AmongUs1(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(20,9);
	curveVertex(15,29);
	curveVertex(15,64);
	curveVertex(21,77);
	curveVertex(32,75);
	curveVertex(33,63);
	curveVertex(39,63);
	curveVertex(42,75);
	curveVertex(52,72);	//front of foot
	curveVertex(57,60);
	curveVertex(56,42);
	curveVertex(59,24);
	curveVertex(50,10);
	curveVertex(35,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}

function AmongUs2(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(15,57);
	curveVertex(5,68);
	curveVertex(19,78);
	curveVertex(34,63);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(22,6);
	curveVertex(15,30);
	curveVertex(15,56);
	curveVertex(24,65);
	curveVertex(34,65);
	curveVertex(42,66);
	curveVertex(55,79);
	curveVertex(68,70);
	curveVertex(52,59);	//front of foot
	curveVertex(55,47);
	curveVertex(55,34);
	curveVertex(58,21);
	curveVertex(47,7);
	curveVertex(33,2);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs3(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(46,56);
	curveVertex(48,73);
	curveVertex(19,72);
	curveVertex(19,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(19,10);
	curveVertex(15,35);
	curveVertex(17,61);
	curveVertex(25,68);
	curveVertex(28,75);
	curveVertex(24,83);
	curveVertex(36,82);
	curveVertex(41,71);
	curveVertex(39,60);	//front of foot
	curveVertex(49,58);
	curveVertex(57,50);
	curveVertex(56,35);
	curveVertex(58,25);
	curveVertex(54,14);
	curveVertex(45,8);
	curveVertex(32,4);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs4(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(40,60);
	curveVertex(56,79);
	curveVertex(66,65);
	curveVertex(54,52);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(25,4);
	curveVertex(16,24);
	curveVertex(15,54);
	curveVertex(19,61);
	curveVertex(8,61);
	curveVertex(5,74);
	curveVertex(19,76);
	curveVertex(28,69);
	curveVertex(32,63);	//front of foot
	curveVertex(45,63);
	curveVertex(56,56);
	curveVertex(58,38);
	curveVertex(58,26);
	curveVertex(54,12);
	curveVertex(43,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs5(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(32,61);
	curveVertex(34,76);
	curveVertex(49,76);
	curveVertex(50,56);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(24,3);
	curveVertex(17,24);
	curveVertex(16,51);
	curveVertex(15,59);
	curveVertex(23,59);
	curveVertex(10,64);
	curveVertex(12,72);
	curveVertex(32,70);
	curveVertex(37,62);	//front of foot
	curveVertex(49,62);
	curveVertex(56,54);
	curveVertex(58,34);
	curveVertex(58,23);
	curveVertex(54,13);
	curveVertex(47,5);
	curveVertex(35,1);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
//draw a dead crewmate
function Dead1(c) {
	stroke(0);
	strokeWeight(5);
	fill(255);
	//bone sticking out
	beginShape();
	curveVertex(33,39);
	curveVertex(32,29);
	curveVertex(27,22);
	curveVertex(32,18);
	curveVertex(35,23);
	curveVertex(37,17);
	curveVertex(41,21);
	curveVertex(38,32);
	curveVertex(38,42);
	endShape(CLOSE);
	fill(c);
	//arm
	beginShape();
	curveVertex(2,39);
	curveVertex(12,34);
	curveVertex(20,38);
	curveVertex(18,60);
	curveVertex(6,59);
	endShape(CLOSE);
	//half body
	beginShape();
	curveVertex(15,37);
	curveVertex(28,40);
	curveVertex(34,37);
	curveVertex(44,40);
	curveVertex(58,38);
	curveVertex(57,66);
	curveVertex(45,74);
	curveVertex(41,62);
	curveVertex(35,62);
	curveVertex(32,74);
	curveVertex(17,73);
	curveVertex(14,49);
	endShape(CLOSE);
}
//BACKGROUND-------------------------------------------------------------------------------------------------------------
//draw the cafeteria floor
//make small diamond tile object
function smallDiamond(x, y) {
	var diamond = {diamondx: x, diamondy: y, diamondw: 70, diamondh: 35, speed: -5.0, draw: drawDiamond, update: updateDiamond}
	return diamond;
}
//draw small diamond
function drawDiamond() {
	noStroke();
	fill(133,135,124);
	beginShape();
	vertex(this.diamondx,this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy-this.diamondh);
	vertex(this.diamondw+this.diamondx, this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy+this.diamondh);
	endShape(CLOSE);
}
//update position of the tile with speed
function updateDiamond() {
	this.diamondy += this.speed;
}
//make big diamond tile object
function bigDiamond(cx, cy) {
	var bigdiam = {leftD: smallDiamond(cx-70, cy), topD: smallDiamond(cx-35, cy-35), rightD: smallDiamond(cx, cy), bottomD: smallDiamond(cx-35, cy+35), draw: drawBigDiamond, update: updateBigDiamond}
	return bigdiam;
}
//make big diamond tile from smaller diamond tiles
function drawBigDiamond() {
	this.leftD.draw()
	this.topD.draw()
	this.rightD.draw()
	this.bottomD.draw()
}
//update position of big diamond tiles
function updateBigDiamond() {
	this.leftD.update();
	this.topD.update();
	this.rightD.update();
	this.bottomD.update();
}
//draw the diamonds
function displayDiamond() {
	for (var i=0; i < diams.length; i++){
		for (var j=0; j < diams[i].length; j++){
			diams[i][j].draw();
		}
	}
}
//update the positons of the diamonds as the screen scrolls
function updateFloor() {
	for (var i=0; i < diams.length; i++) {
		for (var j=0; j < diams[i].length; j++) {
			diams[i][j].update();
		}
	}
}
//get rid of rows that have slipped offscreen
function elimRow(){
	keepRow = false;
	for (var i=0; i < diams[0].length; i++) {
		if (lastOdd == false){
			if (i % 2 == 0) {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0) {
					keepRow = true
				}
			}
			else {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
		}
		else {
			if (i % 2 == 0) {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
			else {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0){
					keepRow = true
				}
			}
		}
	}
	if (keepRow == false){
		diams.shift();
	}
}
//update the new rows added such that they match the original cafeteria tile pattern
function updateRow() {
	if (diams.length < 7){
		n_row = []
		if (lastOdd == true){
			for (var col=0; col < 7; col++){
				if (col % 2 == 0) {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    		else {
	    			n_row.push(bigDiamond(col*105+35, 665)) 
	    		}
			}
			diams.push(n_row);
			lastOdd = false;
		}
		else {
			for (var col=0; col < 7; col++){
	    		if (col % 2 == 0){
	    			n_row.push(bigDiamond(col*105+35, 665))
	    		}
	    		else {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    	}
	    	diams.push(n_row);
	    	lastOdd = true;
		} 
	}
}