Project – 2020 Calendar

2020 Calendar shaunmurDownload
//Diana McLaughlin and Shaun Murray
//dmclaugh@andrew.cmu.edu and shaunmur@andrew.cmu.edu
//Section A and Section B
//A calendar commemorating a major event from each month in 2020
//All global variables except image variables are with the start of the respective month's program. Some of these variables are called in set up, but you'll find them before their clickMonthX() function
//Shaun's code starts at clickMonthJan(). He also wrote the makeCalendar(), clearBkgd(), and backButton() functions
//Diana's code starts at clickMonthJul(). She also wrote the writeMonths() function
//Aside from the makeCalendar and writeMonths functions, Shaun did everything related to January - June and Diana did everything related to July - December
//"The biggest waste of computer processing power in 15-104" -Shaun

//Image Variables
//for the main calendar
var imgJanCal, imgFebCal, imgMarCal, imgAprCal, 
	imgMayCal, imgJunCal, imgJulCal, imgAugCal, 
	imgSepCal, imgOctCal, imgNovCal, imgDecCal;

//for the month functions
var imgJan2, imgMar, aprImg, aprImg2, 
    aprImg3, imgJun1, imgJun2, imgJun3, 
    imgJul, imgOct, imgNov;


function preload() {
	imgJanCal = loadImage("https://i.imgur.com/mGCWr67.jpg?2"); //January main calendar
	imgFebCal = loadImage("https://i.imgur.com/8hI9x3x.jpg"); //February main calendar
	imgMarCal = loadImage("https://i.imgur.com/hozlVRU.jpg"); //March main calendar
	imgAprCal = loadImage("https://i.imgur.com/PUDQpPe.jpg"); //April main calendar
	imgMayCal = loadImage("https://i.imgur.com/FyUdmy7.png"); //May main calendar
	imgJunCal = loadImage("https://i.imgur.com/1V9Akde.jpg"); //June main calendar
	imgJulCal = loadImage("https://i.imgur.com/Tvukiin.jpg"); //July main calendar
	imgAugCal = loadImage("https://i.imgur.com/kECFW1b.jpg"); //August main calendar
	imgSepCal = loadImage("https://i.imgur.com/O6e3LcQ.jpg"); //September main calendar
	imgOctCal = loadImage("https://i.imgur.com/CcQpShS.jpg"); //October main calendar
	imgNovCal = loadImage("https://i.imgur.com/8Sqt5Um.jpg"); //November main calendar
	imgDecCal = loadImage("https://i.imgur.com/DrModlG.jpg"); //December main calendar

    imgJan = loadImage("https://i.imgur.com/UO8RoiW.png"); //santa hat for JAN
    imgJan2 = loadImage("https://i.imgur.com/lM5i1Gp.jpeg") //A-Bomb Jan
    imgFeb = loadImage("https://i.imgur.com/AIq3z8n.jpeg"); //House Chamber background
    imgMar = loadImage("https://i.imgur.com/VFoP91O.png"); //background image for March
    mayImg1 = loadImage("https://i.imgur.com/RhNvf13.jpeg"); //Kim Jong Un
	mayImg2 = loadImage("https://i.imgur.com/huOal0b.png"); //podium
	mayImg3 = loadImage("https://i.imgur.com/20G2Bj4.jpg"); //NK flag
    aprImg = loadImage("https://i.imgur.com/G0SnXSB.jpg"); //Tiger
	aprImg2 = loadImage("https://i.imgur.com/VVfSCll.jpeg"); //Oklahoma
	aprImg3 = loadImage("https://i.imgur.com/IgLfZQb.png"); //Joe Exotic
	imgJun1 = loadImage("https://i.imgur.com/V8MHehF.jpg"); //St John's Church
	imgJun2 = loadImage("https://i.imgur.com/on3fzqb.jpg"); //President
	imgJun3 = loadImage("https://i.imgur.com/SAUkUd3.jpg"); //Protesters
	imgJul = loadImage("https://i.imgur.com/FXdV1Bk.jpg"); //John Lewis photograph for July
    imgOct = loadImage("https://i.imgur.com/a7W8anl.png"); //map for Oct
    imgNov = loadImage("https://i.imgur.com/OCT1IpR.jpg"); //auditorium for November
}

function setup() {
    createCanvas(500, 400);
    makeCalendar();

    //set up March
    for (var i = 0; i < 1; i++) {
    // make virus cell
    	var v = makeVirus(200, 200,
                             random(-50, 50), random(10, 50));
        viruses.push(v);
    }

    //set up for April
    for (var i = 0; i < 12; i++){ // create an initial collection of cats
        var rx = random(width);
        tigers[i] = makeTigers(rx);
    }

    //set up August
    for (var i = 0; i < 1; i++){
        var hy = random(height/3, height);
        hurricane[i] = makeHurricane(hy);
    } 
    
    //set up September
    //set up mountains
    for (var i = 0; i <= 100; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height/2);
        mountain.push(value);
        noiseParam += noiseStep;
    }  

    //set up fire
    for (var i = 0; i <= 100; i++) {
        var n = noise(fNoiseParam);
        var value = map(n, 0, 1, 0, height);
        fire.push(value);
        fNoiseParam += fNoiseStep;
    }  
    
    //draw initial trees
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    
    //draw initial smoke clouds
    for (var i = 0; i < 10; i++){
        var cx = random(width);
        smoke[i] = makeSmoke(cx);
    }
    
}

function draw() {
	clickMonthJan();
	clickMonthFeb();
	clickMonthMar();
	clickMonthApr();
	clickMonthMay();
	clickMonthJun();
	clickMonthJul();
	clickMonthAug();
	clickMonthSep();
	clickMonthOct();
	clickMonthNov();
	clickMonthDec();
	backButton();
}

function makeCalendar() {
	fill(0);
    strokeWeight(1);
    //draw lines between the months on the calendar
    for (let i = 0; i < 3; i++) {
        line(0, i*133.33 + 133, width, i*133.33 + 133);
        line(i*125 + 125, 0, i*125 + 125, height);
    }

    //background pictures
    var calPics = [imgJanCal, imgFebCal, imgMarCal, imgAprCal, imgMayCal, imgJunCal, imgJulCal, imgAugCal, imgSepCal, imgOctCal, imgNovCal, imgDecCal];
    var xCo = [0.5, 125.5, 250.5, 375.5, 0, 125.5, 250.5, 375.5, 0.5, 125.5, 250.5, 375.5];
    var yCo = [0, 0, 0, 0, 132.83, 132.83, 132.83, 132.83, 267.16, 267.16, 267.16, 267.16];
    for (var i = 0; i < calPics.length; i++) {
    	image(calPics[i], xCo[i], yCo[i], 124.5, 132.83);
    }

    writeMonths();

}

function writeMonths() {
	//display text on calendar
	var monthText = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	var monthCode = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " ", "="];
	var monthX = [55, 180, 305, 430, 55, 180, 305, 430, 55, 180, 305, 430];
	var monthY = [65, 65, 65, 65, 200, 200, 200, 200, 335, 335, 335, 335];
	strokeWeight(1);
	textFont('Times');
    textSize(24);
    textAlign(CENTER);
    stroke(0);
    fill(255);
    for (var i = 0; i < monthText.length; i++) {
    	text(monthText[i], monthX[i], monthY[i]);
    	text(monthCode[i], monthX[i], monthY[i] + 30);
    }
    textSize(40);
    text("-", 300, 363);
    textSize(15);
    textAlign(LEFT);
    text("Press a key to begin", 3, 25); //written instruction
    text("Press ESC to return", 380, 25);
}

function backButton() { //click to return to calendar
    if (keyCode === 27) {
        clearBkrd();
        makeCalendar();

        //reset March
        v.diam = 25;

        //reset November
        pCount = 0;
        vpCount = 0;
    }
}

function clearBkrd() { //clear background
    background(255);
}

//Shaun's Code

function clickMonthJan() {
	//Referencing the anticipation of North Korea's overdue X-mas gift
    if (keyCode === 49) {
        clearBkrd();
        frameRate(30);
        JanBackground();
        USflag();
        NKflag();
        nuclear(width/2, height/2);
        JanText(45, height-85);
        backButton(); 
    }
         
}

	function JanBackground() {
		image(imgJan2, 0, 0, width, height);
	}

    function starJan() {
        var x1 = [340, 348, 364, 354, 356, 340, 324, 326, 315, 332]; //star points
        var y1 = [44, 58, 62, 75, 92, 85, 92, 75, 62, 58];
        var nPoints= x1.length;
        beginShape();
        fill('Red');
        for (var i= 0; i< nPoints; i++) {
            vertex(x1[i] + 35, y1[i] + 5);
        }
        endShape(CLOSE);
    }

    function USflag() {// United States Flag minus stars
        fill('Red');
        rect(25, 25, width/3, height/4);
        for(let i = 0; i < 7; i++) { //white rects on flag
            fill('white');
            rect(25, 30 + (i * 13.5), width/3, 7);
        }
        fill(0, 0, 155);
        rect(25, 25, 50, 50);
    }

    function NKflag() { //North Korean Flag
        fill('Blue');
        rect(width-164, 25, width/3, height/4);
        push();
        fill('Red');
        strokeWeight(5);
        noStroke();
        rect(width-163, 40, width/3 + 6, 70); //white border in flag
        stroke('White');
        line(width, 40, width-161, 40);
        line(width, 110, width-161, 110);
        pop();
        noStroke();
        fill('White');
        circle(width-125, 75, 53);
        stroke(0);
        push();
        starJan();
        pop();
    }

    function nuclear(x, y) { //nuclear symbol
        push();
        translate(x, y);
        let d = 80
        let d1 = 10
        stroke(0);
        strokeWeight(3);
        fill('yellow'); //draw circles
        circle(0, 0, d);
        fill('black');
        circle(0, 0, d1);

        let deg = 120;
        let dx = 5;
        let angle = 45;

        rotate(radians(angle));
        for (let i = 0; i < 3; i++) { //draw triangles 
            rotate(radians(deg));
            beginShape();
            fill('black');
            vertex(-7, -7);
            vertex(-30, -10);
            vertex(-10, -30);
            endShape(CLOSE);
        }

        angle = angle + dx;
        pop();

        push();
        rotate(radians(-20));
        image(imgJan, 135, 185, 100, 100); //santa hat
        pop();

    }

    function JanText(x, y) { //display text for Jan
        push();
        translate(x, y);
        textSize(23);
        fill(255);
        text("United Shaysh of America VS. North Korea", 0, 0);
        pop();
    }

//Global variables for Feb
var rip = 0//checks to see if SotU is ripped

function clickMonthFeb() {
	//Referencing the ripped speech at the State of the Union address
    if (keyCode === 50) {
        clearBkrd();
        frameRate(30);
        drawPaper();
		drawRip();
		mendPaper();
        backButton();
    }   
    
}

	//February helper functions
	function drawPaper() { //draw initial SotU
		push();
		background('grey');
		image(imgFeb, 0, 0);
		fill('white');
		rectMode(CENTER);
		rect(width/2+30, height/2, 200, 300);
		rect(width/2+15, height/2, 200, 300);
		rect(width/2, height/2, 200, 300);
		textStyle(ITALIC);
		textSize(22);
		fill('black');
		text("State of the Union", 160, 80);
		fill('white');
		text("Click and hold to rip!", width-205, 25);
		text("Nancy Pelosi Simulator", 10, 25);
		line(180, 110, 320, 110);
		for (let i = 0; i < 20; i++) {
			line(165, 120 + i*11, 335, 120 + i*11);
		}
		pop();
	}

	function drawRip() { //Rip SotU
		push();
		if (mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			textStyle(ITALIC);
		    textSize(22);
			fill('white');
			text("Release mouse to mend...", 10, 25);
			push();
			rotate(radians(-30));
			fill('white');
			rectMode(CORNER);
			rect(width/2-300, height/2-80, 100, 300);
			for (let i = 0; i < 20; i++) {
				line(-40, 190 + i*11, 40, 190 + i*11);
			}
			fill('black');
			text("State of t", -50, 160);
			rotate(radians(60));
			fill('white');
			rect(width/2+160, height/2-345, 100, 300);
			for (let j = 0; j < 20; j++) {
				line(width/2+175, height/2-280 + j*11, width/2+250, height/2-280 + j*11);
			}
			fill('black');
			text("he Union", width/2+162, height/2-300);
			pop();
			pop();
			rip = 1;
		}
	}

	function mendPaper() { //Tape SotU back together like a good American
		push();
		if (rip == 1 & !mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			fill('white');
			rectMode(CENTER);
			rect(width/2+30, height/2, 200, 300);
			rect(width/2+15, height/2, 200, 300);
			rect(width/2, height/2, 200, 300);
			textStyle(ITALIC);
			textSize(22);
			fill('black');
			text("State of the Union", 160, 80);
			fill('white');
			text("Click and hold to rip!", width-205, 25);
		    text("Nancy Pelosi Simulator", 10, 25);
			fill('black');
			line(180, 110, 320, 110);
			for (let i = 0; i < 20; i++) {
				line(165, 120 + i*11, 335, 120 + i*11);
			}
	        fill(255, 248, 220);
			rect(width/2-15, height/2, 30, 300);
			pop();
		}
	}
//Global variable for March
var viruses = [];

function clickMonthMar() {
	//Referencing the spread of COVID-19 in the U.S.
    if (keyCode === 51) {
        clearBkrd();
        backButton();
        frameRate(15);
        image(imgMar, 0, 0, 500, 400);

	    for (var i = 0; i < viruses.length; i++) {
	        var v = viruses[i];
	        v.stepFunction();
	        v.drawFunction();
	        if (v.diam > 450) {
	        	background(0);
	        	stroke(255, 0, 0);
	        	strokeWeight(4);
	        	push();
	        	textSize(48);
	        	translate(width/2, height/2)
	        	rotate(radians(90));
	        	text(":(", 0, 0);
	        	pop();
	        	stroke(0);
	        	strokeWeight(2);
	        	fill('white');
	        	text("Sad", width/2, height/2 + 100);
	        }
	    }
    }   
    
}

	//March Helper Functions
	function virusStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx;
        this.diam *= 1.25;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx;
        this.diam *= 1.25;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy;
        this.diam *= 1.25;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy;
        this.diam *= 1.5;
    }
	}


	function virusDraw() {
		stroke('black');//body of virus
		strokeWeight(2);
		fill('red');
		push();
	    translate(this.x, this.y);
		circle(0, 0, this.diam);
		strokeWeight(3);//stems of virus
		var angle = 45;
		for (let i = 0; i < 8; i++) {
			rotate(radians(angle));
			beginShape();
	        vertex(this.diam/2 - 10, 0)
	        vertex(random(this.diam/2 + 4, this.diam/2 + 8), random(-2, 2));
	        endShape(CLOSE);
	        ellipse(random(this.diam/2 + 8, this.diam/2 + 6), random(1, 3), 11, 9);
	    }
	    pop();
	}


	// create a "Particle" object with position and velocity
	function makeVirus(vx, vy, vdx, vdy) {
	    v = {x: vx, y: vy,
	         dx: vdx, dy: vdy,
	         age: 0,
	         diam: 25,
	         stepFunction: virusStep,
	         drawFunction: virusDraw
	        }
	    return v;
	}	

// Global variables for April
var tigers = [];
var deg = 10
var joe = 1;

function clickMonthApr() {
	//Referencing the popularity of the Tiger King documentary on NETFLIX in March/April
    if (keyCode === 52) {
        clearBkrd();
        frameRate(12);
        displayHorizon();
   		updateAndDisplayTigers();
    	removeTigersThatHaveSlippedOutOfView();
    	addNewTigersWithSomeRandomProbability();
        backButton();
    }
       
}

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


	function removeTigersThatHaveSlippedOutOfView(){
	    var tigersToKeep = [];
	    for (var i = 0; i < tigers.length; i++){
	        if (tigers[i].x + tigers[i].breadth > 0) {
	            tigersToKeep.push(tigers[i]);
	        }
	    }
	    tigers = tigersToKeep; // remember the surviving tigers
	}


	function addNewTigersWithSomeRandomProbability() {
	    // With a very tiny probability, add a new cat to the end.
	    var newTigersLikelihood = 0.03; 
	    if (random(0,1) < newTigersLikelihood) {
	        tigers.push(makeTigers(width));
	    }
	}


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

	// draw the cat and more cats
	function tigersDisplay() {
	    push();
	    translate(this.x, height - floor(random(30, 40))); 
	    image(aprImg, 0, -15, 80, 35);
	    pop();
	}


	function makeTigers(birthLocationX) {
	    var tgs = {x: birthLocationX,
	                breadth: 50,
	                speed: -1.0,
	                move: tigersMove,
	                display: tigersDisplay}
	    return tgs;
	}

	function displayHorizon(){
		image(aprImg2, 0, 0, width, height);
		push();
		translate(60, 80);
		imageMode(CENTER);
		rotate(radians(deg));
		for (let i = 0; i < joe; i++) {
			image(aprImg3, 0, 0, 80, 80);
		}
		pop();
		deg = deg + 10;
	}

function clickMonthMay() {
	//Referencing Kim Jong Un's questionable health and reappearance
    if (keyCode === 53) {
        clearBkrd();
        frameRate(60);
        drawBackdrop();
		leader();
		drawPodium();
        backButton(); 
    }  
    
}

	//May helper functions
	function leader() {//place Kim on canvas
		push();
		var top = height/2;
	    var bottom = height;
	    var conY = constrain(mouseY, top, bottom);
		imageMode(CENTER);
		image(mayImg1, width/2, conY, 120, 180);
		pop();
	}

	function drawPodium() {//place podium
		push();
		imageMode(CENTER);
		image(mayImg2, 250, 400, 300, 250);
		pop();
	}

	function drawBackdrop() {//draw flag background
		push();
		imageMode(CENTER);
		image(mayImg3, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("N.K. Leader Simulator", 10, 30);
		text("Moves with your mouse!", width-210, 30);
		pop();
	}

//Global variable June
var moveJun = 1;

function clickMonthJun() {
	//Referencing President Trump's removal of protesters from St. John's church in D.C.
    if (keyCode === 54) {
        clearBkrd();
        frameRate(30);
        drawChurch();
	    drawPres();
	    drawProtest();
	    fightBack();
        backButton();  
    } 
}

	function drawChurch() {//draw church background
		push();
		imageMode(CENTER);
		image(imgJun1, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("Click and hold mouse to fight back!", 10, 25);
		pop();
	}

	function drawPres() {//place President on canvas
		push();
		var junX1 = width - 50;
		var conX1 = constrain(junX1 - moveJun, 230, width + 60);
		imageMode(CENTER);
		image(imgJun2, conX1 , height-50, 120, 130);
		pop();
	}

	function drawProtest() {//place protesters on canvas
		push();
		var junX2 = 80;
		var conX2 = constrain(junX2 - moveJun, -100, 230);
		imageMode(CENTER);
		image(imgJun3, conX2, height-50, 200, 150);
		pop();
	}

	function fightBack() {//adjusts Xpos of pres and protest on canvas, default move left
		push();
		moveJun ++;
		print(moveJun);

		if (mouseIsPressed) {
			moveJun -= 2;
		}

		moveJun = constrain(moveJun, -150, 230);
		pop();
	}

//Diana's Code

var julXPoints = [];
var julYPoints = [];
var julClr = [];

function clickMonthJul() {
//Remembering John Lewis
    if (keyCode === 55) {
    	clearBkrd();
    	frameRate(60);
        imgJul.resize(width, height);
        imgJul.loadPixels();
        var x = random(width); //randomly draw pixels for a portrait of John Lewis
	    var y = random(height);
	    var clr = imgJul.get(x, y);
    	stroke(clr);
		strokeWeight(5);
	   	noFill();
	   	point(x, y); 
	   	julXPoints.push(x); //push the coordinates into arrays so it doesn't look like the background keeps drawing over it
	   	julYPoints.push(y);
	   	julClr.push(clr);
	   	for (var i = 0; i < julXPoints.length; i++) {
	   		stroke(julClr[i]);
	   		point(julXPoints[i], julYPoints[i]);
	   	}
        backButton(); 
    }
      
}

function clickMonthAug() {
//SpaceX Launch
	strokeWeight(1);
	stroke(0);
    if (keyCode === 56) {
        clearBkrd();
        background(0);
        frameRate(30);
		for (var i = 0; i < 3; i++) {
			for(var j = 0; j < 4; j++){
				star(i*200 + 25, j*100);
			}	
		}

		for (var a = 0; a < 2; a++) {
			for (var b = 0; b < 4; b++) {
				star(a*200 + 125, b*100 + 50);
			}
		}
		spaceship(200, 150);
		backButton(); 
	    }
}
    //August Helper Functions
	function spaceship(x, y) {
		push();
		translate(x, y);
		rotate(radians(30));
		fill(255);
		ellipse(25, 0, 50, 100); //spaceship body
		rect(0, 0, 50, 150);
		stroke(255, 0, 0);
		strokeWeight(3);
		push();
		rotate(radians(-90));
		text("SpaceX", -120, 25);
		pop();
		stroke(0);
		strokeWeight(1);
		triangle(0, 75, 0, 150, -35, 150); //wings
		triangle(50, 75, 50, 150, 85, 150);
		push();
		translate(-35, 150);
		for (var i = 0; i < 3; i++) { //draw flames
			fill(255, 175, 0);
			triangle(i*40, 0, (i+1)*40, 0, (i*40 + random(15, 25)), random(95, 105));
		}
		pop();
		pop();
	}

	function star(x, y) {
		var sx = [0, 5.5, 16.5, 9.5, 10.5, 0, -10.5, -9.5, -16.5, -5.5];
		var sy = [0, 9.5, 12.5, 21, 32, 27.5, 32, 21, 12.5, 10.5];
		push();
		translate(x, y);
		fill(255, 255, 0);
	    var nPoints = sx.length;
	    beginShape();
	    for (var i = 0; i < nPoints; i++) {
	    	vertex(sx[i] + random(-1, 1), sy[i] + random(-1, 1));
	    }
	    endShape(CLOSE);
	    pop();
	}

//Global Variables for September
var trees = [];
var smoke = [];
var mountain = [];
var fire = [];
var noiseParam = 0; //controls mountain landscape
var noiseStep = 0.01;
var fNoiseParam = 0; //controls fire
var fNoiseStep = 0.05;

function clickMonthSep() {
//West Coast Wildfires
    if (keyCode === 57) {
        clearBkrd();
        text("Sep TEST", width/2, height/2);
        backButton();
        frameRate(10);
        background(100); //dark grey

	    updateAndDisplaySmoke();
	    removeSmokeThatHasSlippedOutOfView();
	    addNewSmokeWithSomeRandomProbability();

	    mountains();
	    makeFire();
	    fill(75);
	    rect(0, 335, width, 65); //ground

	    updateAndDisplayTrees();
	    removeTreesThatHaveSlippedOutOfView();
	    addNewTreesWithSomeRandomProbability();   
	}
}

//September Helper Functions
	function updateAndDisplayTrees(){
	    // Update the trees' positions
	    for (var i = 0; i < trees.length; i++){
	        trees[i].move();
	        trees[i].display();
	    }
	}


	function removeTreesThatHaveSlippedOutOfView(){
	    //remove these trees from the array
	    var treesToKeep = [];
	    for (var i = 0; i < trees.length; i++){
	        if (trees[i].x + trees[i].breadth > 0) {
	            treesToKeep.push(trees[i]);
	        }
	    }
	    trees = treesToKeep;
	}


	function addNewTreesWithSomeRandomProbability() {
	    // Add a new tree to the end of the array
	    var newTreeLikelihood = 0.05; 
	    if (random(0,1) < newTreeLikelihood) {
	        trees.push(makeTree(width));
	    }
	}

	function treeMove() {
	    this.x += this.speed;
	}
	    
	function treeDisplay() {
	    //draw the tree
	    var tHeight = 90; 
	    strokeWeight(5);
	    stroke(0); 
	    push();
	    translate(this.x, height - 40);
	    line(0, -tHeight, 0, 0);
	    line(0, -40, -22, -75);
	    line(0, -40, 22, -75);
	    line(0, -50, -15, -85);
	    line(0, -50, 15, -85);
	    line(0, -30, -30, -65);
	    line(0, -30, 30, -65);
	    stroke(200); 
	    pop();
	}


	function makeTree(birthLocationX) {
	    var tr = {x: birthLocationX,
	                breadth: 50,
	                speed: -3.5,
	                move: treeMove,
	                display: treeDisplay}
	    return tr;
	}

	//Smoke Clouds

	function updateAndDisplaySmoke(){
	    // Update the smoke positions
	    for (var i = 0; i < smoke.length; i++){
	        smoke[i].move();
	        smoke[i].display();
	    }
	}


	function removeSmokeThatHasSlippedOutOfView(){
	    // remove clouds that are no longer visible
	    var smokeToKeep = [];
	    for (var i = 0; i < smoke.length; i++){
	        if (smoke[i].x + smoke[i].breadth > 0) {
	            smokeToKeep.push(smoke[i]);
	        }
	    }
	    smoke = smokeToKeep;
	}


	function addNewSmokeWithSomeRandomProbability() {
	    // Add smoke clouds to the end of the arrayS
	    var newSmokeLikelihood = 0.02; 
	    if (random(0,1) < newSmokeLikelihood) {
	        smoke.push(makeSmoke(width));
	    }
	}

	function smokeMove() {
	    this.x += this.speed;
	}
	    

	// draw smoke
	function smokeDisplay() { 
	    fill(50); 
	    noStroke(); 
	    push();
	    translate(this.x, this.y);
	    ellipse(0, this.y, 90, 15);
	    ellipse(0, this.y+10, 100, 15);
	    ellipse(0, this.y-10, 80, 15);
	    pop();
	}


	function makeSmoke(birthLocationX) {
	    var smk = {x: birthLocationX,
	    	        y: random(0, height/2),
	                breadth: 50,
	                speed: -3.,
	                move: smokeMove,
	                display: smokeDisplay}
	    return smk;
	}


	function mountains() {
	    //use random noise to draw mountains
	    mountain.shift();
	    var n = noise(noiseParam);
	    var value = map(n, 0, 1, 0, height);
	    mountain.push(value);
	    noiseParam += noiseStep;
	    
	    
	    fill(0); //black - mountain shadows
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, mountain[i]);
	    }
	    vertex(width, height);
	    endShape(); 
	}

	function makeFire() {
	    //use random noise to draw mountains
	    fire.shift();
	    var n = noise(fNoiseParam);
	    var value = map(n, 0, 1, 0, height);
	    fire.push(value);
	    fNoiseParam += fNoiseStep;
	    
	    
	    fill(255, 0, 0); //red layer
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, fire[i]);
	    }
	    vertex(width, height);
	    endShape(); 

	    fill(255, 175, 0); //orange layer
	    beginShape();
	    vertex(0, height);
	    for (var j = 0; j <= 100; j++) {
	    	vertex(j*5, fire[j] + 50);
	    }
	    vertex(width, height);
	    endShape();

	    fill(255, 255, 0); //yellow layer
	    beginShape();
	    vertex(0, height);
	    for (var p = 0; p <= 100; p++) {
	    	vertex(p*5, fire[p] + 100);
	    }
	    vertex(width, height);
	    endShape();
     
}

//October Global Variables
var hurricane = [];
var xMove = [];
var imgOct;

function clickMonthOct() {
	//Busiest hurricane season on record
    if (keyCode === 48) {
        clearBkrd();
        frameRate(15);
        translate(width, 0);
	    image(imgOct, -width-50, -107, 650, 560);
		updateAndDisplayHurricane(); 
		removeHurricanesThatHaveSlippedOutOfView();
		addNewHurricanesWithSomeRandomProbability();
        backButton();
    }
}

	//October Helper Functions
		function updateAndDisplayHurricane(){
	    // Update the hurricanes' positions
	    for (var i = 0; i < hurricane.length; i++){
	        hurricane[i].move();
	        hurricane[i].display();
	    }
	}

	function removeHurricanesThatHaveSlippedOutOfView(){
	    //remove these hurricanes from the array
	    var hurricanesToKeep = [];
	    for (var i = 0; i < hurricane.length; i++){
	        if (hurricane[i].x > -550 || hurricane[i].y > -50) {
	            hurricanesToKeep.push(hurricane[i]);
	        }
	    }
	    hurricane = hurricanesToKeep;
	}

	function addNewHurricanesWithSomeRandomProbability() {
	    // Add a new hurricane to the end of the array
	    var newHurricaneLikelihood = 0.025;
	    var newHY = random(height/3, height);
	    this.xMove = random(10);
	    this.yMove = random(10);
	    if (random(0,1) < newHurricaneLikelihood) {
	        hurricane.push(makeHurricane(newHY));
	    }
	}

	function hurricaneMove() {
		this.x -= this.hxMove;
		this.y -= this.hyMove;
		this.spin += 10;
	}

	function hurricaneDisplay() {
		push();
		translate(this.x, this.y);
		rotate(radians(this.spin));
	    noStroke();
	    fill(255, 0, 0);
	    ellipse(0, 0, 30, 30);
	    fill(230);
	    ellipse(0, 0, 10, 10);
		push();
		scale(0.7);
		translate(-40, 5);
		stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
	    
	    push();
	    scale(0.7);
	    stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
	    translate(40, -5);
	    rotate(radians(180));
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
		pop();
	}

	function makeHurricane(birthLocationY) {
		var h = {x: 0, y: birthLocationY, hxMove: xMove, hyMove: 5, move: hurricaneMove, spin: 0, display: hurricaneDisplay}
	    return h;
	}

//November Global Variables
var theta = 0;
var txp = 0;
var typ = 0;
var thetavp = 0;
var txvp = 0;
var tyvp = 0;
//counters
var pCount = 0;
var vpCount = 0;

function clickMonthNov() {
//2020 US Presidential Election
    strokeWeight(1);
	stroke(0);
	textSize(14);

    if (keyCode === 189) {
        clearBkrd();
        frameRate(15);
        backButton();
        image(imgNov, -150, -60, 800, 650);
        stroke(255);
		president(150, 200);
		vicePresident(350, 200);
		fill(255);
		text("Who will be the first to 270?", 150, 20);
		text("Click the mouse on the left to give Alec Baldwin electoral votes", 75, 45)
		text("Click the mouse on the right to give Jim Carrey electoral votes", 75, 70);
		text(pCount, 150, 120);
		text(vpCount, 350, 120);
		debate();
	}

    	if (pCount >= 270) {
			background(255, 0,0);
			textSize(30);
			stroke(0);
			fill(0);
			text("I did it! It was RIGGED but I won!", 20, height/2 - 15);
			text("Very good for our Great Country", 25, height/2 + 15);
		}

		if (vpCount >= 270) {
			background(0, 0, 255);
			textSize(50);
			stroke(255);
			fill(255);
			text("Will you shut up man!", 5, height/2);
		}
	
}
    //November Helper Functions    
	function debate(){
		if (mouseIsPressed) {
			if (mouseX < width/2) { //move president
				theta = 15;
				txp = 150;
				typ = -100
				pCount = pCount + 5;				
			}

			if (mouseX >= width/2) { //move vice president
				thetavp = -15;
				txvp = -150;
				tyvp = 0;
				vpCount = vpCount + 5;
			}
		}
	} 

	function mouseReleased() {
		if (theta === 15) { //reset president
			theta = 0;
			txp = 0;
			typ = 0;					
		}

		if (thetavp === -15) { //reset vice president
			thetavp = 0;
			txvp = 0;
			tyvp = 0;				
		}
	}

	function president(x, y) {
		push();
		rotate(radians(theta));
		translate(x + txp, y + typ);
		noStroke();
		fill(255, 175, 0);
		push();
		rotate(radians(75)); //mouth
		ellipse(17, -12, 4, 15);
		rotate(radians(30));
		ellipse(15, -17, 4, 15);
		pop();
		fill(255, 175, 0); //head
		ellipse(0, 0, 40, 50);
		fill(255, 255, 0); //hair
		ellipse(3.5, -20, 45, 15);
		fill(255); //eyes
		ellipse(10, -2, 8, 8);
		fill(0);
		ellipse(10, -2, 4, 4);
		stroke(0);
		line(25, 17, 40, 17);
		line(25, 9, 40, 1);
		line(25, 25, 40, 33);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 32, 50);
		fill(0, 0, 255); //suit jacket
		rect(-15, 23, 25, 50);
		fill(255, 0, 0); //tie
		rect(14, 23, 3, 30);
		fill(0); //shoes
		ellipse(3, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 27, 60);
		push(); //arm
		rotate(radians(-40));
		fill(255, 175, 0);
		ellipse(15, 40, 15, 10);
		fill(0, 0, 255);
		rect(-35, 35, 50, 10);
		pop();
		pop();
	}

	function vicePresident(x, y) {
		push();
		rotate(radians(thetavp));
		translate(x + txvp, y + tyvp);
		noStroke();
		fill(250, 237, 203); //head
		ellipse(-2, 0, 40, 50);
		fill(255); //hair
		ellipse(0, -22, 35, 8);
		fill(255); //eyes
		ellipse(-10, -4, 8, 8);
		fill(0);
		ellipse(-10, -4, 4, 4);
		fill(255, 0, 0); //mouth
		ellipse(-12, 13, 8, 8);
		stroke(0);
		line(-25, 13, -40, 13);
		line(-25, 8, -40, 0);
		line(-25, 18, -40, 26);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 25, 50);
		fill(0, 0, 255); //suit jacket
		rect(-8, 23, 18, 50);
		fill(255, 0, 0); //tie
		rect(-15, 23, 3, 30);
		fill(0); //shoes
		ellipse(-7, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 25, 60);
		push(); //arm
		rotate(radians(40));
		fill(250, 237, 203);
		ellipse(-18, 45, 10, 10);
		fill(0, 0, 255);
		rect(-18, 40, 50, 10);
		pop();
		pop()
		}

//December global variables - firework coordinate arrays     
var xpos = 0;
var xcoord = [35, 25, 55, 200, 240, 400, 470, 440, 455, 230, 280, 415, 100, 280];
var ycoord = [25, 100, 350, 120, 150, 75, 45, 175, 300, 320, 365, 340, 215, 50];

function clickMonthDec() {
	//abstract clock to wait for the end of 2020
    if (keyCode === 187) {
        clearBkrd();
        backButton();
        frameRate(5);
    	background(0);
	    var sec = second();
	    var min = minute();
	    var hr = hour();
	    var d = day();
	    background(0);

	    //draw fireworks in the background
	    for (var i = 0; i < 14; i++) {
	        firework(xcoord[i], ycoord[i]);
	    }

	    push();
	    scale(0.5);
	    president(16*d, 40); //moves with day
	    pop();
	    decVirus(20*hr, 150); //hour
	    image(aprImg3, 8*min, 200, 80, 80); //minute
	    decHurricane(8*sec, 350); //second

	}
}

	//December helper functions
	function firework(x, y) { 
	    var r = random(255);
	    var g = random(255);
	    var b = random(255);
	    push();
	    translate(x, y);
	    stroke(r, g, b);
	    for (var i = 0; i < 12; i++) { //draw lines
	        push();
	        rotate(radians(i*30));
	        line(xpos, 0, xpos + 15, 0);
	        pop();
	    }

	    if (xpos <= 25) { //grow
	    xpos += 1;
	    }

	    else if (xpos > 25) { //reset
	        xpos = 0;
	    }
	    pop();
	}

	function decVirus(x, y) { //design taken from Shaun's virus object - I did not code
	        stroke('black');//body of virus
	        strokeWeight(2);
	        fill('red');
	        push();
	        translate(x, y);
	        circle(0, 0, 35);
	        strokeWeight(3);//stems of virus
	        var angle = 45;
	        for (let i = 0; i < 8; i++) {
	            rotate(radians(angle));
	            beginShape();
	            vertex(35/2 - 10, 0)
	            vertex(random(35/2 + 4, 35/2 + 8), random(-2, 2));
	            endShape(CLOSE);
	            ellipse(random(35/2 + 8, 35/2 + 6), random(1, 3), 11, 9);
	        }
	        pop();
	}

    function decHurricane(x, y) { //from October 
        push();
        translate(x, y);
        noStroke();
        fill(255, 0, 0);
        ellipse(0, 0, 30, 30);
        fill(230);
        ellipse(0, 0, 10, 10);

        //hurricane lines
        push(); 
        scale(0.7);
        translate(-40, 5);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        push();
        scale(0.7);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        translate(40, -5);
        rotate(radians(180));
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        pop();
    }
      

The purpose of our project is to create an interactive calendar that displays important events, memes/jokes,
and or popular culture references to every month in 2020. Each program on its own is not very substantial,
but we aimed to incorporate as many programing elements from the semester as possible. It is a 2020 themed variety show!
The user-interface is a grid displaying the months of the year with instructions on how to access each month.
We have each month bound to a key, “1” through “=,” representing all 12 months.
When a particular key is pressed, the set of functions for the month run until the user presses the “esc” key to return to the main calendar.
The plans for my months are as follows:
Jan – Reference to the tension between the U.S. and North Korea at the tail end of 2019.
Feb – Pelosi Simulator: ripping President Trump’s speech at the State of the Union.
Mar – Object-oriented corona virus representation bouncing around a world map until it covers the U.S.
Apr – Something about Tiger King indeed.
May – Kim Jong Un hiding behind a podium after his health speculations .
Jun – President Trump removing protesters from St. John’s Church in Washington D.C.
We sincerely hope that 2021 is a much better year. Enjoy!

FinalProject-wildFire

sketch-koalaDownload
//Huijun Shen
//huijuns@andrew.cmu.edu 
//section D


//fire
var fireAnim = [];
var fireArr = [];

//particles
var drag = 0.0002;    
var gravity = 0.3;
var particles = [];

//koala
var koalaImg;
var koala;

//var counter
var counter = 5;


function preload(){
 
    //fire animation image
    var filenames = [];
    filenames[0] = "https://i.imgur.com/31vYPuX.png";
    filenames[1] = "https://i.imgur.com/ZhfTftF.png";
    filenames[2] = "https://i.imgur.com/iGSBFBe.png";
    filenames[3] = "https://i.imgur.com/GCq7AjU.png";
    filenames[4] = "https://i.imgur.com/zZGdjbN.png";
    
 
    for (var i = 0; i < filenames.length; i++) {
        fireAnim[i] = loadImage(filenames[i]);
    }

    koalaImg = loadImage("https://i.imgur.com/Xm5QW4o.png");

}

function setup(){
    createCanvas(480,480);
    frameRate(24);
    imageMode(CENTER);

    koala = koalaMake(45,420);
       
}   


function draw(){
    background(144,232,232);  

    //background trees
    var  col = 0; 
    var  row= 0;
    
    var  r = 0;
    for( col = 0; col < 18; col++){ //tree coloe gradation
        var  g = 200;
        var  b = 50;
        for( row = 3; row < 12; row++ ){
           fill(r,g,b);
           b +=5;
           treeDraw(col*28+12,row*38); 
        }
    r +=10;
    }    

    //counter

    textSize(15);
    fill(200,50,0);
    text("fire count ",15,25);
    text(counter.toString(),80,25);

    //intro text
    if(frameCount>0 & frameCount < 24){
        textSize(50);
        fill(255);
        text("Click Mouse",150,200);
    }

    if(frameCount>=24 & frameCount < 48){
        textSize(50);
        fill(255);
        text("Hit Key w",150,200);
    }

    //fire

    if(frameCount % 72 == 0){
        //print(startCount);
        var fire = makeFire(480,410);
        fireArr.push(fire);
    }

    for(var i = 0; i < fireArr.length; i++){
        var f = fireArr[i]
        f.drawFunction();
        f.stepFunction();

        print(f.size);
        //print(counter);

        if (f.size <= 0.2 || f.x <= 0.2){
            print(f.x);
            counter = counter - 1;

        }

        if (f.size<=0.2|| f.x <= 0.2 ){ //Here I choose 0.2 is because 0 is not working, the condition can not run
            fireArr.splice(i,1);
            print("test splice");
        }


 
    }   

     //sun
    fill(223,242,136);
    circle(400,50,50);

    // add new particle to the object
    newParticles = [];
    for (var i = 0; i < particles.length; i++) { // for each particle
        var p = particles[i];
        p.stepFunction();
        p.drawFunction();

    //particle vanishes
        if (p.age < 200) {
            newParticles.push(p);
        }
    }

    particles = newParticles;

   //trunck
    noStroke()
    fill(82,62,41);
    rect(30,280,12,200);

    //koala
    koala.drawFunction();
    koala.stepFunction();

    //ground
    fill(181,170,156);
    rect(0,450,480,30);

    //game ending, win or loose

    if(counter == 0){
        //background (255);
        textSize(40);
        fill(0,100,200,150);
        rect(0,0,width,height);
        fill(255);  
        image(koalaImg,width/2,height/2-100,150,150);           
        text("KOALA SAVED ! ",width/2-130,height/2);
        
        noLoop();
        
    } 

    for(var i = 0; i < fireArr.length; i++){
        var f = fireArr[i]

        if (dist(f.x,f.y,koala.x,koala.y) <= 50){
        background (255,50,0,150);
        textSize(40);
        fill(255);
        text("MISSION FAILED ! ",width/2-150,height/2);

        noLoop();
        }
    }



}


//make new particles by pressing mouse
function mousePressed() {
    var newp = makeParticle(mouseX, mouseY,
        random(-10, 10), random(-10, 0),color(random(1,255),random(1,255),random(1,255),random(5,15)));
    particles.push(newp);


    for(var j = 0; j < fireArr.length; j ++){
        var fire = fireArr[j];
        if(dist(mouseX,mouseY,fire.x,fire.y)<=  400*0.2*fire.size ){
            fire.size -= 0.2;
        }
        if(abs(fire.size -0.1) <=0.0001  || abs(fire.x-0)<0.0001 ){
            //print(fire.size)
            fireArr.splice(j,1);
        }

    }

}

function keyPressed(){
    if (key === "w"){
        koala.y += koala.dy;
    }
}

function counterUpdate(){
    for(var j = 0; j < fireArr.length; j ++){
        var fire = fireArr[j];
    }

    if (fireArr.length > 0  & fire.size <= 0){
        counter = counter - 1;
    }
    
}


function makeFire(fx,fy){
    var p = {x:fx,
         y:fy,
         dx:-8,
         imageNumber:0,
         size:1.0,
         stepFunction:stepFire,
         drawFunction:drawFire,
         }
    return p;

}

function stepFire(){
    this.imageNumber++;
    //print(this.imageNumber);
    if (this.imageNumber > 4){
        this.imageNumber = 0;
    }   
    this.x+=this.dx;
}

function drawFire(){

    push();
    translate(this.x,this.y);
    scale(0.3*this.size);   
    image(fireAnim[this.imageNumber],0,0);
    pop();

    //print("test", this.x,this.y);
}



function treeMake(tx,ty){
    var t = {x:tx,
         y:ty,
         color:c,     
         //stepFunction:stepFire,
         drawFunction:treeDraw,
         }
    return t;

}


function treeDraw(x,y){
    push();
    translate(x, y);
    triangle(-5,0,5,0,0,-15);
    
    beginShape();
    vertex(0,-35);
    vertex(-8,-20);
    vertex(0,-25);
    vertex(8,-20);
    endShape(CLOSE);

    beginShape();
    vertex(0,-25);
    vertex(-12,-12);
    vertex(0,-15);
    vertex(12,-12);
    endShape(CLOSE);

    pop();
}


//particles

function particleStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    this.dy = this.dy + gravity; // force of gravity
    // drag is proportional to velocity squared
    // which is the sum of the squares of dx and dy
    var vs = Math.pow(this.dx, 2) + Math.pow(this.dy, 2);
    // d is the ratio of old velocty to new velocity
    var d = vs * drag;
    //limit the speed
    d = min(d, 0.9);
    // scale dx and dy to include drag effect
    this.dx *= (0.8 - d);
    this.dy *= (0.9 - d);
    if(this.age % 40 == 0){
    this.size*= (1-0.2);
    } 

}

 
function particleDraw() {
   
    fill(this.pc);
    circle(this.x, this.y,this.psize);
}


// create a "Particle" object with position and velocity
function makeParticle(px, py, pdx, pdy,pc,psize) {

    p = {x: px, y: py,
         dx: pdx, dy: pdy,
         age: 0,
         pc:color(0,random(100,150),random(150,250)),
         psize:random(5,15),
         stepFunction: particleStep,
         drawFunction: particleDraw
        }
    return p;
}

//koala

function koalaMake(kx,ky){
    var k = {
        x:kx,
        y:ky,
        dy:-40, 
        gravityK:3,
        drawFunction:koalaDraw,
        stepFunction:koalaStep,
    }
    return k;
}

function koalaDraw(){

    image(koalaImg,this.x,this.y,70,70);

}

function koalaStep(){
    this.y += this.gravityK;
    this.y = constrain(this.y,280,423);

}

I am inspired by the wildfire this year which both happened in Australia and California. Till now I still can remember the pictures I saw about wildlives. Those pictures made me sad.
Also I would like to write one project a bit gamy which can bring some of the interesting points of 15104 together.

How to Play:
1 Hit right button on the fire to extinguish them
2 Or hit W key to move the koala when you failed in 1#
3 When you save your koala for 5 fireballs, you win.
4 If the fireball hit the koala, you lose.

Improvement:
1 If I have more time, I would add a start button. Now the program runs automatically. With the start button, the player will feel better.
2 Also, maybe I would add a tutorial before the game begins. Like, first one fireball is burning in the middle of the canvas, and the player needs to extinguish it first to start the game. Then, a fireball is coming toward the koala, the player needs to hit W to help the koala escape from the fire then start the game.

Final Project

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

}

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

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

    textSize(30);
    textAlign(CENTER);

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

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

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

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

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

    imageMode(CORNER);
    virusBorder();
}

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

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

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

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

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

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

Final Project: Covid-19 Precaution Simulator

In my final project, I showcase somewhat of a Covid-19 Precaution Simulation. The user is situated in the right side of the window and with the refreshing of the page, red virus balls and green mask/safety balls appear. The red viruses will come across the page at different speeds and sizes to symbolize the various ways of possibly contracting Covid-19. Hovering over the green safety orbs will help the users glowing shield to grow larger and brighter. As the shield grows, the viruses will be eliminated; at one point due to the immense “precautions and safety measures” that have been collected/taken by the user, the viruses die before reaching the shield, signifying that we can never be too safe in these times.

sketch
var shieldAttribute; //tracks size + color of shield
var mask=[]; //masks (green circles)
var virus = []; //virus (red circles)
var virusCount=10; //number of virus
var maskCount =15 // number of masks
var waves=10;
var x;
var y;
var speed;
var maskx;
var masky;
var maskr;
var checkMask;
var checkVirus;

function setup() {
  createCanvas(600, 400);
  shieldAttribute = 60; 
  for (var i = 0; i < virusCount; i++) {  //setting up to create virus objects
    var x;
    var y;
    var speed ;
    virus[i] = new Covid19(x, y, speed);
  }
  let checkMask = false;
  for (var j = 0; j < maskCount; j++) {  //creat mask objects
    mask[j] = new Masks(maskx, masky, maskr);
  }
}

function draw() {
  background(0);
  userGen();  //create user + shield 
  for (var i = 0; i < virusCount ; i++){  //functionality of virus implemented
    virus[i].generate();
    virus[i].forward();
    if(dist(virus[i].x, virus[i].y, 550, height/2)<= shieldAttribute-120){  //the virus balls get eliminated as they approach the growing shield
    virus[i].x = -600
  }
  }
  for (var j = 0; j < maskCount ; j++){  //functionality of virus implemented
    mask[j].build();
    mask[j].collect();
    mask[j].move();
  } 
}
//function for creating user
function userGen(){
  noStroke();
  fill(20,255,238,shieldAttribute/5);  //shield
  ellipse(550, height/2, shieldAttribute, shieldAttribute);
  
  fill(60, 198, 177);  //user circle
  ellipse(550, height/2 ,40, 40);
}

//COVID19 VIRUS CLASS
class Covid19 {
  constructor(){
    this.x = 0;
    this.y = random(20, 380);
    this.speed = random(0.5,2.5);
    this.virRad = random (30,50);
    this.checkVirus = false;
  }
  
  forward (){
  //  for (var i = 0; i < 5; i++){
    this.x += this.speed;
  }
  
  generate (){   //create the virus
    if (this.checkVirus == false){
    noStroke();
    fill(255,80,10);
    ellipse(this.x, this.y, this.virRad, this.virRad);
    }
  }
}

//MASK CLASS
class Masks {  
  constructor(){
    this.maskx = random(550);
    this.masky = random(350);
    this.maskr = random(10,80);
    this.checkMask = false;
  }
  
  build(){   //create the mask
    noStroke();  
    fill(50,240,80);
    if (this.checkMask == false){
    ellipse(this.maskx, this.masky, this.maskr);
    }
  }
  collect(){   //the mask balls disappear when hovered over, giving the illusion of "collecting"
    let d = dist(mouseX, mouseY, this.maskx , this.masky);
    if (d <= 20){
      shieldAttribute += this.maskr;
      this.checkMask = true;
      this.maskx = -600
      this.masky = -600
      this.maskr = 0
    }
  }
  
  move(){    //masks jittering to make collecting a bit more difficult
    this.maskx += random(-2,2);
    this.masky += random(-2,2);
  }
  
}

Final Project – Interactive Calendar

sketch
//Diana McLaughlin and Shaun Murray
//dmclaugh@andrew.cmu.edu and shaunmur@andrew.cmu.edu
//Section A and Section B
//A calendar commemorating a major event from each month in 2020
//All global variables except image variables are with the start of the respective month's program. Some of these variables are called in set up, but you'll find them before their clickMonthX() function
//Shaun's code starts at clickMonthJan(). He also wrote the makeCalendar() function
//Diana's code starts at clickMonthJul(). She also wrote the writeMonths() function
//Aside from the makeCalendar and writeMonths functions, Shaun did everything related to January - June and Diana did everything related to July - December
//"The biggest waste of computer processing power in 15-104"

//Image Variables
//for the main calendar
var imgJanCal, imgFebCal, imgMarCal, imgAprCal, 
	imgMayCal, imgJunCal, imgJulCal, imgAugCal, 
	imgSepCal, imgOctCal, imgNovCal, imgDecCal;

//for the month functions
var imgJan2, imgMar, aprImg, aprImg2, 
    aprImg3, imgJun1, imgJun2, imgJun3, 
    imgJul, imgOct, imgNov;


function preload() {
	imgJanCal = loadImage("https://i.imgur.com/mGCWr67.jpg?2"); //January main calendar
	imgFebCal = loadImage("https://i.imgur.com/8hI9x3x.jpg"); //February main calendar
	imgMarCal = loadImage("https://i.imgur.com/hozlVRU.jpg"); //March main calendar
	imgAprCal = loadImage("https://i.imgur.com/PUDQpPe.jpg"); //April main calendar
	imgMayCal = loadImage("https://i.imgur.com/FyUdmy7.png"); //May main calendar
	imgJunCal = loadImage("https://i.imgur.com/1V9Akde.jpg"); //June main calendar
	imgJulCal = loadImage("https://i.imgur.com/Tvukiin.jpg"); //July main calendar
	imgAugCal = loadImage("https://i.imgur.com/kECFW1b.jpg"); //August main calendar
	imgSepCal = loadImage("https://i.imgur.com/O6e3LcQ.jpg"); //September main calendar
	imgOctCal = loadImage("https://i.imgur.com/CcQpShS.jpg"); //October main calendar
	imgNovCal = loadImage("https://i.imgur.com/8Sqt5Um.jpg"); //November main calendar
	imgDecCal = loadImage("https://i.imgur.com/DrModlG.jpg"); //December main calendar

    imgJan = loadImage("https://i.imgur.com/UO8RoiW.png"); //santa hat for JAN
    imgJan2 = loadImage("https://i.imgur.com/lM5i1Gp.jpeg") //A-Bomb Jan
    imgFeb = loadImage("https://i.imgur.com/AIq3z8n.jpeg"); //House Chamber background
    imgMar = loadImage("https://i.imgur.com/VFoP91O.png"); //background image for March
    mayImg1 = loadImage("https://i.imgur.com/RhNvf13.jpeg"); //Kim Jong Un
	mayImg2 = loadImage("https://i.imgur.com/huOal0b.png"); //podium
	mayImg3 = loadImage("https://i.imgur.com/20G2Bj4.jpg"); //NK flag
    aprImg = loadImage("https://i.imgur.com/G0SnXSB.jpg"); //Tiger
	aprImg2 = loadImage("https://i.imgur.com/VVfSCll.jpeg"); //Oklahoma
	aprImg3 = loadImage("https://i.imgur.com/IgLfZQb.png"); //Joe Exotic
	imgJun1 = loadImage("https://i.imgur.com/V8MHehF.jpg"); //St John's Church
	imgJun2 = loadImage("https://i.imgur.com/on3fzqb.jpg"); //President
	imgJun3 = loadImage("https://i.imgur.com/SAUkUd3.jpg"); //Protesters
	imgJul = loadImage("https://i.imgur.com/FXdV1Bk.jpg"); //John Lewis photograph for July
    imgOct = loadImage("https://i.imgur.com/a7W8anl.png"); //map for Oct
    imgNov = loadImage("https://i.imgur.com/OCT1IpR.jpg"); //auditorium for November
}

function setup() {
    createCanvas(500, 400);
    makeCalendar();

    //set up March
    for (var i = 0; i < 1; i++) {
    // make virus cell
    	var v = makeVirus(200, 200,
                             random(-50, 50), random(10, 50));
        viruses.push(v);
    }

    //set up for April
    for (var i = 0; i < 12; i++){ // create an initial collection of cats
        var rx = random(width);
        tigers[i] = makeTigers(rx);
    }

    //set up August
    for (var i = 0; i < 1; i++){
        var hy = random(height/3, height);
        hurricane[i] = makeHurricane(hy);
    } 
    
    //set up September
    //set up mountains
    for (var i = 0; i <= 100; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height/2);
        mountain.push(value);
        noiseParam += noiseStep;
    }  

    //set up fire
    for (var i = 0; i <= 100; i++) {
        var n = noise(fNoiseParam);
        var value = map(n, 0, 1, 0, height);
        fire.push(value);
        fNoiseParam += fNoiseStep;
    }  
    
    //draw initial trees
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    
    //draw initial smoke clouds
    for (var i = 0; i < 10; i++){
        var cx = random(width);
        smoke[i] = makeSmoke(cx);
    }
    
}

function draw() {
	clickMonthJan();
	clickMonthFeb();
	clickMonthMar();
	clickMonthApr();
	clickMonthMay();
	clickMonthJun();
	clickMonthJul();
	clickMonthAug();
	clickMonthSep();
	clickMonthOct();
	clickMonthNov();
	clickMonthDec();
	backButton();
}

function makeCalendar() {
	fill(0);
    strokeWeight(1);
    //draw lines between the months on the calendar
    for (let i = 0; i < 3; i++) {
        line(0, i*133.33 + 133, width, i*133.33 + 133);
        line(i*125 + 125, 0, i*125 + 125, height);
    }

    //background pictures
    var calPics = [imgJanCal, imgFebCal, imgMarCal, imgAprCal, imgMayCal, imgJunCal, imgJulCal, imgAugCal, imgSepCal, imgOctCal, imgNovCal, imgDecCal];
    var xCo = [0.5, 125.5, 250.5, 375.5, 0, 125.5, 250.5, 375.5, 0.5, 125.5, 250.5, 375.5];
    var yCo = [0, 0, 0, 0, 132.83, 132.83, 132.83, 132.83, 267.16, 267.16, 267.16, 267.16];
    for (var i = 0; i < calPics.length; i++) {
    	image(calPics[i], xCo[i], yCo[i], 124.5, 132.83);
    }

    writeMonths();

}

function writeMonths() {
	//display text on calendar
	var monthText = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	var monthCode = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", " ", "="];
	var monthX = [55, 180, 305, 430, 55, 180, 305, 430, 55, 180, 305, 430];
	var monthY = [65, 65, 65, 65, 200, 200, 200, 200, 335, 335, 335, 335];
	strokeWeight(1);
	textFont('Times');
    textSize(24);
    textAlign(CENTER);
    stroke(0);
    fill(255);
    for (var i = 0; i < monthText.length; i++) {
    	text(monthText[i], monthX[i], monthY[i]);
    	text(monthCode[i], monthX[i], monthY[i] + 30);
    }
    textSize(40);
    text("-", 300, 363);
    textSize(15);
    textAlign(LEFT);
    text("Press a key to begin", 3, 25); //written instruction
    text("Press ESC to return", 380, 25);
}

function backButton() { //click to return to calendar
    if (keyCode === 27) {
        clearBkrd();
        makeCalendar();

        //reset March
        v.diam = 25;

        //reset November
        pCount = 0;
        vpCount = 0;
    }
}

function clearBkrd() { //clear background
    background(255);
}

//Shaun's Code

function clickMonthJan() {
	//Referencing the anticipation of North Korea's overdue X-mas gift
    if (keyCode === 49) {
        clearBkrd();
        frameRate(30);
        JanBackground();
        USflag();
        NKflag();
        nuclear(width/2, height/2);
        JanText(45, height-85);
        backButton(); 
    }
         
}

	function JanBackground() {
		image(imgJan2, 0, 0, width, height);
	}

    function starJan() {
        var x1 = [340, 348, 364, 354, 356, 340, 324, 326, 315, 332]; //star points
        var y1 = [44, 58, 62, 75, 92, 85, 92, 75, 62, 58];
        var nPoints= x1.length;
        beginShape();
        fill('Red');
        for (var i= 0; i< nPoints; i++) {
            vertex(x1[i] + 35, y1[i] + 5);
        }
        endShape(CLOSE);
    }

    function USflag() {// United States Flag minus stars
        fill('Red');
        rect(25, 25, width/3, height/4);
        for(let i = 0; i < 7; i++) { //white rects on flag
            fill('white');
            rect(25, 30 + (i * 13.5), width/3, 7);
        }
        fill(0, 0, 155);
        rect(25, 25, 50, 50);
    }

    function NKflag() { //North Korean Flag
        fill('Blue');
        rect(width-164, 25, width/3, height/4);
        push();
        fill('Red');
        strokeWeight(5);
        noStroke();
        rect(width-163, 40, width/3 + 6, 70); //white border in flag
        stroke('White');
        line(width, 40, width-161, 40);
        line(width, 110, width-161, 110);
        pop();
        noStroke();
        fill('White');
        circle(width-125, 75, 53);
        stroke(0);
        push();
        starJan();
        pop();
    }

    function nuclear(x, y) { //nuclear symbol
        push();
        translate(x, y);
        let d = 80
        let d1 = 10
        stroke(0);
        strokeWeight(3);
        fill('yellow'); //draw circles
        circle(0, 0, d);
        fill('black');
        circle(0, 0, d1);

        let deg = 120;
        let dx = 5;
        let angle = 45;

        rotate(radians(angle));
        for (let i = 0; i < 3; i++) { //draw triangles 
            rotate(radians(deg));
            beginShape();
            fill('black');
            vertex(-7, -7);
            vertex(-30, -10);
            vertex(-10, -30);
            endShape(CLOSE);
        }

        angle = angle + dx;
        pop();

        push();
        rotate(radians(-20));
        image(imgJan, 135, 185, 100, 100); //santa hat
        pop();

    }

    function JanText(x, y) { //display text for Jan
        push();
        translate(x, y);
        textSize(23);
        fill(255);
        text("United Shaysh of America VS. North Korea", 0, 0);
        pop();
    }

//Global variables for Feb
var rip = 0//checks to see if SotU is ripped

function clickMonthFeb() {
	//Referencing the ripped speech at the State of the Union address
    if (keyCode === 50) {
        clearBkrd();
        frameRate(30);
        drawPaper();
		drawRip();
		mendPaper();
        backButton();
    }   
    
}

	//February helper functions
	function drawPaper() { //draw initial SotU
		push();
		background('grey');
		image(imgFeb, 0, 0);
		fill('white');
		rectMode(CENTER);
		rect(width/2+30, height/2, 200, 300);
		rect(width/2+15, height/2, 200, 300);
		rect(width/2, height/2, 200, 300);
		textStyle(ITALIC);
		textSize(22);
		fill('black');
		text("State of the Union", 160, 80);
		fill('white');
		text("Click and hold to rip!", width-205, 25);
		text("Nancy Pelosi Simulator", 10, 25);
		line(180, 110, 320, 110);
		for (let i = 0; i < 20; i++) {
			line(165, 120 + i*11, 335, 120 + i*11);
		}
		pop();
	}

	function drawRip() { //Rip SotU
		push();
		if (mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			textStyle(ITALIC);
		    textSize(22);
			fill('white');
			text("Release mouse to mend...", 10, 25);
			push();
			rotate(radians(-30));
			fill('white');
			rectMode(CORNER);
			rect(width/2-300, height/2-80, 100, 300);
			for (let i = 0; i < 20; i++) {
				line(-40, 190 + i*11, 40, 190 + i*11);
			}
			fill('black');
			text("State of t", -50, 160);
			rotate(radians(60));
			fill('white');
			rect(width/2+160, height/2-345, 100, 300);
			for (let j = 0; j < 20; j++) {
				line(width/2+175, height/2-280 + j*11, width/2+250, height/2-280 + j*11);
			}
			fill('black');
			text("he Union", width/2+162, height/2-300);
			pop();
			pop();
			rip = 1;
		}
	}

	function mendPaper() { //Tape SotU back together like a good American
		push();
		if (rip == 1 & !mouseIsPressed) {
			background('grey');
			image(imgFeb, 0, 0);
			fill('white');
			rectMode(CENTER);
			rect(width/2+30, height/2, 200, 300);
			rect(width/2+15, height/2, 200, 300);
			rect(width/2, height/2, 200, 300);
			textStyle(ITALIC);
			textSize(22);
			fill('black');
			text("State of the Union", 160, 80);
			fill('white');
			text("Click and hold to rip!", width-205, 25);
		    text("Nancy Pelosi Simulator", 10, 25);
			fill('black');
			line(180, 110, 320, 110);
			for (let i = 0; i < 20; i++) {
				line(165, 120 + i*11, 335, 120 + i*11);
			}
	        fill(255, 248, 220);
			rect(width/2-15, height/2, 30, 300);
			pop();
		}
	}
//Global variable for March
var viruses = [];

function clickMonthMar() {
	//Referencing the spread of COVID-19 in the U.S.
    if (keyCode === 51) {
        clearBkrd();
        backButton();
        frameRate(15);
        image(imgMar, 0, 0, 500, 400);

	    for (var i = 0; i < viruses.length; i++) {
	        var v = viruses[i];
	        v.stepFunction();
	        v.drawFunction();
	        if (v.diam > 450) {
	        	background(0);
	        	stroke(255, 0, 0);
	        	strokeWeight(4);
	        	push();
	        	textSize(48);
	        	translate(width/2, height/2)
	        	rotate(radians(90));
	        	text(":(", 0, 0);
	        	pop();
	        	stroke(0);
	        	strokeWeight(2);
	        	fill('white');
	        	text("Sad", width/2, height/2 + 100);
	        }
	    }
    }   
    
}

	//March Helper Functions
	function virusStep() {
    this.age++;
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > width) { // bounce off right wall
        this.x = width - (this.x - width);
        this.dx = -this.dx;
        this.diam *= 1.25;
    } else if (this.x < 0) { // bounce off left wall
        this.x = -this.x;
        this.dx = -this.dx;
        this.diam *= 1.25;
    }
    if (this.y > height) { // bounce off bottom
        this.y = height - (this.y - height);
        this.dy = -this.dy;
        this.diam *= 1.25;
    } else if (this.y < 0) { // bounce off top
        this.y = -this.y;
        this.dy = -this.dy;
        this.diam *= 1.5;
    }
	}


	function virusDraw() {
		stroke('black');//body of virus
		strokeWeight(2);
		fill('red');
		push();
	    translate(this.x, this.y);
		circle(0, 0, this.diam);
		strokeWeight(3);//stems of virus
		var angle = 45;
		for (let i = 0; i < 8; i++) {
			rotate(radians(angle));
			beginShape();
	        vertex(this.diam/2 - 10, 0)
	        vertex(random(this.diam/2 + 4, this.diam/2 + 8), random(-2, 2));
	        endShape(CLOSE);
	        ellipse(random(this.diam/2 + 8, this.diam/2 + 6), random(1, 3), 11, 9);
	    }
	    pop();
	}


	// create a "Particle" object with position and velocity
	function makeVirus(vx, vy, vdx, vdy) {
	    v = {x: vx, y: vy,
	         dx: vdx, dy: vdy,
	         age: 0,
	         diam: 25,
	         stepFunction: virusStep,
	         drawFunction: virusDraw
	        }
	    return v;
	}	

// Global variables for April
var tigers = [];
var deg = 10
var joe = 1;

function clickMonthApr() {
	//Referencing the popularity of the Tiger King documentary on NETFLIX in March/April
    if (keyCode === 52) {
        clearBkrd();
        frameRate(12);
        displayHorizon();
   		updateAndDisplayTigers();
    	removeTigersThatHaveSlippedOutOfView();
    	addNewTigersWithSomeRandomProbability();
        backButton();
    }
       
}

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


	function removeTigersThatHaveSlippedOutOfView(){
	    var tigersToKeep = [];
	    for (var i = 0; i < tigers.length; i++){
	        if (tigers[i].x + tigers[i].breadth > 0) {
	            tigersToKeep.push(tigers[i]);
	        }
	    }
	    tigers = tigersToKeep; // remember the surviving tigers
	}


	function addNewTigersWithSomeRandomProbability() {
	    // With a very tiny probability, add a new cat to the end.
	    var newTigersLikelihood = 0.03; 
	    if (random(0,1) < newTigersLikelihood) {
	        tigers.push(makeTigers(width));
	    }
	}


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

	// draw the cat and more cats
	function tigersDisplay() {
	    push();
	    translate(this.x, height - floor(random(30, 40))); 
	    image(aprImg, 0, -15, 80, 35);
	    pop();
	}


	function makeTigers(birthLocationX) {
	    var tgs = {x: birthLocationX,
	                breadth: 50,
	                speed: -1.0,
	                move: tigersMove,
	                display: tigersDisplay}
	    return tgs;
	}

	function displayHorizon(){
		image(aprImg2, 0, 0, width, height);
		push();
		translate(60, 80);
		imageMode(CENTER);
		rotate(radians(deg));
		for (let i = 0; i < joe; i++) {
			image(aprImg3, 0, 0, 80, 80);
		}
		pop();
		deg = deg + 10;
	}

function clickMonthMay() {
	//Referencing Kim Jong Un's questionable health and reappearance
    if (keyCode === 53) {
        clearBkrd();
        frameRate(60);
        drawBackdrop();
		leader();
		drawPodium();
        backButton(); 
    }  
    
}

	//May helper functions
	function leader() {
		push();
		var top = height/2;
	    var bottom = height;
	    var conY = constrain(mouseY, top, bottom);
		imageMode(CENTER);
		image(mayImg1, width/2, conY, 120, 180);
		pop();
	}

	function drawPodium() {
		push();
		imageMode(CENTER);
		image(mayImg2, 250, 400, 300, 250);
		pop();
	}

	function drawBackdrop() {
		push();
		imageMode(CENTER);
		image(mayImg3, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("N.K. Leader Simulator", 10, 30);
		text("Moves with your mouse!", width-210, 30);
		pop();
	}

//Global variable June
var moveJun = 1;

function clickMonthJun() {
	//Referencing President Trump's removal of protesters from St. John's church in D.C.
    if (keyCode === 54) {
        clearBkrd();
        frameRate(30);
        drawChurch();
	    drawPres();
	    drawProtest();
	    fightBack();
        backButton();  
    } 
}

	function drawChurch() {
		push();
		imageMode(CENTER);
		image(imgJun1, width/2, height/2, 500, 400);
		textSize(20);
		fill('black');
		text("Click and hold mouse to fight back!", 10, 25);
		pop();
	}

	function drawPres() {
		push();
		var junX1 = width - 50;
		var conX1 = constrain(junX1 - moveJun, 230, width + 60);
		imageMode(CENTER);
		image(imgJun2, conX1 , height-50, 120, 130);
		pop();
	}

	function drawProtest() {
		push();
		var junX2 = 80;
		var conX2 = constrain(junX2 - moveJun, -100, 230);
		imageMode(CENTER);
		image(imgJun3, conX2, height-50, 200, 150);
		pop();
	}

	function fightBack() {
		push();
		moveJun ++;
		print(moveJun);

		if (mouseIsPressed) {
			moveJun -= 2;
		}

		moveJun = constrain(moveJun, -150, 230);
		pop();
	}

//Diana's Code

var julXPoints = [];
var julYPoints = [];
var julClr = [];

function clickMonthJul() {
//Remembering John Lewis
    if (keyCode === 55) {
    	clearBkrd();
    	frameRate(60);
        imgJul.resize(width, height);
        imgJul.loadPixels();
        var x = random(width); //randomly draw pixels for a portrait of John Lewis
	    var y = random(height);
	    var clr = imgJul.get(x, y);
    	stroke(clr);
		strokeWeight(5);
	   	noFill();
	   	point(x, y); 
	   	julXPoints.push(x); //push the coordinates into arrays so it doesn't look like the background keeps drawing over it
	   	julYPoints.push(y);
	   	julClr.push(clr);
	   	for (var i = 0; i < julXPoints.length; i++) {
	   		stroke(julClr[i]);
	   		point(julXPoints[i], julYPoints[i]);
	   	}
        backButton(); 
    }
      
}

function clickMonthAug() {
//SpaceX Launch
	strokeWeight(1);
	stroke(0);
    if (keyCode === 56) {
        clearBkrd();
        background(0);
        frameRate(30);
		for (var i = 0; i < 3; i++) {
			for(var j = 0; j < 4; j++){
				star(i*200 + 25, j*100);
			}	
		}

		for (var a = 0; a < 2; a++) {
			for (var b = 0; b < 4; b++) {
				star(a*200 + 125, b*100 + 50);
			}
		}
		spaceship(200, 150);
		backButton(); 
	    }
}
    //August Helper Functions
	function spaceship(x, y) {
		push();
		translate(x, y);
		rotate(radians(30));
		fill(255);
		ellipse(25, 0, 50, 100); //spaceship body
		rect(0, 0, 50, 150);
		stroke(255, 0, 0);
		strokeWeight(3);
		push();
		rotate(radians(-90));
		text("SpaceX", -120, 25);
		pop();
		stroke(0);
		strokeWeight(1);
		triangle(0, 75, 0, 150, -35, 150); //wings
		triangle(50, 75, 50, 150, 85, 150);
		push();
		translate(-35, 150);
		for (var i = 0; i < 3; i++) { //draw flames
			fill(255, 175, 0);
			triangle(i*40, 0, (i+1)*40, 0, (i*40 + random(15, 25)), random(95, 105));
		}
		pop();
		pop();
	}

	function star(x, y) {
		var sx = [0, 5.5, 16.5, 9.5, 10.5, 0, -10.5, -9.5, -16.5, -5.5];
		var sy = [0, 9.5, 12.5, 21, 32, 27.5, 32, 21, 12.5, 10.5];
		push();
		translate(x, y);
		fill(255, 255, 0);
	    var nPoints = sx.length;
	    beginShape();
	    for (var i = 0; i < nPoints; i++) {
	    	vertex(sx[i] + random(-1, 1), sy[i] + random(-1, 1));
	    }
	    endShape(CLOSE);
	    pop();
	}

//Global Variables for September
var trees = [];
var smoke = [];
var mountain = [];
var fire = [];
var noiseParam = 0; //controls mountain landscape
var noiseStep = 0.01;
var fNoiseParam = 0; //controls fire
var fNoiseStep = 0.05;

function clickMonthSep() {
//West Coast Wildfires
    if (keyCode === 57) {
        clearBkrd();
        text("Sep TEST", width/2, height/2);
        backButton();
        frameRate(10);
        background(100); //dark grey

	    updateAndDisplaySmoke();
	    removeSmokeThatHasSlippedOutOfView();
	    addNewSmokeWithSomeRandomProbability();

	    mountains();
	    makeFire();
	    fill(75);
	    rect(0, 335, width, 65); //ground

	    updateAndDisplayTrees();
	    removeTreesThatHaveSlippedOutOfView();
	    addNewTreesWithSomeRandomProbability();   
	}
}

//September Helper Functions
	function updateAndDisplayTrees(){
	    // Update the trees' positions
	    for (var i = 0; i < trees.length; i++){
	        trees[i].move();
	        trees[i].display();
	    }
	}


	function removeTreesThatHaveSlippedOutOfView(){
	    //remove these trees from the array
	    var treesToKeep = [];
	    for (var i = 0; i < trees.length; i++){
	        if (trees[i].x + trees[i].breadth > 0) {
	            treesToKeep.push(trees[i]);
	        }
	    }
	    trees = treesToKeep;
	}


	function addNewTreesWithSomeRandomProbability() {
	    // Add a new tree to the end of the array
	    var newTreeLikelihood = 0.05; 
	    if (random(0,1) < newTreeLikelihood) {
	        trees.push(makeTree(width));
	    }
	}

	function treeMove() {
	    this.x += this.speed;
	}
	    
	function treeDisplay() {
	    //draw the tree
	    var tHeight = 90; 
	    strokeWeight(5);
	    stroke(0); 
	    push();
	    translate(this.x, height - 40);
	    line(0, -tHeight, 0, 0);
	    line(0, -40, -22, -75);
	    line(0, -40, 22, -75);
	    line(0, -50, -15, -85);
	    line(0, -50, 15, -85);
	    line(0, -30, -30, -65);
	    line(0, -30, 30, -65);
	    stroke(200); 
	    pop();
	}


	function makeTree(birthLocationX) {
	    var tr = {x: birthLocationX,
	                breadth: 50,
	                speed: -3.5,
	                move: treeMove,
	                display: treeDisplay}
	    return tr;
	}

	//Smoke Clouds

	function updateAndDisplaySmoke(){
	    // Update the smoke positions
	    for (var i = 0; i < smoke.length; i++){
	        smoke[i].move();
	        smoke[i].display();
	    }
	}


	function removeSmokeThatHasSlippedOutOfView(){
	    // remove clouds that are no longer visible
	    var smokeToKeep = [];
	    for (var i = 0; i < smoke.length; i++){
	        if (smoke[i].x + smoke[i].breadth > 0) {
	            smokeToKeep.push(smoke[i]);
	        }
	    }
	    smoke = smokeToKeep;
	}


	function addNewSmokeWithSomeRandomProbability() {
	    // Add smoke clouds to the end of the arrayS
	    var newSmokeLikelihood = 0.02; 
	    if (random(0,1) < newSmokeLikelihood) {
	        smoke.push(makeSmoke(width));
	    }
	}

	function smokeMove() {
	    this.x += this.speed;
	}
	    

	// draw smoke
	function smokeDisplay() { 
	    fill(50); 
	    noStroke(); 
	    push();
	    translate(this.x, this.y);
	    ellipse(0, this.y, 90, 15);
	    ellipse(0, this.y+10, 100, 15);
	    ellipse(0, this.y-10, 80, 15);
	    pop();
	}


	function makeSmoke(birthLocationX) {
	    var smk = {x: birthLocationX,
	    	        y: random(0, height/2),
	                breadth: 50,
	                speed: -3.,
	                move: smokeMove,
	                display: smokeDisplay}
	    return smk;
	}


	function mountains() {
	    //use random noise to draw mountains
	    mountain.shift();
	    var n = noise(noiseParam);
	    var value = map(n, 0, 1, 0, height);
	    mountain.push(value);
	    noiseParam += noiseStep;
	    
	    
	    fill(0); //black - mountain shadows
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, mountain[i]);
	    }
	    vertex(width, height);
	    endShape(); 
	}

	function makeFire() {
	    //use random noise to draw mountains
	    fire.shift();
	    var n = noise(fNoiseParam);
	    var value = map(n, 0, 1, 0, height);
	    fire.push(value);
	    fNoiseParam += fNoiseStep;
	    
	    
	    fill(255, 0, 0); //red layer
	    beginShape();
	    vertex(0, height);
	    for (var i = 0; i <= 100; i++) {
	        vertex(i*5, fire[i]);
	    }
	    vertex(width, height);
	    endShape(); 

	    fill(255, 175, 0); //orange layer
	    beginShape();
	    vertex(0, height);
	    for (var j = 0; j <= 100; j++) {
	    	vertex(j*5, fire[j] + 50);
	    }
	    vertex(width, height);
	    endShape();

	    fill(255, 255, 0); //yellow layer
	    beginShape();
	    vertex(0, height);
	    for (var p = 0; p <= 100; p++) {
	    	vertex(p*5, fire[p] + 100);
	    }
	    vertex(width, height);
	    endShape();
     
}

//October Global Variables
var hurricane = [];
var xMove = [];
var imgOct;

function clickMonthOct() {
	//Busiest hurricane season on record
    if (keyCode === 48) {
        clearBkrd();
        frameRate(15);
        translate(width, 0);
	    image(imgOct, -width-50, -107, 650, 560);
		updateAndDisplayHurricane(); 
		removeHurricanesThatHaveSlippedOutOfView();
		addNewHurricanesWithSomeRandomProbability();
        backButton();
    }
}

	//October Helper Functions
		function updateAndDisplayHurricane(){
	    // Update the hurricanes' positions
	    for (var i = 0; i < hurricane.length; i++){
	        hurricane[i].move();
	        hurricane[i].display();
	    }
	}

	function removeHurricanesThatHaveSlippedOutOfView(){
	    //remove these hurricanes from the array
	    var hurricanesToKeep = [];
	    for (var i = 0; i < hurricane.length; i++){
	        if (hurricane[i].x > -550 || hurricane[i].y > -50) {
	            hurricanesToKeep.push(hurricane[i]);
	        }
	    }
	    hurricane = hurricanesToKeep;
	}

	function addNewHurricanesWithSomeRandomProbability() {
	    // Add a new hurricane to the end of the array
	    var newHurricaneLikelihood = 0.025;
	    var newHY = random(height/3, height);
	    this.xMove = random(10);
	    this.yMove = random(10);
	    if (random(0,1) < newHurricaneLikelihood) {
	        hurricane.push(makeHurricane(newHY));
	    }
	}

	function hurricaneMove() {
		this.x -= this.hxMove;
		this.y -= this.hyMove;
		this.spin += 10;
	}

	function hurricaneDisplay() {
		push();
		translate(this.x, this.y);
		rotate(radians(this.spin));
	    noStroke();
	    fill(255, 0, 0);
	    ellipse(0, 0, 30, 30);
	    fill(230);
	    ellipse(0, 0, 10, 10);
		push();
		scale(0.7);
		translate(-40, 5);
		stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
	    
	    push();
	    scale(0.7);
	    stroke(255, 0, 0);
		strokeWeight(5);
		noFill();
	    translate(40, -5);
	    rotate(radians(180));
		beginShape();
		for (var i = 2; i <= 4; i += 0.1) {
			var y1 = Math.pow(2.6, i);
	    	vertex(i*25, -y1);
		}
		endShape();
		pop();
		pop();
	}

	function makeHurricane(birthLocationY) {
		var h = {x: 0, y: birthLocationY, hxMove: xMove, hyMove: 5, move: hurricaneMove, spin: 0, display: hurricaneDisplay}
	    return h;
	}

//November Global Variables
var theta = 0;
var txp = 0;
var typ = 0;
var thetavp = 0;
var txvp = 0;
var tyvp = 0;
//counters
var pCount = 0;
var vpCount = 0;

function clickMonthNov() {
//2020 US Presidential Election
    strokeWeight(1);
	stroke(0);
	textSize(14);

    if (keyCode === 189) {
        clearBkrd();
        frameRate(15);
        backButton();
        image(imgNov, -150, -60, 800, 650);
        stroke(255);
		president(150, 200);
		vicePresident(350, 200);
		fill(255);
		text("Who will be the first to 270?", 150, 20);
		text("Click the mouse on the left to give Alec Baldwin electoral votes", 75, 45)
		text("Click the mouse on the right to give Jim Carrey electoral votes", 75, 70);
		text(pCount, 150, 120);
		text(vpCount, 350, 120);
		debate();
	}

    	if (pCount >= 270) {
			background(255, 0,0);
			textSize(30);
			stroke(0);
			fill(0);
			text("I did it! It was RIGGED but I won!", 20, height/2 - 15);
			text("Very good for our Great Country", 25, height/2 + 15);
		}

		if (vpCount >= 270) {
			background(0, 0, 255);
			textSize(50);
			stroke(255);
			fill(255);
			text("Will you shut up man!", 5, height/2);
		}
	
}
    //November Helper Functions    
	function debate(){
		if (mouseIsPressed) {
			if (mouseX < width/2) { //move president
				theta = 15;
				txp = 150;
				typ = -100
				pCount = pCount + 5;				
			}

			if (mouseX >= width/2) { //move vice president
				thetavp = -15;
				txvp = -150;
				tyvp = 0;
				vpCount = vpCount + 5;
			}
		}
	} 

	function mouseReleased() {
		if (theta === 15) { //reset president
			theta = 0;
			txp = 0;
			typ = 0;					
		}

		if (thetavp === -15) { //reset vice president
			thetavp = 0;
			txvp = 0;
			tyvp = 0;				
		}
	}

	function president(x, y) {
		push();
		rotate(radians(theta));
		translate(x + txp, y + typ);
		noStroke();
		fill(255, 175, 0);
		push();
		rotate(radians(75)); //mouth
		ellipse(17, -12, 4, 15);
		rotate(radians(30));
		ellipse(15, -17, 4, 15);
		pop();
		fill(255, 175, 0); //head
		ellipse(0, 0, 40, 50);
		fill(255, 255, 0); //hair
		ellipse(3.5, -20, 45, 15);
		fill(255); //eyes
		ellipse(10, -2, 8, 8);
		fill(0);
		ellipse(10, -2, 4, 4);
		stroke(0);
		line(25, 17, 40, 17);
		line(25, 9, 40, 1);
		line(25, 25, 40, 33);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 32, 50);
		fill(0, 0, 255); //suit jacket
		rect(-15, 23, 25, 50);
		fill(255, 0, 0); //tie
		rect(14, 23, 3, 30);
		fill(0); //shoes
		ellipse(3, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 27, 60);
		push(); //arm
		rotate(radians(-40));
		fill(255, 175, 0);
		ellipse(15, 40, 15, 10);
		fill(0, 0, 255);
		rect(-35, 35, 50, 10);
		pop();
		pop();
	}

	function vicePresident(x, y) {
		push();
		rotate(radians(thetavp));
		translate(x + txvp, y + tyvp);
		noStroke();
		fill(250, 237, 203); //head
		ellipse(-2, 0, 40, 50);
		fill(255); //hair
		ellipse(0, -22, 35, 8);
		fill(255); //eyes
		ellipse(-10, -4, 8, 8);
		fill(0);
		ellipse(-10, -4, 4, 4);
		fill(255, 0, 0); //mouth
		ellipse(-12, 13, 8, 8);
		stroke(0);
		line(-25, 13, -40, 13);
		line(-25, 8, -40, 0);
		line(-25, 18, -40, 26);
		noStroke();

		//suit
		fill(255); //shirt
		rect(-15, 23, 25, 50);
		fill(0, 0, 255); //suit jacket
		rect(-8, 23, 18, 50);
		fill(255, 0, 0); //tie
		rect(-15, 23, 3, 30);
		fill(0); //shoes
		ellipse(-7, 133, 35, 15);
		fill(0, 0, 255); //pants
		rect(-15, 73, 25, 60);
		push(); //arm
		rotate(radians(40));
		fill(250, 237, 203);
		ellipse(-18, 45, 10, 10);
		fill(0, 0, 255);
		rect(-18, 40, 50, 10);
		pop();
		pop()
		}

//December global variables - firework coordinate arrays     
var xpos = 0;
var xcoord = [35, 25, 55, 200, 240, 400, 470, 440, 455, 230, 280, 415, 100, 280];
var ycoord = [25, 100, 350, 120, 150, 75, 45, 175, 300, 320, 365, 340, 215, 50];

function clickMonthDec() {
	//abstract clock to wait for the end of 2020
    if (keyCode === 187) {
        clearBkrd();
        backButton();
        frameRate(5);
    	background(0);
	    var sec = second();
	    var min = minute();
	    var hr = hour();
	    var d = day();
	    background(0);

	    //draw fireworks in the background
	    for (var i = 0; i < 14; i++) {
	        firework(xcoord[i], ycoord[i]);
	    }

	    push();
	    scale(0.5);
	    president(16*d, 40); //moves with day
	    pop();
	    decVirus(20*hr, 150); //hour
	    image(aprImg3, 8*min, 200, 80, 80); //minute
	    decHurricane(8*sec, 350); //second

	}
}

	//December helper functions
	function firework(x, y) { 
	    var r = random(255);
	    var g = random(255);
	    var b = random(255);
	    push();
	    translate(x, y);
	    stroke(r, g, b);
	    for (var i = 0; i < 12; i++) { //draw lines
	        push();
	        rotate(radians(i*30));
	        line(xpos, 0, xpos + 15, 0);
	        pop();
	    }

	    if (xpos <= 25) { //grow
	    xpos += 1;
	    }

	    else if (xpos > 25) { //reset
	        xpos = 0;
	    }
	    pop();
	}

	function decVirus(x, y) { //design taken from Shaun's virus object - I did not code
	        stroke('black');//body of virus
	        strokeWeight(2);
	        fill('red');
	        push();
	        translate(x, y);
	        circle(0, 0, 35);
	        strokeWeight(3);//stems of virus
	        var angle = 45;
	        for (let i = 0; i < 8; i++) {
	            rotate(radians(angle));
	            beginShape();
	            vertex(35/2 - 10, 0)
	            vertex(random(35/2 + 4, 35/2 + 8), random(-2, 2));
	            endShape(CLOSE);
	            ellipse(random(35/2 + 8, 35/2 + 6), random(1, 3), 11, 9);
	        }
	        pop();
	}

    function decHurricane(x, y) { //from October 
        push();
        translate(x, y);
        noStroke();
        fill(255, 0, 0);
        ellipse(0, 0, 30, 30);
        fill(230);
        ellipse(0, 0, 10, 10);

        //hurricane lines
        push(); 
        scale(0.7);
        translate(-40, 5);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        push();
        scale(0.7);
        stroke(255, 0, 0);
        strokeWeight(5);
        noFill();
        translate(40, -5);
        rotate(radians(180));
        beginShape();
        for (var i = 2; i <= 4; i += 0.1) {
            var y1 = Math.pow(2.6, i);
            vertex(i*25, -y1);
        }
        endShape();
        pop();
        pop();
    }
      

Press any key in the row from “1” to “=” to select a month

Press “esc” to return to the main calendar and select another month

Shaun and I made this interactive monthly calendar recap of 2020 based on the memes from the beginning of the year that something big and strange was happening every month. It was not that hard to come up with events. I picked the events that I did partly based on what I had programming ideas for and partly in order to include some variety and show how many different things happened this year. We have many different types of events, from satire to more serious ones that we wanted to commemorate.
To use the program, press a key in line from “1” down to “=” to display a different month (“-” corresponds to November and “=” is December). Press “esc” to leave the month and return to the main calendar, or you can move between the months themselves. The counters in the March and November functions will reset if you leave the month by hitting “esc” so you can go back and run the simulation again, but they will not reset if you leave the month and return to it from another month (without hitting “esc” in between). I never have July reset because the portrait takes awhile to draw, so I didn’t think it needed to start over every time the month is replayed.
If I had more time, I would have liked to do more with the August function to make it interactive in some way, but I didn’t want to just link the spaceship to mouseX and mouseY, so I left it as is for now. Maybe eventually I could make it so that you can steer the spaceship through space or something.

Final Project – Maze

    For my project, I created a maze with a turtle guiding the path to get out of the maze. My goal was to make this environmentally themed because this is still a persistent issue. The wonderful thing about where technology is headed, however, we can do a lot more to solve some of these issues. For example, electric automobiles replacing gas ones. Another motivator was to continue to bring self awareness. It’s crazy to think that people were freaking out in the 2020 debates/election over the fear that Biden would “force” everyone to get an electric car. Of course I see the issue in getting rid of gas cars all of the sudden, but 1) he isn’t going to do it “all of the sudden” and 2) electric cars should replace gas cars completely, eventually. 

Anyway, the difference between this and most standard mazes is that there is always one clear path. However, my maze doesn’t have any clear paths. It does have one distinct path, but it is blocked by obstacles. There are six obstacles that are each a factor of environmental issues. In order to get rid of them, and clear the path for the turtle, you have to click on them once the turtle approaches each obstacle. Once you click on one, a fact will appear at the bottom of the page relating to environmental issues. Once you make it to the end, you are done and there will be an ending page, with a smiling earth. The idea of this project is to continue to bring awareness to the climate crisis/environmental issues and the player gets to “clean up” the messes or “get rid” of the issues along the way.

Some side notes: movement is with the wasd keys, instead of the arrow keys. So, “w” is up, “a” is left, “s” is down, and “d” is right. Also, sometimes the turtle may get stuck, just play around with the movement keys if this happens. I apologize for this, but I couldn’t figure out how to fix it. Of course if I had more time, I would’ve liked to figure out this problem, Overall, it works pretty well, so enjoy!

sketch.slmazeDownload
//Sarah Luongo
//sluongo
//Section A

// This code aims to create a maze with obstacles that are causes of
// environmental problems. As you go through, click on the obstacles to
// clear the path for the turtle and learn some facts along the way.

var walls = [];
var x = 120; // x location of circle
var y = 25; // y location of circle
var obstaclesx = []; // array to hold the x location of the obstacles
var obstaclesy = []; // array to hold the y location of the obstacles
var industry;
var litter;
var light;
var tree;
var car;
var rings;
var obstaclesarealive = [];
var facts = '';
var earth;
var facing = 0;
var turtlecol; // boolean for collision as turtle rotates

function preload() {
    industry = loadImage('https://i.imgur.com/kT2IbbF.png');
    litter = loadImage('https://i.imgur.com/iQ2mdUY.png');
    light = loadImage('https://i.imgur.com/uMRxZlH.png');
    tree = loadImage('https://i.imgur.com/vn4OlLX.png');
    car = loadImage('https://i.imgur.com/i4iop8I.png');
    rings = loadImage('https://i.imgur.com/BAAbVNY.png');
    earth = loadImage('https://i.imgur.com/RfrmGyt.png');
}

function setup() {
    createCanvas(600, 600);
    frameRate(60);
    // Maze lines are are drawn somewhat like a grid, so they are separated by
    // Row and column and seperated further to make up to rows and columns

    // Maze lines (columns) starting from left to right
    maze(140, 50, 140, 90, true);    
    maze(140, 130, 140, 210, true);
    maze(140, 250, 140, 330, true);
    maze(140, 370, 140, 410, true);

    maze(180, 50, 180, 130, true);
    maze(180, 170, 180, 250, true);
    maze(180, 370, 180, 410, true);

    maze(220, 170, 220, 210, true);
    maze(220, 250, 220, 330, true);

    maze(260, 90, 260, 170, true);
    maze(260, 210, 260, 250, true);
    maze(260, 290, 260, 330, true);
    maze(260, 410, 260, 450, true); 

    maze(300, 90, 300, 130, true);
    maze(300, 250, 300, 330, true);
    maze(300, 370, 300, 410, true);

    maze(340, 90, 340, 170, true);
    maze(340, 330, 340, 370, true);

    maze(380, 50, 380, 250, true);

    maze(420, 90, 420, 130, true);
    maze(420, 170, 420, 250, true);
    maze(420, 290, 420, 410, true);

    maze(460, 90, 460, 290, true);
    maze(460, 330, 460, 370, true);

    // Maze lines (rows) starting from top to bottom
    maze(220, 90, 260, 90, false);
    maze(300, 90, 340, 90, false);
    maze(420, 90, 460, 90, false);

    maze(140, 130, 220, 130, false);
	
    maze(220, 170, 340, 170, false);
    maze(380, 170, 420, 170, false);

    maze(180, 210, 340, 210, false);

    maze(220, 250, 260, 250, false);
    maze(300, 250, 380, 250, false);
    
    maze(140, 290, 220, 290, false);
    maze(260, 290, 300, 290, false);
    maze(340, 290, 460, 290, false);

    maze(100, 330, 180, 330, false);
    maze(300, 330, 380, 330, false);
    maze(460, 330, 500, 330, false); 

    maze(140, 370, 300, 370, false);
    maze(340, 370, 380, 370, false);

    maze(180, 410, 260, 410, false);
    maze(300, 410, 460, 410, false);

    // Resize images
    industry.resize(35, 40);
    litter.resize(35, 35);
    light.resize(35, 35);
    tree.resize(30, 30);
    car.resize(35, 35);
    rings.resize(60, 60);
    earth.resize(300, 300);

    obstaclesx = [140, 260, 223, 385, 462, 440]
    obstaclesy = [210, 53, 333, 255, 150, 410]

    obstaclesarealive = [true, true, true, true, true, true]
}

function draw() {
    background(220);
    
    // Maze background
    strokeWeight(1);
    stroke(0);
    fill(255);
    square(100, 50, 400);

    for (var i = 0; i < walls.length; i++) {
        line(walls[i].x1, walls[i].y1, walls[i].x2, walls[i].y2);
    }

    // Maze start and finish
    stroke(255);
    strokeWeight(1);
    line(101, 50, 139, 50);
    line(461, 450, 499, 450);
    
    noStroke();
    turtle(x, y);

    if (obstaclesarealive[0] == true) {
        image(industry, 140, 210);
    }
    if (obstaclesarealive[1] == true) {  
        image(litter, 260, 53);
    }
    if (obstaclesarealive[2] == true) {  
        image(light, 223, 333);
    }
    if (obstaclesarealive[3] == true) {  
       image(tree, 385, 255);
    }
    if (obstaclesarealive[4] == true) {  
        image(car, 462, 150);
    }
    if (obstaclesarealive[5] == true) {  
        image(rings, 440, 410);
    }

    // If statements to move and rotate the turtle:
    // Key 'w' moves up
    if (keyIsDown(87)) {
	facing = 180;
	turtlecol = false;
	y--;
	if (collision()) {
	    y++;
	}
    // Key 'a' moves left
    } else if (keyIsDown(65)) {
	facing = 90;
	turtlecol = true;
	x--;
	if (collision()) {
	    x++;
	}
    // Key 's' moves down
    } else if (keyIsDown(83)) {
	facing = 0;
	turtlecol = false;
	y++;
	if (collision()) {
	    y--;
	}
    // Key 'd' moves right
    } else if (keyIsDown(68)) {
	facing = -90;
	turtlecol = true;
	x++;
	if (collision()) {
	    x--;
	}
    }
    
    // Text attributes and placement after each obstacle is clicked
    textSize(15);
    fill(0);                         
    text(facts, 100, 500);
}

function turtle(a, b) {
    push();
    translate(a, b);
    // Rotate based on direction it's traveling
    rotate(radians(facing));

    // Head
    fill(153, 200, 130);
    ellipse(0, 9, 7, 8);

    // Tail
    strokeWeight(3);
    stroke(153, 200, 130);
    line(0, -10, 0, -8); 

    // Legs
    strokeWeight(4);
    line(-7, -8, -6, -7);
    line(7, 8, 6, 7);
    line(-7, 8, -6, 7);
    line(7, -8, 6, -7);

    noStroke();

    // Eyes
    fill(88, 130, 96);
    circle(-2, 11, 2); 
    circle(2, 11, 2);

    // Body
    fill(204, 223, 156);
    circle(0, 0, 16);
    pop();
}

// Maze object 
function maze(xone, yone, xtwo, ytwo, pos) {
    var mz = {x1: xone, y1: yone, x2: xtwo, y2: ytwo, p: pos}
    walls.push(mz);
}

// Function that deals with all collision types
function collision() {
    var xoffset = (turtlecol)? 12 : 13;
    var yoffset = (turtlecol)? 13 : 12;

    // Collision against maze border
    if (x == 111 || x == 489 || y == 65 || y == 430) {
        if (x >= 112 & x <= 128 && y <= 65) {
	    return false;
	}
	// End of maze
	if (x >= 450 & x <= 488 && y == 430) {
            endscreen();
        }
	return true;
    }
    
    // Collision against maze walls
    for (var i = 0; i < walls.length; i++) {
        if (walls[i].p == true) {
            if ((y+yoffset) > walls[i].y1 & (y-yoffset) <= walls[i].y2) {
	        if ((x+xoffset) >= walls[i].x1 && (x-xoffset) <= walls[i].x1) {
		    return true;
		}
	    }
	} else {
            if ((x+xoffset) >= walls[i].x1 & (x-xoffset) <= walls[i].x2) {
	        if ((y+yoffset) >= walls[i].y1 && (y-yoffset) <= walls[i].y1) {
		    return true;
		}
	    }
	}
    }
    return obstacleCollision();
}

// Collision against images
function obstacleCollision() {
    var xoffset = (turtlecol)? 12 : 13;
    var yoffset = (turtlecol)? 13: 12;

    for (var i = 0; i < obstaclesx.length; i++) {
        if ((x+xoffset) >= obstaclesx[i] & (x-xoffset) <= (obstaclesx[i] + 40)) {
	    if ((y+yoffset) >= obstaclesy[i] && (y-yoffset) <= (obstaclesy[i] + 40)) {
	        return obstaclesarealive[i];
	    }
	}
    }
    return false;
}

// Facts from the industry, electricity, and transportation obstacles come from
// the following website:
// https://www.epa.gov/ghgemissions/sources-greenhouse-gas-emissions
// Litter obstacle fact:
// https://www.metrobinhire.com.au/blog/9-surprisingly-and-alarming-facts-about-littering
// Deforestation obstacle fact:
// https://www.greenmatters.com/p/why-is-deforestation-a-problem
// 6 Pack Ring obstacle fact:
// https://www.nationalgeographic.com/environment/2018/09/news-plastic-six-pack-rings-alternatives-history/#close
function mousePressed() {
    if (mouseX >= 140 & mouseX <= 175 && mouseY >= 210 && mouseY <= 250) {
        obstaclesarealive[0] = false;
	facts = 'Greenhouse gas emissions from industry primarily come \nfrom burning fossil fuels for energy, as well as greenhouse \ngas emissions from certain chemical reactions necessary to \nproduce goods from raw materials.';
    }
    if (mouseX >= 260 & mouseX <= 295 && mouseY >= 53 && mouseY <= 88) {
	obstaclesarealive[1] = false;
	facts = 'Some alarming quick facts about littering: almost all litter \nends up in the ocean. The most littered item is fast food \npackaging many animals die from littering. Cigarette butts \nmake up 1/2 the amount of littered objects.';
	    
    }
    if (mouseX >= 223 & mouseX <= 258 && mouseY >= 333 && mouseY <= 368) {
        obstaclesarealive[2] = false;
	facts = 'Electricity production generates the second largest share \n(26.9% in 2018) greenhouse gas emissions. Approximately \n63 percent of our electricity comes from burning fossil fuels, \nmostly coal and natural gas.';
    }
    if (mouseX >= 385 & mouseX <= 415 && mouseY >= 255 && mouseY <= 285) {
        obstaclesarealive[3] = false;
	facts = 'Deforestation has many major (and way too often unforeseen) \nimpacts on the environment. There’s soil erosion, water cycle \ndisruption, greenhouse gas emissions, and biodiversity \nlosses with every tree that is chopped, and the planet feels its \nimpact.';
    }
    if (mouseX >= 462 & mouseX <= 499 && mouseY >= 150 && mouseY <= 185) {
        obstaclesarealive[4] = false;
	facts = 'The transportation sector generates the largest share (28.2%\nin 2018) of greenhouse gas emissions. Greenhouse gas \nemissions from transportation primarily come from burning \nfossil fuel for our cars, trucks, ships, trains, and planes.';
    }
    if (mouseX >= 440 & mouseX <= 500 && mouseY >= 410 && mouseY <= 440) {
        obstaclesarealive[5] = false;
	facts = 'Almost 700 species are now known to have been harmed \nby ocean plastic, and every year, around 18 billion pounds \nof plastic flows into the ocean. Producing plastic rings also \nrequires using petroleum—around eight percent of global \noil production is to make plastic.';
    }
}

function endscreen() {
    facts = '';
    fill(0, 0, 102);
    push();
    translate(width/2, height/2);
    square(-300, -300, 600);
    image(earth, -150, -200);
    textSize(50);
    fill(255);
    textAlign(CENTER);
    text('THE END', 0, 200);
    pop();
    noLoop();
}

// Code used to make the building/first obstacle
/*function industry() {
     // Building
     fill(139, 69, 19);
     rect(145, 225, 8, 20);
     rect(153, 234, 20, 11);

     //CO2
      fill(70);
      circle(149, 222, 5);
      circle(153, 220, 8);
      circle(159, 214, 11);
}*/

Final Project-Protect Sam from Coronavirus!

This project was inspired by the biggest theme of the year 2020—COVID-19. It is an invisible enemy that humanities struggled to fight against. The U.S. is surely losing the war on COVID-19, but it did not have to be this way. If people are more aware of how they could be infected by the virus, and understand how to protect themselves, then the pandemic would be more under control. I wanted this program to be educational and relatable to the player.

In my program, the players need to actively engage in using three different tools to protect the character from the coronavirus for 80 seconds. By applying the mask to Sam’s face, you could protect him from viruses that are spreading through the air. By sanitizing the table with disinfectant spray, you could prevent viruses from getting attached to Sam’s hand. However, there might be a few viruses that survived or escaped from the spray, so you need to apply hand sanitizer constantly just in case Sam starts rubbing his eyes.

If I had more time, I probably will explore how to parent the virus to the hand once it is attached. I would also like to make the background and surrounding more like a public space where other characters are also involved in this interaction.

sketch
//jiaqiwa2; Jiaqi Wang; Section C
//final project fall 2020 15-104
var num=0;
var VirusA;
var VirusS;
//the mask variables
var MaskPic;
var mx=445;
var my=60;
var mdragging=false;
var offsetMX;
var offsetMY;
var fhighlight=false;
var maskON=false;

//variables for virus
var airVirus=[];
var surfVirus=[];


//the spray variable
var Spray;
var sx=460;
var sy=125;
var sdragging=false;
var offsetSX;
var offsetSY;
var shighlight=false;
var SprayON=false;
var Sapplied=false;

//variables for animation
var Writing=[];
var Drinking=[];
var Rubbing=[];
var rubbing=false;
var count=0;
var stopwatch=0;
var EndGame=false;
var z;
var win=false;

var mug;
//the hand sanitizer variables
var handSanitizer;
var hx=480;
var hy=230;
var hdragging=false;
var offsetHX;
var offsetHY;
var Hhighlight=false;
var HON=false;
var Happlied=false;


function preload(){
 VirusA=loadImage("https://i.imgur.com/teJshOW.png");
 VirusS=loadImage("https://i.imgur.com/Vs0Z6HV.png");
 Mask=loadImage("https://i.imgur.com/3KxEFPC.png");
 Spray=loadImage("https://i.imgur.com/u0X1SgO.png");


 //writing
 var filenames = [];
    filenames[0] = "https://i.imgur.com/YJbLiPT.png";
    filenames[1] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[2] = "https://i.imgur.com/rx4PTch.png";
    filenames[3] = "https://i.imgur.com/lI2EDs4.png";
    filenames[4] = "https://i.imgur.com/K4I9fup.png";
    filenames[5] = "https://i.imgur.com/EUNV9c7.png";
    filenames[6] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[7] = "https://i.imgur.com/YJbLiPT.png";
    filenames[8] = "https://i.imgur.com/HCMWQFZ.png";
	filenames[9] = "https://i.imgur.com/YJbLiPT.png";
	filenames[10] = "https://i.imgur.com/HCMWQFZ.png";
    filenames[11] = "https://i.imgur.com/YJbLiPT.png";
    filenames[12] = "https://i.imgur.com/HCMWQFZ.png";
	filenames[13] = "https://i.imgur.com/YJbLiPT.png";

	for (var i = 0; i<filenames.length; i++) {
        Writing[i] = loadImage(filenames[i]);
    }
//drinking
var filenames2 = [];
    filenames2[0] = "https://i.imgur.com/YI78DMb.png";
    filenames2[1] = "https://i.imgur.com/pFFMlNc.png";
    filenames2[2] = "https://i.imgur.com/M6VWA4T.png";
    filenames2[3] = "https://i.imgur.com/YIN1o3J.png";
    filenames2[4] = "https://i.imgur.com/Eu7gh1b.png";
    filenames2[5] = "https://i.imgur.com/UlWmeif.png";
    filenames2[6] = "https://i.imgur.com/WFkzYAg.png";
    filenames2[7] = "https://i.imgur.com/xjnNAFU.png";
    filenames2[8] = "https://i.imgur.com/ISv7MwT.png";
	filenames2[9] = "https://i.imgur.com/X6FYgwF.png";
	filenames2[10] = "https://i.imgur.com/ISv7MwT.png";
	filenames2[11] = "https://i.imgur.com/xjnNAFU.png";
	filenames2[12] = "https://i.imgur.com/WFkzYAg.png";
	filenames2[13] = "https://i.imgur.com/UlWmeif.png";
	filenames2[14] = "https://i.imgur.com/Eu7gh1b.png";
	filenames2[15] = "https://i.imgur.com/YIN1o3J.png";
	filenames2[16] = "https://i.imgur.com/M6VWA4T.png";
	filenames2[17] = "https://i.imgur.com/pFFMlNc.png";
	 
    for (var i = 0; i<filenames2.length; i++) {
        Drinking[i] = loadImage(filenames2[i]);
    }
    // mug
    mug=loadImage("https://i.imgur.com/rlJA4yY.png");
    //hand sanitizer
    handSanitizer=loadImage("https://i.imgur.com/d5h6GeR.png");
//rubbing
var filenames3 = [];
    filenames3[0] = "https://i.imgur.com/B1Kr1t2.png";
    filenames3[1] = "https://i.imgur.com/8T6UUR4.png";
    filenames3[2] = "https://i.imgur.com/untVivz.png";
    filenames3[3] = "https://i.imgur.com/DaIu3C6.png";
    filenames3[4] = "https://i.imgur.com/Wvif1mI.png";
    filenames3[5] = "https://i.imgur.com/66gOJPD.png";
    filenames3[6] = "https://i.imgur.com/XhPbm01.png";
    filenames3[7] = "https://i.imgur.com/bDfotS2.png";
    filenames3[8] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[9] = "https://i.imgur.com/N3plYyV.png";
	filenames3[10] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[11] = "https://i.imgur.com/N3plYyV.png";
	filenames3[12] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[13] = "https://i.imgur.com/N3plYyV.png";
	filenames3[14] = "https://i.imgur.com/dzKQ4d7.png";
	filenames3[15] = "https://i.imgur.com/bDfotS2.png";
	filenames3[16] = "https://i.imgur.com/XhPbm01.png";
	filenames3[17] = "https://i.imgur.com/66gOJPD.png";
	filenames3[18] = "https://i.imgur.com/Wvif1mI.png";
	filenames3[19] = "https://i.imgur.com/DaIu3C6.png";
	filenames3[20] = "https://i.imgur.com/untVivz.png";
	filenames3[21] = "https://i.imgur.com/8T6UUR4.png";
 
    for (var i = 0; i<filenames3.length; i++) {
        Rubbing[i] = loadImage(filenames3[i]);
    }
}
function setup() {
    createCanvas(560,400);
    for(var i=0;i<3;i++){
    	var brith=random(1,3);
    	airVirus[i]=makeAirVirus(-20*brith,-20*brith,(360+20*brith)/(150*random(2,4)),(120+20*brith)/(150*random(2,4)));
        surfVirus[i]=makeSurfVirus(-20,random(270,380),random(1,3),0);

    }  
    frameRate(10);   
}
function draw() {
	background(220);
	noStroke();
	if(!EndGame){
	    //drinking
	    //drinking will cause mask removal	    
        if((count>=102&count<=119)||(count>=510&&count<=527)||(count>=918&&count<=935)){
        	print("drink");
        	var j=count%17;
        	image(Drinking[j],0,0,560,400);
        	mx=445;
        	my=60;
        	maskON=false;  
        }
        //rubbing
		else if((count>=189&count<=201)||(count>=567&&count<=588)||(count>=987&&count<=1008)){
			 z=count%21;
			 if(z<10) rubbing=true;
			//print("rub",z);
			image(Rubbing[z],0,0,560,400);
			image(mug,88,263,70,65);

		}
		//writing
        else{
        	rubbing=false;
        	var i=count%13;
        	image(Writing[i],0,0,560,400);
        	image(mug,88,263,70,65);

        }
    }

    // the user interface & text
    fill(235,100);
	rect(440,40,100,300);
	strokeWeight(2);
	fill(255,190);
	textSize(12);
	text("PROTECT SAM FROM CORONAVIRUS WITH TOOLS", 10,20);
	push();
	textSize(30);
	var time=floor(80-(map(count,0,1200,0,80,true)));
	text(time,80,50);
	pop();
	text("FOR", 50,40);
	text("SECONDS",120,40);
	text("TOOLS",470,30);
	text("MASK",470,110);
	text("DISINFECTANT",445,200);
	text("SPRAY",470, 215);
	text("HAND",470, 295);
	text("SANITIZER",460, 310);
	
	//display the mask
	image(Mask,mx,my,80,40);
    //display the spray
	image(Spray,sx,sy,50,60);
	//display the hand sanitizer
	image(handSanitizer, hx,hy,17,50);

	//update and show the virus   	
	removeVirusThatHaveSlippedOutOfView();
	addNewVirusWithSomeRandomProbability();

	for(var i=0;i<airVirus.length;i++){
		airVirus[i].range();
	    airVirus[i].move();
	    airVirus[i].show();
	}

	for(var j=0; j<surfVirus.length;j++){
		if(count>=102){
			//print(j);
			surfVirus[j].range();
			surfVirus[j].range2();
			surfVirus[j].move();
			surfVirus[j].show();
			

		}
	}
//show the tools behaviors
	mask();
	spray();
	HSanitizer();


	count++;
	endGame();
	
}

function removeVirusThatHaveSlippedOutOfView(){
    var AVirusToKeep = [];
    var SVirusToKeep = [];
    for (var i = 0; i < airVirus.length; i++){
        if (airVirus[i].x>-60 & airVirus[i].x-60 && airVirus[i].y0 && surfVirus[i].y=250)&&(my<=400)){
			Project_highlight();

		}
		
	}

}

function HSanitizer(){
	//move the hand sanitizer if it is selected
	if(hdragging){
		hx=mouseX+offsetHX;
		hy=mouseY+offsetHY;
	}
	if(Happlied){
		hx=480;
		hy=230;
		protection();
		stopwatch+=1;
		if(stopwatch==10){
			Happlied=false;
			stopwatch=0;
		}
		

	}
    // highlight the effective area of hand sanitizer
    if(Hhighlight){
		highlight(250,260,80,50);
    }

}

function protection(){
	//visual effect for protection
	for(var i=0;i<5; i++){
	push();
	translate(250+random(i*20),280+random(i*20));
	rectMode(CENTER);
	fill(114,204,82,100);
	rect(0,0,20,9);
	rect(0,0,9,20);
	pop();

	}
	
}

//Virus that moves on the surface
function makeSurfVirus(sx,sy,sdx,sdy){
	var sv={x: sx, y: sy, dx: sdx, dy:sdy, attach:false, VirusTransp: false,
			show: SVirusDraw, move:SVirusMove, range: CheckInProjection, range2:SCheckInBound};
		return sv;
}

function SVirusDraw(){
	image(VirusS,this.x,this.y,30,30);
	if(this.attach &!Sapplied){
		textSize(20);
		fill(255,10,10);
		text("!",this.x,this.y);
		
	}
}
function SVirusMove(){
	this.y+=this.dy;
	this.x+=this.dx;
	if(win){
		this.dy=30;
		this.dx=-30;
	}
}

function CheckInProjection(){
	//check if surface Virus get to the spray area
	if(InATriangle(this.x,this.y)){
		//check if spray is applied
		if(Sapplied){
			//reject virus if spray is applied
			print("reject Surface Virus");
			this.dy=5;
		}
		
	}

}
function SCheckInBound(){
	//check if surface virus is being transported
	if(this.VirusTransp){
		this.dx=0;
		this.dy=-20;
		//check if hand reaches the face
		if(z==9){
			EndGame=true;
		}
	}
	//check if surface Virus get to the hand area
	if((this.x>=250)&(this.x<=250+90)&&(this.y>=270)&&(this.y<=270+30)){
		//check if Hand sanitizer is applied
		if(Happlied){
			//reject virus if hand sanitizer is applied
			print("reject Surface Virus");
			this.dx=0;
			this.dy=5;
		}
		else if(! rubbing){
			//if not applied, attach virus to hand, virus stops moving if not rubbing
			print("Attached");
			this.dx=0;
			this.attach=true;
		}
		else if(rubbing& Happlied==false){
			this.VirusTransp=true;
			
		}
	}
}


//Virus that spreads through air
function makeAirVirus(ax,ay,adx,ady){
	var av={x: ax, y: ay, dx: adx, dy: ady, reject: false, 
		range: CheckInBound, show: AVirusDraw, move:AVirusMove};
	return av;
}

function AVirusDraw(){
	image(VirusA,this.x,this.y,30,30);
}

function AVirusMove(){
	if(this.reject){
		//virus go off canvas if you win
		if(win){
			this.dy=50;
			this.dx=50;
		}		
		this.x-=this.dx;
		this.y-=this.dy;		
	}
	else{
		//virus go off canvas if you win
        if(win){
			this.dy=-50;
			this.dx=-50;
		}
		this.x+=this.dx;
		this.y+=this.dy;	
	}
	    
}

function CheckInBound(){
	//check if air Virus get to the face area
	if((this.x>=240)&(this.x<=320)&&(this.y>=70)&&(this.y<=160)){
		//check if mask is on
		if(maskON){
			//reject virus if mask is on
			this.reject=true;
			print("reject Air Virus");
		}
		else{
			//end game if failed to protect face with mask
			EndGame=true;
			

		}
	}
}

function mousePressed(){
	//select mask
	if((mouseX>=445)&(mouseX<=445+80)&&(mouseY>=60)&&(mouseY<=60+40)){
		mdragging=true;
		fhighlight=true;
		offsetMX=mx-mouseX;
		offsetMY=my-mouseY;
	}
	//select spray
	else if((mouseX>=sx)&(mouseX<=sx+50)&&(mouseY>=sy)&&(mouseY<=sy+60)){
		sdragging=true;
		shighlight=true;
		offsetSX=sx-mouseX;
		offsetSY=sy-mouseY;
		
	}
	//select hand sanitizer
	else if((mouseX>=hx)&(mouseX<=hx+17)&&(mouseY>=hy)&&(mouseY<=hy+50)){
		hdragging=true;
		Hhighlight=true;
		offsetHX=hx-mouseX;
		offsetHY=hy-mouseY;
	}


}

function mouseReleased(){
    //when the mouse is released, mask dragging stops
    if((mx>=250)&(mx<=370)&&(my>=90)&&(my<=145)){
    	mdragging = false;
    	mx=260;
    	my=125;
    	maskON=true;
    	fhighlight=false;
    }
    //when the mouse is released, spray dragging stops
    if((sx>=10)&(sx<=320)&&(sy>=250)&&(my<=400)){
    	sdragging = false;
		Sapplied=true;
		sdragging = false;
    	SprayON=true;
    	shighlight=false;

    }
       //when the mouse is released, hand sanitizer dragging stops
    if((hx>=250)&(hx<=250+90)&&(hy>=270)&&(hy<=270+80)){
    	hdragging = false;
		Happlied=true;
		hdragging = false;
    	HON=true;
    	Hhighlight=false;

    }


    
}

function endGame(){
	//lose game
	if(EndGame){
		fill(120,54,55,100);
		rect(0,0,width,height);
		fill(0);
		textSize(20);
		noStroke();
		text("YOU FAILED TO PROTECT SAM:(", width/4,height/2);	
		airVirus.dx=0;
		airVirus.dy=0;
		surfVirus.dx=0;
		
		noLoop();
	}
	//win game
	if(!EndGame& count>=1200){
		win=true;
		fill(120,191,58,100);
		noStroke();
		rect(0,0,width,height);
		push();
		fill(255);
		textSize(20);
		text("YOU PROTECTED SAM :)", width/3,height/2);
		pop();
		airVirus.dx=-100;
		airVirus.dy=-100;
		surfVirus.dx=-100;
		stopwatch+=1;
		if(stopwatch==10){
			fhightlight=false;
			Hhighlight=false;
			shighlight=false;
			noLoop();
			stopwatch=0;
		}
		
	}
	
}
//highlight area for application
function highlight(x,y,w,h){
	noFill();
	stroke(98,232,228,150);
	strokeWeight(3);
	rect(x,y,w,h);

}

function Project_highlight(){
	noFill();
	stroke(98,232,228,150);
	strokeWeight(5);
	triangle(sx,sy+5,sx-90,sy-50, sx-90, sy+60);

}



function InATriangle(px,py){
var x1 = sx;      // three points of the triangle
var y1 = sy+5;
var x2 = sx-90;
var y2 = sy-50;
var x3 = sx-90;
var y3 = sy+60;

  // get the area of the triangle
  var areaOrig = abs( (x2-x1)*(y3-y1) - (x3-x1)*(y2-y1) );

  // get the area of 3 triangles made between the point
  // and the corners of the triangle
  var area1 =    abs( (x1-px)*(y2-py) - (x2-px)*(y1-py) );
  var area2 =    abs( (x2-px)*(y3-py) - (x3-px)*(y2-py) );
  var area3 =    abs( (x3-px)*(y1-py) - (x1-px)*(y3-py) );

  // if the sum of the three areas equals the original,
  // we're inside the triangle!
  if (area1 + area2 + area3 == areaOrig) {
    return true;
  }
  else{
  	return false;
  }

}

Final Project – Simple Virus Simulator

For my final project, I wanted to create a simple virus simulation where one infected particle infects a population of healthy particles. The particles move across the canvas at random speeds and directions and bounce off the edges of the canvas. I wanted to show how quickly disease can spread within a population if you don’t take preventative measures such as wearing a mask and social distancing.

  1. Your mouse is a social distancing particle that repels all other particles that comes within its’ social distancing radius.
  2. Healthy particles that come within range of a sick particles’ “infection radius” will be infected.
  3. If you press any key on the keyboard, more healthy particles will be added to the screen (but will quickly be infected by the population of sick particles).
  4. If you click the “RETURN” key, the sick particles will all reset to healthy and the process of infection begins again. 
  5. In the upper left corner, there is a counter for the number of sick particles.
Covid Simulation
//Maggie Ma
//Section D
//Final Project Virus Simulator

var dots = [];
var infectionRadius = 20; //light red infection radius 
var rpc = 19000; //repelling constant


function setup() {

    createCanvas(600, 600);
 	for (i = 0; i < 100; i++) { //create 100 healthy dots
		var p = new dot();
		dots.push(p);
	}
	frameRate(20);
}

function draw() {
	background(255);

	for (var i = 0; i< dots.length; i++) { //draw uninfected dots
		dots[i].update();
		dots[i].show();
	}
	if (frameCount ==100){
		dots[9].infected = true; //after 100 frameCount, one dot becomes sick
	}
	//dots infect eachother if come in contact in the "infectionRadius"
	for (var m = 0; m<dots.length; m++) {
		for (var i = 0; i < dots.length; i++) {
			if (dist(dots[m].x, dots[m].y,
		dots[i].x, dots[i].y) <= infectionRadius) {
				if (dots[m].infected == true) {
						dots[i].infected = true;
			}
		}
		}
	}
	//Social Distance dot that repels all infected dots
	ellipseMode(CENTER);
	noStroke();
	fill(0,0,0,100);
	ellipse(mouseX,mouseY,100,100);
	fill(0);
	ellipse(mouseX,mouseY,25,25);

	var sickcounter = 0;
	//var healthycounter = 100;

	for (var i = 0; i < dots.length; i ++) {
		if(dots[i].infected ==true) {
			sickcounter++;
			//healthycounter--;
		}
	}
	noStroke();
	fill(200);
	textSize(12);
	text("You are the social distancing particle.", 10, 25);
	text("Press any key to add healthy particles.", 10, 50);
	fill(200);
	text("Press 'Return' key to reset.", 10, 75);
	text("Sick Particles:", 10,100);
	text(sickcounter, 130,100);

	
}

//add new uninfected dots by pressing key
function keyPressed() {
	dots.push(new dot(mouseX, mouseY));
	//healthycounter++;

	//if click "Return key" simulation resets.
	if (keyCode === RETURN) {
		for (var m = 0; m<dots.length; m++) {
			for (var i = 0; i < dots.length; i++) {
				if(dots[i].infected == true) {
					dots[i].infected = false;
					dots[9].infected = true;
					sickcounter = 0;
			}
		}
		}
	}
}

class dot { 

	constructor() { 
		this.x =random(3.5, width-3.5);
		this.y =random(3.5,height-3.5);
		this.dx =random(-10,7);
		this.dy =random(-10,7);
		this.infected = false
		this.history = [];
	}

	update() { 
		//move black dots
		this.x+= this.dx; 
		this.y+=this.dy;

		//bounce off the edges of the canvas
		if (this.x > width) { //bounce off right wall
			this.x = width - (this.x - width);
			this.dx = -this.dx
		} else if (this.x < 0) { //bounce off left wall
			this.x = -this.x;
			this.dx = -this.dx
		}
		if (this.y > height) { // bounce off bottom
       		this.y = height - (this.y - height);
        	this.dy = -this.dy; 
    	} else if (this.y < 0) { // bounce off top
        	this.y = -this.y;
        	this.dy = -this.dy;
		}

		//create the particle trail
		var v = createVector(this.x, this.y);
		this.history.push(v);
		if (this.history.length>15) { //trail is 15 ellipses long
			this.history.splice(0,1); //splice out the trail circle at index 0
		}

		//effect of the social distancing repeller
		var dp = dist(this.x, this.y, mouseX, mouseY);
    	var f = rpc /(Math.pow(dp, 2)); //Math.pow is exponent w/ base dp
    	var dirx = (this.x - mouseX)/dp;
   		var diry = (this.y - mouseY)/dp;
    	this.x += f*dirx;
    	this.y += f*diry;
	}	

	show() { 
		//if dot is infected, color red
		if (this.infected ==true) {
			noStroke();

			//creating dot "tail"
			for (var i = 0; i < this.history.length; i++) {
				var pos = this.history[i];
				fill('red');
				ellipse(pos.x,pos.y, i*.15, i*.15) 
			}
			//drawing red dot
			fill(255,0,0,100);
			ellipse(this.x, this.y, 30,30);
			fill('red');
			ellipse(this.x,this.y,10,10);

		//else if dot is uninfected, color black dot
		} else {
			noStroke();
			//creating dot "tail"
			for (var i = 0; i < this.history.length; i++) {
				var pos = this.history[i];
				fill(0);
				ellipse(pos.x,pos.y, i*.15, i*.15) 
			}
			fill(0);
			ellipse(this.x,this.y, 10,10); 
		}
	}
}

Project 15 – COVID Shooter Game

For this project, I was inspired by scrolling shooter games. These games were popular in arcades and on older gaming consoles. I used to play games like these a lot as a kid, so I was really looking forward to creating this. As COVID-19 is something that affected us all this year, I used this theme for my project. You move the ship around in this game by using the WASD keys and you shoot by using the spacebar. The goal is to shoot the coronavirus molecules that are coming at the ship. If you shoot enough, you’ll win the game and prevent the world from getting infected. If the ship gets hit too many times, you’ll lose the game. If too many molecules pass the screen, you’ll lose the game and the world will be infected. There is a bit of a randomness factor to this game as the bullets will shoot from either the left or right gun on the ship. If I had more time, I would have wanted to add animations to this game. For example, I was considering having the viruses explode when hit. 

sketch
//Dreami Chambers; Section C; dreamic@andrew.cmu.edu; Assignment-14-Project

var stars = []
var bullets = []
var viruses = []
var hearts = []
var hearts2 = []
var x = 170 //ship x position
var y = 320 //ship y position
var dx = 0 //ship x velocity
var dy = 0 //ship y velocity
var health = 3
var worldHealth = 3
var virusesHit = 0
var gameStart = false //checks if game was started

function preload() {
	ship=loadImage("https://i.imgur.com/te1SxyO.png")
	bullet=loadImage("https://i.imgur.com/YHVJAW8.png")
	virus=loadImage("https://i.imgur.com/RrjmBFe.png")
	hearts[0]=loadImage("https://i.imgur.com/eEYu6KF.png")
	hearts[1]=loadImage("https://i.imgur.com/xe4b6B7.png")
	hearts[2]=loadImage("https://i.imgur.com/Jupb3vO.png")
	hearts[3]=loadImage("https://i.imgur.com/ByIC9eQ.png")
	hearts2[0]=loadImage("https://i.imgur.com/GdyaHu7.png")
	hearts2[1]=loadImage("https://i.imgur.com/chdj98I.png")
	hearts2[2]=loadImage("https://i.imgur.com/onnPuBv.png")
	hearts2[3]=loadImage("https://i.imgur.com/6ZwZ3ej.png")
} 

function setup() {
	noLoop() //game does not start at first
    createCanvas(400, 400);
    //stars setup
    for (var i = 0; i < 100; i++) {
    	var rx = random(width)
    	var ry = random(height)
    	var rdy = random(4)
        stars[i] = makeStars(rx, ry, 2, rdy)
    }
    //virus setup
    for (var j = 0; j < 1; j++) {
    	var rx = random(50, 350)
    	var ry = random(-50, 0)
        viruses[j] = makeVirus(rx, ry)
    }
}

function draw() {
	background(0)
	//draws, removes, and adds stars
	starUpdate()
	starsRemove()
	starsAdd()
	//draws, removes, and adds viruses
	virusUpdate()
	virusRemove()
	virusAdd()
	//draws and removes bullets
	bulletUpdate()
	bulletRemove()
	image(ship, x, y, 60, 70) //spaceship
	image(hearts[health], 10, 10, 60, 20) //healthbar
	image(hearts2[worldHealth], 330, 10, 60, 20) //world healthbar

	if (gameStart == false){ //if game has not been started, a start message will show
		start()
	}
	if (collides() == true){ //if bullet hits virus, remove virus
		virusesHit += 1
		viruses.splice(0, 1)
	}
	if (collides2() == true){ //if virus hits the spaceship, remove a heart from the healthbar
		health -= 1
		viruses.splice(0, 1)
	}
	if (viruses[0].y > height){
		worldHealth -= 1
		print(worldHealth)
	}
	if (keyIsDown(87) & y > 0){ //move up
		y-=2
	}
	if (keyIsDown(83) && y < 380){ //move down
		y+=2
	}
	if (keyIsDown(68) && x < 380){ //move right
		x+=2
	}
	if (keyIsDown(65) && x > -40){ //move left
		x-=2
	}
	endings() //different ending screens depending on whether or not the game is won
}

function start(){ //start message
	strokeWeight(3)
	stroke(240, 175, 0)
	textSize(40)
	translate(200, 190)
	textAlign(CENTER, CENTER)
	text("Click to Start", 0, 0)
}

function mousePressed(){ //starts game when mouse clicked
	loop()
	gameStart = true
}

//if spacebar pressed, shoot bullet
function keyPressed(){
	if (key === ' '){
		x2 = random([x+5, x+45]) //bullet shoots from either left or right gun
		var bullet = makeBullets(x2, y, 2)
		bullets.push(bullet)
	}
}

//star functions
function starUpdate(){
	for (var i = 0; i < stars.length; i++){
        stars[i].stepFunction()
        stars[i].drawFunction()
	}
}

//removes stars when off screen
function starsRemove(){
	starsToKeep = []
	for (var i = 0; i < stars.length; i++){
        if (stars[i].y + stars[i].size > 0){
        	starsToKeep.push(stars[i])
        }
	}
	stars = starsToKeep
}

//adds new stars
function starsAdd(){
	var starProb = 0.5
	if (random(1) < starProb){
		stars.push(makeStars(random(width), random(-5, 0), 2, random(4)))
	}
}

//moves stars down
function starStep() {
    this.y += this.dy
}

function starDraw() {
	stroke(this.c)
	strokeWeight(this.size)
	point(this.x, this.y)
}

function makeStars(px, py, pdy, ps) {
	var s = {x: px, y: py, dy: pdy, 
		size: ps, c: color(random(200, 255),random(150, 230),random(100, 145)),
		drawFunction: starDraw, stepFunction: starStep
	}
	return s
}

//bullet functions
function bulletUpdate(){
	for (var i = 0; i < bullets.length; i++){
	    bullets[i].stepFunction()
	    bullets[i].drawFunction()
	}
}

//moves bullet up
function bulletStep() {
    this.y -= this.dy
}

function bulletDraw() {
	image(bullet, this.x, this.y, 10, 20)
}

//removes bullet when off screen
function bulletRemove(){
	bulletsToKeep = []
	for (var i = 0; i < bullets.length; i++) {
        if (bullets[i].y > 0){
        	bulletsToKeep.push(bullets[i])
        }
	}
	bullets = bulletsToKeep
}

function makeBullets(px, py, pdy) {
	var b = {x: px, y: py, dy: pdy, 
		drawFunction: bulletDraw, stepFunction: bulletStep
	}
	return b
}

//virus functions
function virusUpdate(){
	for (var i = 0; i < 1; i++){
        viruses[i].stepFunction()
        viruses[i].drawFunction()
	}
}

//adds virus when there are none on the screen
function virusAdd(){
	var virusProb = 0.7
	if (random(1) < virusProb){
		viruses.push(makeVirus(random(50, 350), random(-100, -20)))
	}
}

//removes virus when off screen
function virusRemove(){
	virusToKeep = []
	for (var i = 0; i < viruses.length; i++) {
        if (viruses[i].y < height+2){
        	virusToKeep.push(viruses[i])
        }
	}
	viruses = virusToKeep
}

//moves virus down
function virusStep() {
    this.y += this.dy
}

function virusDraw() {
	image(virus, this.x, this.y, this.size, this.size)
}

function makeVirus(px, py) {
	var v = {x: px, y: py, dy: 2, 
		size: random(40,50),
		drawFunction: virusDraw, stepFunction: virusStep
	}
	return v
}

//checks to see if any bullet hits the virus
function collides() {
	for (var i = 0; i < bullets.length; i++){
		var d = dist(bullets[i].x, bullets[i].y, viruses[0].x, viruses[0].y)
		if (d < viruses[0].size-10){
			return true
		}
	}	
}

//checks to see if any virus hits the spaceship
function collides2() {
	var d = dist(x, y, viruses[0].x, viruses[0].y)
		if (d < viruses[0].size){
			return true
		}
	}

function endings(){
	if (health == 0 ){ //bad ending
		image(hearts[0], 10, 10, 60, 20) //makes sure that the heart bar shows zero hearts
		strokeWeight(3)
		stroke(240, 175, 0)
		textSize(40)
		translate(200, 190)
		textAlign(CENTER, CENTER)
		text("GAME OVER", 0, 0)
		stroke(0)
		fill(240, 175, 0)
		textSize(12)
		translate(0, 40)
		text("You were unable to prevent the spread of the virus.\nBetter luck next time!", 0, 0)
		noLoop()
	}
	if (worldHealth == 0){ //second bad ending
		strokeWeight(3)
		stroke(240, 175, 0)
		textSize(40)
		translate(200, 190)
		textAlign(CENTER, CENTER)
		text("GAME OVER", 0, 0)
		stroke(0)
		fill(240, 175, 0)
		textSize(12)
		translate(0, 40)
		text("You let too many viruses pass and the world has been infected.\nBetter luck next time!", 0, 0)
		noLoop()
	}
	if (virusesHit == 10){ //good ending
		strokeWeight(3)
		stroke(240, 175, 0)
		textSize(40)
		translate(200, 190)
		textAlign(CENTER, CENTER)
		text("YOU WIN", 0, 0)
		stroke(0)
		fill(240, 175, 0)
		textSize(12)
		translate(0, 40)
		text("You have successfully destroyed all the viruses.\nRefresh to play again!", 0, 0)
		noLoop()
	}
}

Project 15: Final Project

finalYeung2020Download
//stores all the changes
var changes={
    activism: false, //political poster on the wall, b
    cramps: false, //typing sound, c
    battery: false, //low battery, d
    voted: false, //i voted sticker on wall, e
    text: false, //text notif from friend to hangout, f
    delivery: false, //notif that grubhub is here, g
    canvasNotifs: false, //notif that new assignment was posted, h
    mask: false, //mask on wall, i
    handshake: false, //handshake homepage, j
    rust: false, //keys turn brown, k
    night: false, //outside window is night now, l
    maskBox: false, //box of masks appear on desk, m
    dino: false, //dino game, n
    zeroPercent: false, //canvas grade page with a 0, o
    parents: false, //knocking sound, p
    askText: false, //text notif to ask if you're okay, q
    grenell: false, //grenell petition, r
    netflix: false, //netflix home page, s
    tikTok: false, //tik tok home page, t
    unmuted: false, //eating sound, u
    chegg: false, //chegg home page, w
    pills: false, //pill bottle on desk, x
    muted: false, //zoom page, muted y
    zoomFatigue: false, //yawn sound, z
}

//triggers for sound
var fr1=0;
var fr2=0;
var fr3=0;
var fr4=0;

//triggers congrats
var fr5=0

//arrays to store letters and corresponding messages
var alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
var letterMessage = [
    "An optimistic start: you're kind of excited that spring break got extended by a week!\nyou'll be back on campus in no time", //no change
    "Black Lives Matter: you do whatever you can to help the cause",
    "Cramps: you've typed so much in the past few months that your fingers start cramping", //typing sound
    "Dying: crap, your battery is low",
    "Election: you sent in your mail-in ballot",
    "Friends: your friend asks you to hangout but you feel too guilty to do anything",
    "Grubhub: I don't feel like making food so I'll just waste $20 on a $10 meal",
    "Homework: homework assignments just seem to pile up, but you're so unmotivated",
    "I forgot a mask: you walked to the store but forgot your mask, so you had to come back",
    "Job Applications: you know you have to applying for internships,\nbut you just don't have the effort to",
    "Keys: you haven't gone outside in so long, your keys are rusting",
    "Long Hours: time seems nonexistent when you work from home",
    "Masks: your mom buys you a giant box of masks", 
    "No Internet: oh no! Your internet went out, time to play the dino game :(",
    "Oops, I forgot: without your friends to remind you,\nyou accidentally forget to do your homework",
    "Parents: even though you're in lecture,\nyour parents don't understand and still try to talk to you", //knocking sound
    "Questions: it seems like every two seconds someone's asking if you're okay",
    "Richard Grenell: you sign the petition to fire him,\neven though you're not sure if anything will happen",
    "Streaming: you feel like you've watched everything on Netflix in the past few months",
    "Tik Tok: you spend your time endlessly scrolling",
    "Unmuted: you forgot to mute yourself so your entire class heard you eat your lunch!", //eating sound
    "Vaccine: you're just hoping there's a vaccine in time for summer", //no change
    "Work: has homework always been this hard?",
    "Xanax: you start having panic attacks and your doctor prescribes you Xanax",
    "You're Muted: you try to answer a question in class but forget you're muted,\nso you just look stupid",
    "Zoom Fatigue: after hours on Zoom for lectures, you feel exhausted", //yawn sound
]

//images that need to be loaded
var blm;
var boxOfMasks;
var canvasNotification;
var cheggHomePage;
var dinoGame;
var grenellPetition;
var grubhubText;
var handshakeHomePage;
var hangOutText;
var iVotedSticker;
var lowBatteryNotif;
var netflixHomePage;
var questionText;
var tikTokHomePage;
var zeroPercentGrade;

//sounds that need to be loaded
var eating;
var knockKnock;
var tired;
var type;

function preload(){
    //loads images
    blm=loadImage("https://i.imgur.com/JFLSHwn.jpg");
    boxOfMasks=loadImage("https://i.imgur.com/XEQ2DIE.png");
    canvasNotification=loadImage("https://i.imgur.com/iI0fpJP.png");
    cheggHomePage=loadImage("https://i.imgur.com/hdPz4NX.png");
    dinoGame=loadImage("https://i.imgur.com/tvKCVyP.png");
    grenellPetition=loadImage("https://i.imgur.com/i7QTQyK.png");
    grubhubText=loadImage("https://i.imgur.com/YROzHtr.png");
    handshakeHomePage=loadImage("https://i.imgur.com/K36qX37.png");
    hangOutText=loadImage("https://i.imgur.com/Nqt81BJ.png");
    iVotedSticker=loadImage("https://i.imgur.com/SfQn4pk.png");
    lowBatteryNotif=loadImage("https://i.imgur.com/cC8hsTT.png");
    netflixHomePage=loadImage("https://i.imgur.com/N9BohE8.jpg");
    questionText=loadImage("https://i.imgur.com/rQHSMwT.png");
    tikTokHomePage=loadImage("https://i.imgur.com/DlDOeHF.png");
    zeroPercentGrade=loadImage("https://i.imgur.com/exTf7NY.png");
    zoomMeeting=loadImage("https://i.imgur.com/RcF2XKO.jpg");
    xanaxBottle=loadImage("https://i.imgur.com/EcRn3JI.png");
    maskMessage=loadImage("https://i.imgur.com/qR7W3rv.png");

    //loads sounds
    eating=loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/crunch.wav");
    knockKnock=loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/knock.wav");
    tired=loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/yawn.wav");
    type=loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/12/typing.wav");
}
//setup functions
function setup() {
    createCanvas(600, 550);
    useSound();
    frameRate(1);
}

function soundSetup(){
    eating.setVolume(0.5);
    knockKnock.setVolume(0.5);
    tired.setVolume(0.5);
    type.setVolume(0.5);
}

function draw() {
    covid(); //changes the booleans
    drawRoom(); //draws the room

    typeAlphabet(); //types the alphabet and messages
    typeMessages();

    ifStatements(); //adds all the if statements to make the images and sounds appear/play
}

function covid(){ //when a key is pressed, boolean changes
    if (key == 'b') {
        changes.activism =true;
    }
    if (key == 'c') {
        changes.cramps =true;
    }
    if (key == 'd') {
        changes.battery =true;
    }
    if (key == 'e') {
        changes.voted =true;
    }
    if (key == 'f') {
        changes.text =true;
    }
    if (key == 'g') {
        changes.delivery =true;
    }
    if (key == 'h') {
        changes.canvasNotifs =true;
    }
    if (key == 'i') {
        changes.mask =true;
    }
    if (key == 'j') {
        changes.handshake =true;
    }
    if (key == 'k') {
        changes.rust =true;
    }
    if (key == 'l') {
        changes.night =true;
    }
    if (key == 'm') {
        changes.maskBox =true;
    }
    if (key == 'n') {
        changes.dino =true;
    }
    if (key == 'o') {
        changes.zeroPercent =true;
    }
    if (key == 'p') {
        changes.parents =true;
    }
    if (key == 'q') {
        changes.askText =true;
    }
    if (key == 'r') {
        changes.grenell =true;
    }
    if (key == 's') {
        changes.netflix =true;
    }
    if (key == 't') {
        changes.tikTok =true;
    }
    if (key == 'u') {
        changes.unmuted =true;
    }
    if (key == 'w') {
        changes.chegg =true;
    }
    if (key == 'x') {
        changes.pills =true;
    }
    if (key == 'y') {
        changes.muted =true;
    }
    if (key == 'z') {
        changes.zoomFatigue =true;
    }
}

function drawRoom(){
    background(230, 234, 245);
    noStroke();
    fill(74, 40, 2);
    rect(0, 350, 600, 130);
    drawWindow();
    fill(77, 77, 77);
    rect(0, 200, 400, 280);
    fill(0);
    rect(0, 215, 385, 270);
    fill(220);
    rect(0, 425, 600, 175);
    drawKey();
    push();
    translate(150, 40);
    scale(0.15);
    drawClock();
    pop();

    //draws sign with instructions
    fill(255, 255, 204);
    rect(15, 15, 80, 70);

    fill(0, 0, 51);
    textAlign(CENTER);
    textSize(12);
    text("Press keys\nin ABC order\nto finish", 55, 35);

}

function drawWindow(){
    //changes background to show time elapsed
    if (changes.night==true){
        fill(0, 20, 37);
        rect(300, 40, 300, 250);
    }
    if (changes.night==false){
        fill(81, 174, 255);
        rect(300, 40, 300, 250);
    }

    //grass
    fill(0, 102, 0);
    rect(300, 220, 300, 70);

    //mountains
    stroke(135, 126, 138);
    strokeWeight(1);
    for (var x=300; x<width; x++){
        var l=x*0.01;
        var y=map(noise(l), 0, 1, 170, 220);
        line(x, y, x, 220);
    }

    //window pane
    noFill();
    stroke(255);
    strokeWeight(15);
    rect(300, 40, 350, 250);
    strokeWeight(10);
    line(300, 165, 600, 165);
    line(550, 40, 550, 290);
    noStroke();  
}

function drawKey(){
    //changes color of key
    if (changes.rust==false){
        fill(180); //grey
    }
    if (changes.rust==true){
        fill(204, 102, 0) //orange
    }

    //draws key
    push();
    scale(0.5);
    translate(1000, 800);
    rotate(radians(10));
    ellipse(0, 0, 20, 40);
    rect(0, -5, 60, 10);
    //draws key's spokes(?)
    var keyLengths=[15, 20, 13];
    for (var i=0; i<4; i++){
        rect(25+(i*10), 0, 6, keyLengths[i]);
    }
    pop();

}

function ifStatements(){ //inputs images and sounds for the key presses
    //images triggered
    if (changes.activism==true){
        image(blm, 45, 100, 70, 91);
    }
    if (changes.battery==true){
        image(lowBatteryNotif, 185, 215, 200, 52);
    }
    if (changes.voted==true){
        image(iVotedSticker, 225, 150, 50, 50);
    }
    if (changes.text==true){
        image(hangOutText, 185, 215, 200, 52);
    }
    if (changes.delivery==true){
        image(grubhubText, 185, 215, 200, 52);
    }
    if (changes.canvasNotifs==true){
        image(canvasNotification, 185, 215, 200, 52);
    }
    if (changes.mask==true){
        image(maskMessage, 185, 215, 200, 52);
    }
    if (changes.handshake==true){
        image(handshakeHomePage, 0, 215, 385, 211);
    }
    if (changes.maskBox==true){
        image(boxOfMasks, 500, 300, 150, 113);
    }
    if (changes.dino==true){
        image(dinoGame, 0, 215, 385, 211);
    }
    if (changes.zeroPercent==true){
        image(zeroPercentGrade, 0, 215, 385, 211);
    }
    if (changes.askText==true){
        image(questionText, 185, 215, 200, 52);
    }
    if (changes.grenell==true){
        image(grenellPetition, 0, 215, 385, 211);
    }
    if (changes.netflix==true){
        image(netflixHomePage, 0, 215, 385, 211);
    }
    if (changes.tikTok==true){
        image(tikTokHomePage, 0, 215, 385, 211);
    }
    if (changes.pills==true){
        image(xanaxBottle, 410, 340, 25, 44);
    }
    if (changes.muted==true){
        image(zoomMeeting, 0, 215, 385, 211);
    }
    if (changes.chegg==true){
        image(cheggHomePage, 0, 215, 385, 211);
    }

    //sounds triggered
    if (changes.cramps==true){
        fr1++;
        if (fr1==1){
            type.play();
        }
        fr1++;
        
    }
    if (changes.parents==true){
        fr2++;
        if (fr2==1){
            knockKnock.play();
        }
        fr2++;
    }
    if (changes.unmuted==true){
        fr3++;
        if (fr3==1){
            eating.play();
        }
        fr3++;
    }
    if (changes.zoomFatigue==true){
        fr4++;
        if (fr4==1){
            tired.play();
        }
        fr4++;

    }

    //triggers the congrats message
    if (changes.activism & changes.cramps && changes.voted && changes.text && changes.delivery && changes.canvasNotifs && changes.mask && changes.handshake && changes.rust && changes.night && changes.maskBox && changes.dino && changes.zeroPercent && changes.parents && changes.askText && changes.grenell && changes.netflix && changes.tikTok && changes.unmuted && changes.chegg && changes.pills && changes.muted && changes.zoomFatigue){
        fr5++;
        if (fr5>5){
            textAlign(CENTER);
            textSize(25);
            text("Congrats, you finished 2020!", width/2, height-50);
        }
    }
    
}

//types the alphabet on screen
function typeAlphabet() {
    for (var i = 0; i < 26; i ++) {
        textAlign(CENTER);
        textSize(20);
        noStroke();
        var yLocation = 540;
        var x = map(i, 0, alphabet.length, 50, width - 30);
        if (keyCode === 65 + i) { //when key is down, letter turns grey
            fill(100);
            text(alphabet[i], x, yLocation);
        } else {
            fill(0, 0, 51);
            text(alphabet[i], x, yLocation);
        } 
    }
}

function keyReleased() { //replaces already clicked letters and their info with spaces in the respective arrays
    for (var i = 0; i < 26; i ++) {
        if (keyCode == 65 + i) {
            alphabet.splice(i, 1, " ");
            letterMessage.splice(i, 1, " ");
        }       
    }
}

//types the messages on screen
function typeMessages() {
    textAlign(CENTER);
    textSize(15);
    fill(0, 0, 51);
    for (var i = 0; i < 26; i ++) {
        if (keyCode === 65 + i) {
            text(letterMessage[i], width / 2, height - 60);  
        } 
    }   
}

//draws accurate clock on the wall
function drawClock(){
    //from https://p5js.org/examples/input-clock.html
    var cx;
    var cy;
    var secR;
    var minR;
    var hrR;
    var cD;
  
    var radius=width/2;
    secR=radius*0.71;
    minR=radius*0.6;
    hrR=radius*0.5;
    cD=radius*1.7
  
    cx=width/2;
    cy=height/2;
  
    noStroke();
    fill(15);
    ellipse(cx, cy, cD+25, cD+25);
    fill(255);
    ellipse(cx, cy, cD, cD);
  
    var s=map(second(), 0, 60, 0, TWO_PI)-HALF_PI;
    var m=map(minute()+norm(second(), 0, 60), 0, 60, 0, TWO_PI)-HALF_PI;
    var h=map(hour()+norm(minute(), 0, 60), 0, 24, 0, TWO_PI*2)-HALF_PI;
  
    stroke(0);
    strokeWeight(1);
    line(cx, cy, cx+cos(s)*secR, cy+sin(s)*secR);
    strokeWeight(2);
    line(cx, cy, cx+cos(m)*minR, cy+sin(m)*minR);
    strokeWeight(4);
    line(cx, cy, cx+cos(h)*hrR, cy+sin(h)*hrR);
  
    strokeWeight(2);
    beginShape(POINTS);
    for(var i=0; i<360; i+=6){
        var angle=radians(i);
        var x=cx+cos(angle)*secR;
        var y=cy+sin(angle)*secR;
        vertex(x, y);
    }
    endShape();
  }

My final project was inspired by working from home as a full time student last semester and this semester. Like many other students, I experienced a lot of difficulties and setbacks we don’t usually have at school and I wanted to show all the tiny things that happen to us everyday. I also wanted it to reflect the political unrest that was happening at the same time due to the rise of the Black Lives Matter movements, the election, and for CMU students the hiring of Richard Grenell.
My program is interactive and each change is triggered by the keyboard. Users are supposed to follow the alphabet and something will change on the screen or a sound will be played. Since there are some sounds, you will need to use a localhost in order to hear them or view it from WordPress.