## Final Project

For my project I created a game to raise awareness towards mask wearing so the person is trying to move through covid particles to reach the mask. And basically gets saved if he does so without colliding with a covid body. If you reach the mask, the words, “You were saved show up” while if you collide with a cover particle it says, “You’ve been infected, happy recovery!”
If I had more time I would have implemented multiple levels where the speed of the covid particles begin to vary making it more difficult and instead of a generic score the levels would be how many months you have gone without being infected. Thus, again endorsing mask wearing as a norm.

Instructions use your mouse and YOU DO NOT WANT TO GET COVID SO STAY AWAY FROM THOSE NASTY RED THINGS!!

sketch
``````//Aadya Bhartia
//Section A

/* The objective of the game is for the user to reach the mask and to
avoid the covid particles! Once you reach the mask you win the game and if you
bang into a particle you lose. The purpose of the game is to encourage mask wearing
*/

var rad = 40; // for size of covid particle
//person
var personX;
var personY;
//array to store covid symbols
var covidX = [];
var covidY = [];
var dx = [];
var dy = [];
//variables to store images
var covid;
var person;

}

function setup() {
createCanvas(500, 500);
background(220);
//storing covid particles random x and position as well as speed
for(var i = 0; i<15; i++){
covidX[i] = random(width);
covidY[i] = random(height);
dx[i] = random(-5,5);
dy[i] = random(-5,5);
}
//text formatting
frameRate(10);
textAlign(CENTER);
textFont('New Roman');
textStyle(BOLD);
}

function draw() {
//constraining mouse within canvas
var x = constrain(mouseX, 0, width-10);
var y = constrain(mouseY, 0, height-10);
background(220);
//displaying mask and checking if person has touched maks

for(var i = 0; i<10; i++){
fill(0);
covidX[i] += dx[i];
covidY[i] += dy[i];
//to bounce covid particles off the sides
if(covidX[i] >= (width) || covidX[i] <= 0){
dx[i] = -1*dx[i];
}
if(covidY[i] >= (height) || covidY[i] <= 0){
dy[i] = -1*dy[i];
}
//when person bangs into covid particle
if(covidY[i]> y-15  & covidY[i]< y+15 ){
if(covidX[i]> x-15  && covidX[i]< x+15 ){
finishGame();
}
}
}
//person
fill(255,0,0);
//displaying mouse as person
image(person,x, y, 60,100);

}
}

//game won if person reaches the maks
function achieved(){
var d = dist(mouseX, mouseY, this.x, this.y);
if(d<20){
wonGame();
}
}

//constructor
var m = {x : random(30, width-30),
y : random(30, height-30),
show : maskDisplay, check : achieved}
return m;
}
//message for when game has been lost
function finishGame(){
fill("black");
textSize(30);
text("You've been infected, happy recovery!", width/2, height/2);
noLoop();
}
//message for when game has been won
function wonGame(){
fill("black");
textSize(40);
text("YOU WERE SAVED!!!", width/2, height/2);
noLoop();
}

``````

## Final Project – Responsive Wearables

In 2020, one of the biggest treasure is to experience the time in outdoor. In the time when we need to carefully think about distancing to other people and gearing up ourselves with masks, gloves and sanitizer, I design this interactive game to explore with the idea of using garments as an responsive exterior shell to protect ourselves and create personal boundaries.

By moving the mouse, the character is able to wondering in this projected scenery with colorful reference object. For the design of the character, there are two mode in response to two situations. The character begins with wearing a normal scale clothes. When the player pressed the mouse, the character switch to the inflatables garment set with an “alert” sign.

One of the biggest challenge I encountered with when programming this game is making paneling affect on the canvas. The canvas visually works as a camera frame that shifting with the location of the mouse. If I further develop this program, I hope to have the alert character setting on when the character intersect with every bubble in the arrays.

sketch
``````//Isabel Xu
//Section A
//Final Project

var cX = 0;
var cY = 0;
var cdx = 0;
var cdy = 0;
var start_locationX = 300;
var start_locationY = 200;
var cir_X = [];
var cir_Y = [];
var cir_c = [];
var animGreen = [];

//green character image arrays
animGreen = [green1, green2, green3];

//red character image

}

function setup() {
createCanvas(600,400);
frameRate(20);

//create level of randomness to the bubble
for (var i = 0; i < 7000; i++) {
cir_X[i] = random(-5000, width+5000);
cir_Y[i] = random(-4000, height+4000);
cir_c[i] = color(235, random(255), random(255));
}
imageMode(CENTER);
}

function draw() {
background(235, 218, 199);
//movement of the bubble inversely to the character
let cir_dx = ((mouseX)-300)/20*-1;
let cir_dy = ((mouseY)-200)/20*-1;
//create colorful bubble background for visual reference
for (var i = 0; i < 7000; i++) {
noStroke();
drawShape(cir_X[i], cir_Y[i], cir_c[i]);

cir_X[i] += cir_dx;
cir_Y[i] += cir_dy;

}

drawFigure(cir_X[i], cir_Y[i]);

}

function drawShape(cir_X, cir_Y, cir_c) {
fill(cir_c);
ellipse(cir_X, cir_Y, 30, 15);
}

function drawFigure(){
if (mouseIsPressed) {
drawRedCharacter();
}else{
drawGreenCharacter();
}
}
function drawGreenCharacter(){
//limit the character movement
cX = constrain(mouseX,250,350);
cY = constrain(mouseY,175,225);

fill(110);
ellipse(start_locationX+5,start_locationY+80,130,40)

//draw green character
//create animation effect with multiple image
let randomGreen = random(animGreen);
image(randomGreen,start_locationX,start_locationY,150,180);

//speed is inversely proportional to the mouse distance
cdx = (cX - start_locationX)/20;
cdy = (cY - start_locationY)/20;

start_locationX += cdx;
start_locationY += cdy;

}
function drawRedCharacter (){
cX = constrain(mouseX,250,350);
cY = constrain(mouseY,175,225);

fill(255,0,0);
cdx = (cX - start_locationX)/20;
cdy = (cY - start_locationY)/20;

start_locationX += cdx;
start_locationY += cdy;

}``````

## Final Project

sketch
``````/*
Lauren Kenny
lkenny@andrew.cmu.edu
Section A

This program draws a grid of masks and covid particles.

*/

"https://i.imgur.com/1GlKrHl.png",
"https://i.imgur.com/EJx0rn7.png",
"https://i.imgur.com/uz2coXH.png",
"https://i.imgur.com/rxFAYmh.png",
"https://i.imgur.com/SWkTR5H.png",
]

// ARRAY TO STORE LOADED IMAGES
var objectImages = [];

// ARRAYS TO STORE RELEVANT IMAGE VALUES
var objectX = [0, 0, 0, 0, 0];
var objectY = [0, 0, 0, 0, 0];
var objectW = [672/8, 772/5, 847/5, 841/5, 744/8];
var objectH = [656/8, 394/5, 323/5, 410/5, 828/8];

for (var i=0; i<objectLinks.length; i++) {
}
}

function setup() {
createCanvas(800, 500);
frameRate(4);
}

function draw() {
background(180);
var x=0;
var y=0;
// CREATES A GRID OF MASK/COVID IMAGES
for (let rows=0; rows<=height; rows+=100) {
x=0;
for (let cols=0; cols<=width; cols+=150) {
i = int(random(0, objectImages.length));
image(objectImages[i], x, y, objectW[i], objectH[i]);
x+=150;
}
y+=100;
}

// WHEN THE MOUSE IS PRESSED, TEXT APPEARS
if (mouseIsPressed) {
fill(0, 0, 0, 200);
rect(0, 0, width, height);
fill(255);
textSize(35);
text('beware of covid', width/3, height/2);
}
}

``````

## Final Project

My project was inspired by a silly idea I had for a flip book of my personal failures revolving around the bouncing ball problem from early on in the class. That evolved into slides containing the ball that you had to click or else the game would end. Eventually I figured with all the problems the year had I could make it America and the ball representing the horrible things popping up all over the country. The user has to keep clicking on the ball as it bounces around the map until they win. Every time the map goes off the canvas, the ball gets faster and more red and the background gets darker. The screen will also begin to crack. Encouraging and frightened dialogue will also appear at the bottom and top respectively, and I’ve included instructions and a brief introduction in the console at the start of the game. I wish I had more time to flesh out the theme of the multiple problems of the year and could’ve made multiple minigames rather than just one, or a more involved animation, but after how poorly my proposal turned out I’m very happy with what I have.

``````var slides = []
var threat = 0
var prevent = 0
var incomingX = -100
var incomingY = -100
var incomingSize = 20
var u
var t
var rectY = -200
var flag;
var pic;
var hasDrawn = false
var lineX = []
var lineY= []
var gameStart = false
var hasWritten = false

function makeSlide(sX, sY, sDX, slideTime, ballX, ballY, bounceX, bounceY){
slide = {x: sX, y: sY, dx: sDX, timing: slideTime, drawFunction: drawSlide, stepFunction: slideSlide, extra: drawBall, extraMove: ballMove, extraX: ballX, extraY: ballY, moveX: bounceX, moveY: bounceY}
return slide
}

function drawSlide(){
imageMode(CENTER)
image(pic, this.x, this.y, 350, 350)
}

function slideSlide(){
this.x += this.dx
if(this.x >= 600 || this.x <= -200){
this.dx *= -1
} if (this.x == 600){
this.dx -= 2
} else if (this.x == -200){
this.dx += 2
}
}

function drawBall(){
stroke(0, 0, 0)
fill(256 - threat, (256 -(threat * 13)), 256 -(threat * 13))
circle(constrain(this.extraX, this.x - 155, this.x + 175), constrain(this.extraY, 30, 350), 40)
}

function ballMove(){
this.extraX += this.dx
this.extraX += this.moveX
this.extraY += this.moveY
if (this.extraX >= this.x + 175 || this.extraX <= this.x - 155){
this.moveX *= -1
} if (this.extraY >= 330 || this.extraY <= 30){
this.moveY *= -1
}
if (mouseIsPressed & dist(mouseX, mouseY, this.extraX, this.extraY) <= 20){
prevent += 1
}
else if (this.x == 600 || this.x == -20){
threat += 1
}
}

}

function setup() {
angleMode(DEGREES)
frameRate(15)
createCanvas(400, 400);``````

## Final Project!

For my final project, I wanted to create a game that presents a picture at the end with hidden images that represent events of 2020. The user is able to click two images to switch the locations of the images, and therefore unscramble the original scrambled image that loads. In order not to pressure the user or make the user create one “right answer”, I chose not to tell the user when the image is “correctly” unscrambled. Therefore, the game acts more like a pressure-free artistic adaptation of an image if they’d like.

sketch
``````// Susie Kim
// Final Project
// susiek@andrew.cmu.edu
// Section A

// set global variables
"https://i.imgur.com/vGhpX7m.jpg", //1
"https://i.imgur.com/bNtGvLH.jpg", //2
"https://i.imgur.com/cWHfsai.jpg", //3
"https://i.imgur.com/hnFyXIy.jpg", //4
"https://i.imgur.com/06xo9FF.jpg", //5
"https://i.imgur.com/FJbeTn2.jpg", //6
"https://i.imgur.com/HZduFcW.jpg", //7
"https://i.imgur.com/fU2goSM.jpg", //8
"https://i.imgur.com/i4BVpfk.jpg", //9
"https://i.imgur.com/dvCAEzm.jpg", //10
"https://i.imgur.com/t7FzJVW.jpg", //11
"https://i.imgur.com/MVcrDnK.jpg", //12
"https://i.imgur.com/QUBppYU.jpg", //13
"https://i.imgur.com/IPIsgqD.jpg", //14
"https://i.imgur.com/Inkq9Nc.jpg", //15
"https://i.imgur.com/FJotQ09.jpg"]; //16

gridRows = 4;
gridCols = 4;
sqSize = 100;

images = [];
puzzles = [];
ids = [];
shuffledIds = [];

clickedImgs = [];
numClicks = 0;

for (var i=0; i < 16; i++) {
}
}

function setup() {
createCanvas(500, 500);
background(145, 168, 209);

// write instructions text ontop and bottom
fill(255);
text('complete the puzzle to see the image :)', 150, 35);
text('click 2 pictures to switch their location!', 150, 475);

push();

// write instructions text on left and right
translate(250, 250);
text('2020 in review', -35, 225);

text('2020 in review', -35, 225);
pop();

// create a set of shuffled ids:
for (var i = 0; i < 16; i++) {
ids[i] = i;
}
shuffledIds = shuffle(ids);

// make 16 objects with object properties
for (var i = 0; i < gridRows; i++) {
for (var j = 0; j < gridCols; j++) {
puzzles[j+i*4] = makePuzzle(50+j*100, 50+i*100, shuffledIds[j+i*4], j+i*4);
}
}
}

function draw() {
// draw the grid of shuffled images
for (var i = 0; i < gridRows; i++) {
for (var j = 0; j < gridCols; j++) {
puzzles[j+i*4].display();
}
}
}

// create an object that holds the images' properties
function makePuzzle(xlocation, ylocation, idNum, idNum2) {
var makeImg = { x1: xlocation,
y1: ylocation,
shuffId: idNum,
origId: idNum2,
display: makeImage }
return makeImg;
}

// function that creates the image
function makeImage() {
image(images[this.shuffId], this.x1, this.y1, 100, 100);
}

// if mouse is clicked on two images, switch them
function mouseClicked() {
for (var i = 0; i < 16; i++) {
if (mouseX > puzzles[i].x1 & mouseX < puzzles[i].x1+100 && // boundaries of any image i
mouseY > puzzles[i].y1 && mouseY < puzzles[i].y1+100) {
clickedImgs.push(puzzles[i].origId); // push original Id value of clicked image into clickedImgs array
numClicks += 1;
}
}
// if 2 images are clicked, swap, and reset clicknum to 0
if (numClicks == 2) {
swapImages();
numClicks = 0;
}
}

// function that swaps the two images
function swapImages() {
// store the x and y values in a temporary variable
var tempX = puzzles[clickedImgs[0]].x1;
var tempY = puzzles[clickedImgs[0]].y1

// switch the x and y values
puzzles[clickedImgs[0]].x1 = puzzles[clickedImgs[1]].x1;
puzzles[clickedImgs[0]].y1 = puzzles[clickedImgs[1]].y1;

puzzles[clickedImgs[1]].x1 = tempX;
puzzles[clickedImgs[1]].y1 = tempY;

// clear the clickedImgs array
clickedImgs.pop();
clickedImgs.pop();
}``````

Some examples of imagery I used was a basketball for Kobe Bryant’s death, a fire printed bag for the California and Australia wildfires, a tiger poster for Tiger King, and an Oscar for Parasite winning Best Picture.

## Final Project

sketch
`````` /*
Rachel Kim
Section C
rachelki@andrew.cmu.edu

Nicholas Wong
Section A
nwong1@andrew.cmu.edu
*/

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

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

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

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

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

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

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

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

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

// These URLs are for the individual walk cycle images,
var filenames = [];
filenames[0] = "https://i.imgur.com/URNRJvg.png";
filenames[1] = "https://i.imgur.com/dt8xXHQ.png";
filenames[2] = "https://i.imgur.com/jmhE5QQ.png";
filenames[3] = "https://i.imgur.com/twdsSdv.png";
filenames[4] = "https://i.imgur.com/HWf5XmA.png";
filenames[5] = "https://i.imgur.com/45onU9z.png";
filenames[6] = "https://i.imgur.com/ey2SDeI.png";
filenames[7] = "https://i.imgur.com/cG56PdF.png";
filenames[8] = "https://i.imgur.com/533xGwE.png";

for (var i = 0; i < filenames.length; i++)
{
}

//Background elements

//Further background elements

//Covid obstacles
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}

}

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

}
}
//-------------------------------------------------------------------------------------------------------------------------------------------
}

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

return player;
}

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

return platform;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
}

``````

To run this program, simply press space.

This game is a side-scrolling platform game, where the screen constantly scrolls and the player can only jump.
The goal of the game is to not touch any covid particles and to not fall of the edge of the screen. The longer you survive, the faster the screen scrolls.

We created a side-scrolling game because we thought it would be fun. The theme was around Covid to stay relevant. A side-scrolling game proved to be somewhat challenging due to the dynamic collision detection. Checking bounds and making particles bounce off of things were covered in class, however it was a little harder to implement that in a game where we needed to know exactly where the player collided with an object, and how to deal with positioning the player during/after the collision. Due to time constraints, we did not have much time to play-test the game. For example, we realized only after implementing the graphical elements that the game was pretty hard to read; the player and covid obstacles constantly blended in with the background, making it hard to see where everything was.

Overall, if we had more time, we would have refined the collision detection system and added in an actual algorithm for creating obstacles and platforms, as currently they are being randomly generated and do not take into account whether it is possible to ‘beat’ or ‘pass’ any given set of platforms or obstacles. Also, we would implement sound.

Done by Rachel Kim and Nicholas Wong.

## 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 = [];
"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 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;

// load pictures (different color viruses)
for(var i = 0; i < covidImageLinks.length; i ++) {
}
}

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

imageMode(CENTER);

// 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;
}
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){
}
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);

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
// 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);

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 – 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;

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
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
imgJun1 = loadImage("https://i.imgur.com/V8MHehF.jpg"); //St John's Church
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);
}

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;

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

angle = angle + dx;
pop();

push();
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();
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);
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)
text(":(", 0, 0);
pop();
stroke(0);
strokeWeight(2);
fill('white');
}
}
}

}

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

// 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,
speed: -1.0,
move: tigersMove,
display: tigersDisplay}
return tgs;
}

function displayHorizon(){
image(aprImg2, 0, 0, width, height);
push();
translate(60, 80);
imageMode(CENTER);
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();
drawPodium();
backButton();
}

}

//May helper functions
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("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);
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);
fill(255);
ellipse(25, 0, 50, 100); //spaceship body
rect(0, 0, 50, 150);
stroke(255, 0, 0);
strokeWeight(3);
push();
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();

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

updateAndDisplayTrees();
removeTreesThatHaveSlippedOutOfView();
}
}

//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;
}

// 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,
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;
}

// 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),
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;

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

// 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);
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);
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();
translate(x + txp, y + typ);
noStroke();
fill(255, 175, 0);
push();
ellipse(17, -12, 4, 15);
ellipse(15, -17, 4, 15);
pop();
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
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();
translate(x + txvp, y + tyvp);
noStroke();
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
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();
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++) {
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);
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.slmaze
``````//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 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

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:
// 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);
}*/
``````

## PROJECT-15 (covid-simulator)

For this project, I decided to go in a direction of analyzing covid spread through showing how if you infect one person, how the others will get infected through probability and chance. I will use an array of people and if one or more is clicked, a droplet of covid is “given” to the person to “infect” them. Over time, the nearby people will heal and recover or pass away. If all people are infected, the population will never recover.

sketch
``````// 15-104
// SEAN CHEN
// FINAL PROJECT

var people = [];
var wNum = 14;
var hNum = 12;
var chance = .1; // chance of transmission
var speed = 20; // speed of transmission
var deathRate = 0.02; // death rate
var body;

// image for the body
}

function setup() {
createCanvas(600, 400);
for (var i = 0; i < wNum; i++) {
var temp = []
for (var j = 0; j < hNum; j++) {
temp.push(createPerson(i, j));
}
people.push(temp);
}
frameRate(speed);
}

// drawing people + infection spreading
function draw() {
background(235);
updatePerson();
infectPerson();
}

// step and drawing of people
function updatePerson() {
for (var i = 0; i < wNum; i++) {
for (var j = 0; j < hNum; j++) {
people[i][j].draw();
people[i][j].step();
}
}
}

// creating person object
function createPerson(x, y) {
var p = {
px: x*(width/(wNum-1)),
py: y*(height/(hNum-1)),
infected: 0,
age: 0,
col: 0,
draw: thePerson,
step: stepPerson,
}
return p;
}

// individual people
function thePerson() {
stroke(0);
push();
translate(-20, 5);
image(body, this.px, this.py, 40, 80);
pop();

push();
fill(colPerson(this.col));
circle(this.px, this.py, 30);
fill(255);
ellipse(this.px-8, this.py-2, 7, 10);
ellipse(this.px+8, this.py-2, 7, 10);
pop();

push();
noStroke();
fill(0);
circle(this.px-8, this.py-2, 4, 4);
circle(this.px+8, this.py-2, 4, 4);
pop();
}

// red for most infected
// green for temp immunity
// black for death
function colPerson(colNum) {
if (colNum == 0) {
return color(255);
} else if (colNum == 1) {
return color(255, 0, 0);
} else if (colNum == 2) {
return color(255, 65, 65);
} else if (colNum == 3) {
return color(255, 130, 130);
} else if (colNum == 4) {
return color(255, 195, 195);
} else if (colNum == 5) {
return color(0, 255, 0);
} else if (colNum == 6) {
return color(0);
}
}

// if infected, what stage infection
function stepPerson() {
if (this.infected == 2) {
this.col = 6;
this.age = 0;
}
if (this.infected == 1) {
this.age++;
if (this.age <= 10) {
this.col = 1;
} else if (this.age > 10 & this.age <= 20) {
this.col = 2;
} else if (this.age > 20 & this.age <= 30) {
this.col = 3;
} else if (this.age > 30 & this.age < 40) {
this.col = 4;
} else if (this.age < 60) {
if (random(0, 10) < deathRate) {
this.infected = 2;
} else {
this.col = 5;
}
} else if (this.age == 60) {
this.col = 0;
this.age = 0;
this.infected = 0;
}
}
}

function mouseClicked() {
clickPerson();
}

// clicking persons to give covid
function clickPerson() {
for (var i = 0; i < wNum; i++) {
for (var j = 0; j < hNum; j++) {
if (dist(mouseX, mouseY, people[i][j].px, people[i][j].py) < 20)  {
people[i][j].infected = 1;
people[i][j].col = 1;
people[i][j].age = 0;
}
}
}
}

// infecting right
function r(i, j) {
if (random(0, 10) < chance & people[i+1][j].infected != 2) {
people[i+1][j].infected = 1;
}
}
// infecting left
function l(i, j) {
if (random(0, 10) < chance & people[i-1][j].infected != 2) {
people[i-1][j].infected = 1;
}
}
// infecting up
function u(i, j) {
if (random(0, 10) < chance & people[i][j-1].infected != 2) {
people[i][j-1].infected = 1;
}
}
// infecting down
function d(i, j) {
if (random(0, 10) < chance & people[i][j+1].infected != 2) {
people[i][j+1].infected = 1;
}
}

// probability and chance of spread
function infectPerson() {
for (var i = 0; i < wNum; i++) {
for (var j = 0; j < hNum; j++) {
if (people[i][j].age >= 20) {
if (i > 0 & j > 0 && i < wNum-1 && j < hNum-1) {
r(i, j);
l(i, j);
u(i, j);
d(i, j);
} else if (i == 0 & j == hNum-1) {
r(i, j);
u(i, j);
} else if (i == wNum-1 & j == 0) {
l(i, j);
d(i, j);
} else if (i == 0 & j == 0) {
r(i, j);
d(i, j);
} else if (i == 0) {
r(i, j);
u(i, j);
d(i, j);
} else if (j == 0) {
r(i, j);
l(i, j);
d(i, j);
} else if (i == wNum-1 & j == hNum-1) {
l(i, j);
u(i, j);
} else if (i == wNum-1) {
l(i, j);
u(i, j);
d(i, j);
} else if (j == hNum-1) {
r(i, j);
l(i, j);
u(i, j);
}
}
}
}
}``````