Final Project: Santa and Rudolph Take on COVID-19

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

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

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

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

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

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


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


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

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


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


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


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


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


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

}


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


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


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

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

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

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

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

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


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


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


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

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

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


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


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


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


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


















Looking Outwards 11: A Focus on Women Practitioners

The work is called “Weather Worlds” by Emily Gobeille. This work is an interactive installation that “grants” children with superpowers to “control the weather.” The work uses a camera and can green-screen anyone who interacts with it in real-time. This installation can project the image of lightning bolts flying out of the hands of the user, or clouds coming from the palms of their hands. I found this project interesting because it works so incredibly fast, that the person in sight of the camera will be immediately projected onto the screen and can control aspects of the interactive code. On top of this, I really liked the multi-user aspect of this work, as many users can be projected onto the screen at once, which would allow for more interaction, and less line-waiting. Though I do not know exactly how or what went into generating this algorithm for this project, I can already understand that it likely took a lot of time to calibrate correctly so that the green-screened images would not overlap or skew. I personally really admire this because I feel that as time passes, the importance of art for a child’s education is always being undermined, and I feel that this installation does a great job of making kids interested into artworks like this. This project combines both an artistic flare and technological touch that is perfect for the new generation of children who are constantly interacting with smart devices.

Emily Gobeille is a creator of high-end interactive installations for children. For the past few years, she’s studied and worked with motion graphics, concept development, interaction design, and user interaction. Her experiences over the years include web, print, TV< wireless platforms, and installations. It appears that she works in California, New York, and Miami as she runs her own interactive studio called Design I/O, which is located in those areas. Much of Emily Gobeille’s work centers around how children think and behave, which influences what type of interactive installations she makes. She claims to be intrigued by the way children think and play, and she often tries to think like a child when creating her installations.

http://zanyparade.com/

https://www.design-io.com/

Here is an image of what the projected users look like on the screen. Some of them appear to be trapped in ice, another is casting dark clouds in the sky, and another is creating snowflakes that are falling.
Here is another example of how the projected users can interact with the installation. Here you can see multiple users shooting lightning bolts out of their palms.
Here is another image of a user’s feet that is made to look like a Greek God is walking amongst human life, similar to Zeus.

Project-11: Landscape ~ The Up Movie

For my project this week, I wanted to make something that wouldn’t have the most common approach among the class. I figured that a lot of people would look to do a horizontal landscape, where there is a lot of movement with the X position. Therefore, I decided to do the house from Up but moving vertically!

I referred to images of the actual house from the Up animation to try to recreate it with shapes. This was not too difficult because I have gotten used to recreating specific images through layering shapes in p5js. However, the most difficulty I had with this assignment was with making the clouds reappear after they disappear off of the canvas. (I actually had to go to OH for a while for this.. thanks Peter for the help.)

One thing I wish I could have done differently though, is thinking through the concept more. Once I had basically established all of the objects I made, and had movement, I realized that by making the house go “into the sky” there wasn’t much more detail I could add other than birds. I guess with doing things horizontally, there are a lot more realistic features you could add that would make sense (such as mountains or trees).

sketch
//Annie Kim
//anniekim@andrew.cmu.edu
//Section B
//anniekim-11-project

var balloon = []; 
var cloud = [];
var bird = [];
var a = 430; //height at which ground is started

function setup() {
    createCanvas(340, 480);
    //create an initial collection of clouds:
    for (var j = 0; j < 15; j ++) {
    	cloud[j] = makeCloud();
    } 
    //create initial collection of balloons:
    for (var i = 0; i < 100; i ++) {
   		balloon[i] = makeBalloon();
    }
    //create initial collection of birds:
    for (var k = 0; k < 5; k ++) {
    	bird[k] = new Object();
    	//set its properties
    	bird[k].x = random(-10, 340);
    	bird[k].y = random(0, 250);
    	bird[k].dx = random(-2, 2);
    	bird[k].dy = random(-2, 2);
    }
    frameRate(6);
}

function draw() {
	background(143, 214, 236); //light blue sky color
	drawGround();
	updateAndDisplayClouds();
	for (var i = 0; i < 4; i ++) {
		drawBirds(bird[i]);
		bird[i].x += bird[i].dx;
	}
	updateAndDisplayBalloons();
	removeCloudsThatHaveSlippedOutOfView();
	addNewCloudsWithSomeRandomProbability();
	drawHouse();
}

function updateAndDisplayBalloons() { 
//will update and place the balloons:
	for (var i = 0; i < 100; i ++) {
		balloon[i].move();
		balloon[i].display();
	}
}

function updateAndDisplayClouds() {
	//update the cloud's positions and display them:
	for (var i = 0; i < 15; i ++) {
		cloud[i].move();
		cloud[i].display();
		cloud[i].y += cloud[i].dy;
	}
}

function removeCloudsThatHaveSlippedOutOfView() {
	//will remove clouds that are off the canvas and readd in other helper function
	var cloudsToKeep = [];
	for (var i = 0; i < cloud.length; i ++) {
		if (cloud[i].y < height) {
			cloudsToKeep.push(cloud[i]);
		}
	}
	cloud = cloudsToKeep;
}

function addNewCloudsWithSomeRandomProbability() {
	//with a very tiny probability, add a new cloud to the end:
	var newCloudLikelihood = 0.35;
	if (random(0,1) < newCloudLikelihood) {
		cloud.push(makeCloud());
	}
}

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

function cloudDisplay() {
	fill(255);
	noStroke();
	circle(this.x, this.y, 40);
	circle(this.x - 25, this.y - 2, 13);
	ellipse(this.x - 35, this.y + 10, 30, 20);
	circle(this.x - 20, this.y + 12, 25);
	ellipse(this.x + 20, this.y + 10, 30, 20);
}

function balloonDisplay() {
	fill(this.color);
	stroke(this.color);
	ellipse(this.x, this.y, 14, 19);
	stroke(255, 100);
	line(this.x, this.y + 9.5, 170, 315);
}

function balloonMove() {
	this.x += this.dx;
	if (this.x > 250 || this.x < 100) {
		this.dx = -this.dx;
	}
}

function makeCloud() {
	var cld = 
	{x : random(-50, 370),
	y : random(-100, 240),
	dy : 2,
	dx : 1,
	move : cloudMove,
	display : cloudDisplay}
	return cld;
}

function makeBalloon() {
	var bln = 
	{x : random(100, 250),
	y : random(100, 230),
	dx : random(-3, 3),
	color : color(random(130, 255), random(130, 255), random(130, 255)),
	move : balloonMove,
	display : balloonDisplay}
	return bln;
}

function drawHouse() {
	noStroke();
	//ROOF OF HOUSE
	fill(111, 95, 137); //purple color
	quad(120, 315, 220, 315, 240, 360, 100, 360);
	//PART OF HOUSE
	fill(114, 159, 215); //blue color
	rect(120, 360, 100, 20);
	//PART OF HOUSE
	fill(247, 214, 215); //pink color
	rect(120, 380, 100, 50);
	//POINTY PART OF ROOF AND WINDOWS
	fill(241, 234, 150); //yellow color
	rect(130, 310, 20, 20);
	triangle(130, 310, 150, 310, 140, 300); //left window
	triangle(160, 360, 210, 360, 185, 270); 
	rect(160, 360, 50, 10);
	//BAY WINDOW OF HOUSE
	fill(141, 196, 91); //green color
	rect(160, 370, 50, 60);
	triangle(160, 430, 176, 430, 176, 433);
	triangle(192, 433, 192, 430, 210, 430);
	fill(161, 216, 111);
	rect(176, 370, 17, 63);
	//FRONT DOOR
	fill(118, 100, 88); //brown color
	rect(135, 395, 20, 35);
	stroke(50, 40, 20);
	noFill();
	rect(137.5, 398, 15, 30);
	line(145, 398, 145, 428);
	line(137.5, 413, 152.5, 413);
	//WINDOWS
	//top left window
	fill(200, 222, 233); //light blue color
	stroke(114, 159, 215); //darker light blue color
	square(135, 315, 10);
	line(140, 315, 140, 325);
	line(135, 320, 145, 320);
	//right window
	rect(175, 325, 20, 30);
	line(175, 345, 195, 345);
	//bay window 1
	rect(162.5, 390, 10, 20);
	rect(179.5, 392, 10, 20);
	rect(196.5, 390, 10, 20);
}

function drawGround() {
	fill(126, 182, 128);
	noStroke();
	rect(0, a, 340, 50);
	//ground "take-off"
	a += 1;
}

function drawBirds(b) {
	stroke(0);
	strokeWeight(2);
	noFill();
	arc(b.x, b.y, 25, 20, PI + QUARTER_PI, 0, OPEN);
	arc(b.x + 24, b.y, 25, 15, PI, QUARTER_PI - HALF_PI, OPEN);
	b.x += b.dx;
	b.y += b.dy;
	//if bird goes off canvas, it'll come back opposite
	if (b.x > width + 25 || b.x < -25) {
		b.dx = -b.dx;
		b.dy = -b.dy;
	}
}


































Here is the reference image of the house from Up that I was using. Obviously I did not include all the small details of the house, but tried my best to make it as similar and recognizable as possible.
I started by creating this house first in a helper function, and this is what my canvas looked like before I added the objects.
Here is how I was drawing out my work and writing it out. I usually like to match all the colors I want first and then take note of what the RGB combo is.

LookingOutwards-10: Sound Art

The project I will be discussing is The Egg by Fedde ten Berge. This work is egg-shaped with textured ridges on the side which are used to to play vibrations and sound. It is a very hands-on type of installation/project, and despite its egg-shape, appears quite alien-like. It is made out of a block of wood. The artist likes to combine ceramic with another object of another material (left in their true natural form), which in this case is wood. I found this project interesting because when I think of sound art, I typically imagine technology and computers that an audience would not be so openly allowed to touch or fidget with. I was interested in how these slight ridges would produce sound, and was fascinated to find out that with wet hands, or a smooth surface like a mallet, The Egg will give off vibrations that translate to acoustic vibrations, which also makes it accessible/welcoming to those who are hard of hearing. Overall, I was most impressed with the shape of The Egg, because it is very obvious that it was likely a tedious process to hollow out a large block of wood, but keep it strong enough to hold its shell-like structure. The creator’s artistic sensibilities are manifested in the final form in many ways. When you look at the creator’s past works, they all have a few things in common. His projects are very touch-reliant, and prompt the user/audience to interact with it physically. Additionally, the artist utilizes how water and wet surfaces can produce an interesting vibration. On top of this, the artist seems to really enjoy working with natural materials, such as wood, and often tries to leave it in its most natural form without changing the medium too much.

http://www.feddetenberge.nl/het-ei

This is what The Egg looks like, with its natural wood material and usage of ceramic ridges.
Here are some of the artist’s previous works that show his focus on natural materials like wood, and how he incorporates hands-on interaction with his sound art.

Project-10: Sonic Story (& Media Sound Files)

For my project, I animated a short story about a frog on a lily pad on a lake. The story is simply about a lonely frog who gets excited to eat a fly that comes alone (because it was hungry), and gets sad when a nearby fish swims away. There is thunder and lightning that turns the sky dark, and the frog wishes the fish had stayed with him. This project was pretty difficult because there were many things to account for, like all of the coordinates, movements, sounds, and captions. I had to refresh my canvas multiple times to make sure everything was playing out the way I wanted it to. I was tempted to import images into my code, but wanted to challenge myself, so I decided to create all the images and shapes/objects myself.

My 4 sounds consist of the following: a loud thunder that echoes, a rippling/swishing noise of water, a loud croaking of a frog, and a (very irritating) buzzing of a fly. I used the buzzing sound of the fly to make sure the viewer could understand that the shape I had created was some sort of bug/fly. With the frog, I wanted to make sure its croaking was heard after it ate the fly to show some emotion. With the loud thunder, I used it to make the story more dark and scary, followed by a sudden darkening of the sky. With the water noises, I used that to make the night sounds seem louder and make it more clear that the fish had swam away.

sketch
//Annie Kim
//anniekim@andrew.cmu.edu
//SectionB
//anniekim-10-project

/* 
For my program, this is the general story line:
A lonely frog who is on a lilypad in the middle
of the water, is there with a fish. A fly comes near
the frog, and the frog eats it. Luckily, the frog is 
happy because it was getting hungry, however it is not 
so lucky for the fly. Then suddenly, lightning strikes,
and thunder echoes through the sky, and the sky turns dark.
The fish swims away in fear, and the frog is left alone again.
*/

var fly; //audio file names
var frogcroak;
var thunder;
var water;

var bug = {
    x: 450, y: 180,
    width: 45, height: 25
}
var lily = {
    x: 110, y: 320, 
    width: 200, height: 90
}
var lily1 = {
    x: 110, y: 320,
    width: 200, height: 90
}
var tongue_move = {
    x: 240, y: 220
}
var cloud = {
    x: 50, y: 75
}
var crab = {
    x: 400, y: 370,
}
var fish = {
    x: 225, y: 440,
}


function preload() {
    // call loadImage() and loadSound() for all media files here
    fly = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/fly-1.wav")
    frogcroak = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/frogcroak.wav")
    thunder = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/thunder.wav")
    water = loadSound("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/water.wav")
}


function setup() {
    // you can change the next 2 lines:
    createCanvas(450, 480);
    useSound();
    frameRate(1);
}


function soundSetup() { // setup for audio generation
    // you can replace any of this with your own audio code:
    fly.setVolume(0.25);
    frogcroak.setVolume(0.75);
    thunder.setVolume(0.75);
    water.setVolume(0.8);
}


function draw() {
    //sky color
    background(217, 243, 245);
    //water
    fill(150, 214, 250);
    noStroke();
    rect(0, 250, 450, 230);
    //calling fish object
    fishy();
    //lilypad1 ~stagnant, doesnt move
    strokeWeight(2);
    stroke(100, 175, 0);
    fill(150, 225, 0);
    ellipse(lily1.x, lily1.y, lily1.width, lily1.height);
    fill(150, 214, 250); //making cut into lily pad
    noStroke();
    triangle(lily1.x, lily1.y, lily1.x - 100, lily1.y + 15, lily1.x - 50, lily1.y + 60);
    //calling cloud object
    clouds();
    //calling froggy object
    froggy();
    //fly & tongue movement + sound
    if (frameCount >= 1 && frameCount <= 7) {
        flying();
        fill(0);
        textSize(17);
        strokeWeight(1);
        textFont('HelveticaBold');
        text("The fly accidentally gets too close to the hungry frog.", 10, 100);
        tongue();
        fly.play();
    }
    if (frameCount == 7) {
        fly.stop(); //stops sound once fly disappears
    }
    if (frameCount >= 9 & frameCount <= 13) {
        frogcroak.play();
    }
    if (frameCount == 13) {
        frogcroak.stop();
    }
    if (frameCount == 25) {
        background(0);
        textSize(40);
        fill(255);
        strokeWeight(1);
        textFont('HelveticaBold');
        text("The End", 150, 240);
        water.stop();
        noLoop();
    }
}

function flying() {
    //creating 1st fly wing
    fill(255);
    stroke(0);
    ellipse(bug.x + 10, bug.y - 12, bug.width - 15, bug.height - 10);
    //creating fly body
    fill(0);
    noStroke();
    ellipse(bug.x, bug.y, bug.width, bug.height);
    //creating 2nd fly wing
    fill(255);
    stroke(0);
    ellipse(bug.x + 12, bug.y - 10, bug.width - 15, bug.height - 10);
    //making fly move
    bug.x = bug.x - 65;
    if (bug.x <=  200) {
        bug.x = 200;
    }
}

function froggy() {
    //light green color
    fill(117, 176, 111);
    //legs
    stroke(0);
    strokeWeight(3);
    ellipse(lily.x - 15, lily.y - 43, 35, 55);
    ellipse(lily.x + 65, lily.y - 43, 35, 55);
    //body
    ellipse(lily.x + 25, lily.y - 50, 80, 90);
    //feet
    fill(117, 176, 111);
    //arc(lily1.x - 3, lily1.y - 5, 40, 25, PI, 0);
    arc(lily.x + 4, lily.y - 5, 40, 30, PI, 0, CHORD);
    arc(lily.x + 46, lily.y - 5, 40, 30, PI, 0, CHORD);
    //head
    stroke(0);
    ellipse(lily.x + 25, lily.y - 105, 100, 80);
    //smile
    fill(100, 0, 0);
    arc(lily.x + 25, lily.y - 100, 70, 40, 0, PI, CHORD);
    //ears
    fill(117, 176, 111);
    circle(lily.x, lily.y - 140, 38);
    circle(lily.x + 47, lily.y - 140, 38);
    noStroke();
    circle(lily.x + 4, lily.y - 132, 36);
    circle(lily.x + 43, lily.y - 132, 36);
    //white part of eyes
    stroke(0);
    strokeWeight(2);
    fill(255);
    circle(lily.x + 47, lily.y - 140, 23);
    circle(lily.x, lily.y - 140, 23);
    //black of eyes
    fill(0);
    circle(lily.x + 47, lily.y - 140, 10);
    circle(lily.x, lily.y - 140, 10);
    //this will make the frog jump
    if (frameCount >= 9 & frameCount <= 10) {
        lily.y -= 150;
        textSize(20);
        strokeWeight(1);
        textFont('HelveticaBold');
        fill(0);
        text("The frog jumps with joy because it was hungry.", 15, 380);
    }
    if (frameCount >= 10 & frameCount <= 11) {
        lily.y += 150;
    }
}

function tongue() {
    strokeWeight(17);
    stroke(100, 0, 0);
    line(tongue_move.x, tongue_move.y - 10, 135, 230);
    //moving tongue to catch fly
    tongue_move.y -= 5;
    tongue_move.x -= 5;
    if (tongue_move.y <= 200) {
        tongue_move.y = 200;
    }
    if (tongue_move.x <= 220) {
        tongue_move.x = 220;
    }
}

function clouds() {
    if (frameCount >= 14 & frameCount <= 18) {
        darksky();
        lightning();
        textSize(28);
        fill(0);
        textFont('HelveticaBold');
        text("The sky shakes with thunder.", 100, 390);
        thunder.play();
    }
    if (frameCount >= 19 & frameCount <= 25) {
        darksky();
        thunder.stop();
        water.play();
    }
    fill(255);
    //left cloud
    circle(cloud.x, cloud.y, 100);
    circle(cloud.x - 45, cloud.y, 70);
    circle(cloud.x + 55, cloud.y, 55);
    //right cloud
    circle(cloud.x + 300, cloud.y - 30, 100);
    circle(cloud.x + 255, cloud.y - 30, 70);
    circle(cloud.x + 355, cloud.y - 30, 55);
    //clouds moving
    cloud.x += 5;
}

function lightning() {
    fill(255, 255, 0);
    quad(cloud.x, cloud.y, cloud.x - 20, cloud.y + 70, cloud.x + 10, cloud.y + 90, cloud.x + 30, cloud.y + 20);
    quad(cloud.x + 2, cloud.y + 75, cloud.x - 10, cloud.y + 145, cloud.x + 12, cloud.y + 165, cloud.x + 32, cloud.y + 95);
}

function darksky() {
    fill(160);
    rect(0, 0, 450, 250);
}

function fishy() {
    //body and tail
    fill(237, 104, 74);
    strokeWeight(1);
    stroke(255, 0, 0);
    ellipse(fish.x - 38, fish.y - 5, 17, 30);
    ellipse(fish.x - 38, fish.y + 5, 17, 30);
    ellipse(fish.x - 8, fish.y - 26, 30, 25);
    ellipse(fish.x, fish.y, 70, 60);
    //face of fish
    fill(255, 122, 92);
    ellipse(fish.x + 10, fish.y, 53, 54);
    //eyes of fish
    fill(255);
    stroke(0);
    circle(fish.x + 9, fish.y - 5, 18, 18);
    circle(fish.x + 27, fish.y - 5, 18, 18);
    fill(0);
    circle(fish.x + 9, fish.y - 5, 6, 6);
    circle(fish.x + 27, fish.y - 5, 6, 6);
    //bottom fin
    fill(237, 104, 74);
    stroke(155, 0, 0);
    triangle(fish.x, fish.y + 22, fish.x - 20, fish.y + 23, fish.x - 4, fish.y + 38);
    //smile
    noFill();
    arc(fish.x + 18, fish.y + 10, 20, 10, 0, PI);
    //fish is moving off of the canvas
    if (frameCount >= 19 & frameCount <= 25) {
        fish.x += 55;
        fish.y -= 36;
        fill(0);
        textFont('HelveticaBold');
        textSize(20);
        text("The frog wishes the fish would stay.", 50, 450);
        text("The frog doesn't want to be alone in the storm.", 50, 400);
    }
}

















This is the image of a frog that I used as reference when drawing the shape on p5js.

Project 09 – Computational Portrait (Custom Pixel)

I chose to use a selfie of me for this project. I resized the image so that my face would fit in the canvas, and then had words appearing to reveal the selfie. I used the following words : “annie”, “jean”, “flag”, “blue”, “brown”, “tan”, “red”, etc. I used these words because it described images in the actual picture, such as the background, me, and colors within the picture.

I had a little difficulty at first about trying to figure out another creative way to reveal the picture. However, from a previous LO post that I had made, I was inspired by an artist who used common words associated with each other on Google to graphically display data, therefore I chose the words that would be related to/associated with my selfie to appear as it seemed most reasonable.

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

var img;
//words describing pic
var words = ["annie", "jean", "flag", "selfie", "snapchat", "blue", "red", "tan", "brown"]


function preload() {
	var selfie = "https://i.imgur.com/AB85yVlb.jpg";
	img = loadImage(selfie);
}							

function setup() {
	createCanvas(480, 480);
	background(0);
	img.loadPixels();
	frameRate(1000);

}

function draw() {
	//resizing selfie
	img.resize(480, 480);
	var x = random(width);
	var y = random(height);
	//getting exact pixel color to fill in words later
	var pixelx = constrain(floor(x), 0, width);
	var pixely = constrain(floor(y), 0, height);
	var pixelcolor = img.get(pixelx, pixely);

	noStroke();
	fill(pixelcolor);
	textSize(random(8, 18));
	textFont('Helvetica');
	text(words[Math.floor(random(0, 9))], x, y);
	
}
This is as the words are starting to appear..
This is when the picture is almost entirely resolved..
This is the selfie that shows when the words are done appearing.

Looking Outwards – 09

For this Looking Outwards assignment, I chose to look at Flora’s blog post from last week. Flora’s post mentioned how she really liked the “Summer ’91” piece by Sarah Groff Hennigh-Palermo because the work had a smooth visual flow, with mesmerizing warm tones. I thought this was accurately describing the work because upon first glance at the work, I immediately thought of a hot summer day, but an enjoyable type of hot weather. It’s very appealing to the eyes especially during dark seasons and cold weather right now.

I think that in order to add to this discussion, Sarah’s type of artistic style should be talked more in-depth. Upon looking at her portfolio of modern artwork, it was very apparent that her work tends to relate to the “rare aesthetic/deeply hidden memories” trend, where the art tends to remind you of something you’ve seen long ago.

According to Sarah’s own website, my assumption about her art style was correct because she claims to focus on “hybrid nostalgia” with her work. I always tend to find these aesthetics amusing because in a way, it gives me deja vu or a quick glimpse of an old, fading, memory.

This is Flora’s original blog post from last week.

Below is the link to Sarah Groff Hennigh-Palermo’s work website.

http://art.sarahghp.com/works/

This is “Summer ’91” by Sarah Groff Hennigh-Palermo.
This is “Make Manifest” by the artist. This is the one that for some reason gave me ‘deja-vu’ vibes, and reminded me a lot of familiar images that I seem to remember from a while ago.

Looking Outwards-08 : Mike Tucker

https://mike-tucker.com/15/

Mike Tucker is an interactive director whose work focuses on how arts and music can be turned interactive. He is based in the UK, and he studied how to create interactive art. Mike Tucker currently works at Magic Leap, but he has worked with many bands to create interactive art that played their music, such as pulling spheres to your ear virtually, or creating little organisms that would chime with noise. He described himself as a big fan of Flash, before Steve Jobs had gotten rid of it with the development of Macintosh. 

His work centers around using body motions, such as hands, eye movement, and head movement to direct art virtually. I admire how he tries to incorporate all five senses, and has made work that people had experienced synthesia with. I admire this because I tend to be sensitive to my senses, and end up focusing on certain noises or sights, and he effectively uses these traits to create art. 

I admire his Tonandi work the most, because something about it seems very ethereal. There are glowing lights that sway with the sound and the head movement of the VR set, and it almost feels like you are in the movie, Avatar. Additionally, I think this work is special because though there are ethereal images appearing, the background can be anything, and it will make the user feel that they are in a different landscape. It gives off fairy-like vibes, and it is visually and audibly beautiful. 

Mike Tucker presented his work very effectively, by going through timelines and comparisons. He first started by showing how VR once looked like before the technological advancements we have today, and then slowly showed how it changed with time. On top of this, he continuously showed the audience his work, and examples of how a user could interact with VR. For example, one of the works made it possible to “grab” a sphere with a song playing, and hold it to your ear to increase the volume. Another example was where the user’s fingertip could be used to draw different geometric shapes. It was impressive to see how the interactive media progressed as technology improved, and how Mike Tucker’s work grew with the time. From Mike Tucker, I got a sense of what a good presentation would be for artistic and technological projects like his. I would definitely present progress pictures/videos, and show examples of my inspiration like he did.

https://vimeo.com/channels/eyeo2019/page:4

The link above is the link to his talk. However I could not find a video of his work, Tonandi. Therefore, below includes pictures of Tonandi.

These are the glowing strings that I had mentioned that reminded me of the movie Avatar.
Here is an example of how Mike Tucker included hand movement to interact with the art.

LookingOutwards-07

The work is called “Word Spectrum: Visualizing Google’s Bi-Gram Data” by Chris Harrison. It is a visualization of word associations found from Google, where words closer to the ends are more associated with that one word, while words in the center are more evenly associated between both opposing words, and where the font size of the word would be based on the frequency of use of the word. Immediately I was drawn to the work for the following reasons. First, it was visually obvious that there had been many factors that contributed to the color, size, and placement of each word. It reminded me of tug-of-war in the sense that the strength a word had (which would be the frequency of use), the closer or further it came to one side. Second, I admired how the words that were pitted against each other covered many topics, such as war/peace, socioeconomic status, ethnicities, religious beliefs, and things such as love/like. These words often come across our daily dialect and it was interesting to see exactly how often we associate certain words with it. The algorithm that helped generate the work was Google’s enormous bigram dataset, where distributions of words can be analyzed. The creator’s artistic sensibilities and thoughts are manifested in this work as many of Chris Harrison’s previous works focus on research done online. His previous works include unique visualizations of Wikipedia categories, Amazon book links, and internet searches. This work was intriguing and made me wonder what a visualization of my most common used words would look like.

https://www.chrisharrison.net/index.php/Visualizations/WordSpectrum

This is his visualization of war and peace, and the words most often associated with them. The most common words for both opposing terms are “for” and “with” which could be used to link people or groups that are at war or have peace.
This is the visualization of poor and rich associated terms. A lot of the words that are seen tend to mention nations, family, and environment. Through this visualization, I can see many terms that are used to associate with either economic status, and some of them do seem to have bias or stereotypes behind them.
This is Chris Harrison’s visualization of Wikipedia articles and categories that are seemingly unrelated. This shows how these research/search engine topics are focused on by Harrison, and shows that his artistic sensibilities are easily identified within his work.

Project-07-Curves (Fireworks)

For my project, I wanted to incorporate these curves so that it served a purpose to the image. I did not want to simply create curves and just submit random shapes. I thought that the curve I wanted to use would suit the appearance of fireworks very well. It was difficult at first to figure out how to create these fireworks because I originally wanted them to burst and then disappear/fall down as real fireworks do. However, I decided to just have the fireworks growing and changing colors because I wanted the curves to constantly be seen. I based my project off of a cartoon image of a Fourth of July fireworks celebration, and that is why I put a person on a picnic blanket on the grass so that it would make more sense. I think the easiest part for me was making the city skyline and the person’s body because I have continuously layered shapes in all my projects. I think the most difficulty I had was creating the fireworks, while also making them different enough so that it actually seemed like real unpredictable fireworks. As mouseX or mouseY moves, colors of the fireworks can change, and the size and patterns move based on the mouse movement.

sketch
//Annie Kim
//anniekim@andrew.cmu.edu
//SectionB
//anniekim-07-project ~ CURVES ~ 

xStar = []; //array for stars
yStar = [];

function setup() {
    createCanvas(480, 440);
    background(10, 23, 45); //dark blue sky
    for (i = 0; i < 60; i ++) {
    	xStar[i] = random(0, 480); //randomly placing stars
    	yStar[i] = random(0, 240);
    }
    frameRate(10);
}
function draw() {
	//moon
    fill(245);
    noStroke();
    circle(360, 50, 40);
    fill(10, 23, 45);
    circle(350, 50, 40);

    var s = second(); //stars popping up every second
    for (i = 0; i < s; i ++) {
    	fill(255);
    	ellipse(xStar[i], yStar[i], 2, 2); //stars
    }
//orange OR yellow firework
    push();
    translate(250, 80);
    if (mouseX > 240) { //mouseX right half -> yellow
    	stroke(218, 218, 100);
    } else { //mouseX left half -> orange
    	stroke(218, 100, 100);
    }
	firework1(); 
	pop();
    //purple or pink firework
	push();
	translate(450, 45);
	if (mouseY < 240) { //mouseY top half -> pink
		stroke(135, 105, 170);
	} else { //mouseY bottom half -> purple
		stroke(105, 85, 255);
	}
	firework2();
	pop();
	//blue firework
	push();
	translate(30, 50);
	stroke(136, 194, 223);
	firework3();
	pop();
    //pink and red firework
	push();
	translate(200, 200);
	if (mouseX < 240) { //mouseX left half -> pink
		stroke(180, 70, 180); 
	} else { //mouseX right half -> red
		stroke(255, 120, 150);;
	}
	firework4();
	pop();
	//green or dark green firework
	push();
	translate(440, 180);
	if (mouseX > 240) { //mouseX right half -> dark green
		stroke(155, 165, 130);
	} else {
		stroke(205, 255, 180);
	}
	firework5();
	pop();
	
	//~~~~~CITY~~~~~
	//buildings in black
	fill(0); 
	noStroke();
	rect(0, 260, 480, 40); //base
	rect(0, 220, 20, 80);
	rect(145, 200, 15, 100);
	rect(225, 230, 15, 70);
	rect(310, 200, 25, 100);
	//city buildings FILLED BY YELLOW
	fill(250, 250, 160);
	stroke(0);
	strokeWeight(8);
	rect(20, 240, 30, 60);
	rect(50, 210, 25, 90);
	rect(75, 230, 20, 70);
	rect(95, 250, 30, 50);
	rect(125, 220, 20, 80);
	rect(160, 215, 20, 85);
	rect(180, 200, 20, 100);
	rect(200, 200, 25, 100);
	rect(240, 250, 30, 50);
	rect(270, 230, 40, 70);
	rect(335, 220, 15, 80);
	rect(350, 240, 30, 60);
	rect(380, 190, 20, 110);
	rect(400, 220, 20, 80);
	rect(420, 230, 40, 70); 
	rect(460, 260, 20, 40);//rightmost building
    //START OF WINDOW MAKING(separated by building in code)
	strokeWeight(8);
	stroke(0);
	//building #1
	line(62, 215, 62, 300);
	line(55, 230, 70, 230);
	line(55, 245, 70, 245);
	line(55, 263, 70, 263);
	line(55, 280, 70, 280);
    //building #2
	strokeWeight(4);
	line(270, 240, 310, 240);
	line(270, 250, 310, 250);
	line(270, 260, 310, 260);
	line(270, 270, 310, 270);
	line(270, 280, 310, 280);
	line(270, 290, 310, 290);
    //building #3
	line(410, 220, 410, 295);
	line(400, 240, 420, 240);
	line(400, 260, 420, 260);
	line(400, 280, 420, 280);
    //building #4
    line(425, 230, 425, 295);
	line(430, 230, 430, 295);
	line(435, 230, 435, 295);
	line(440, 230, 440, 295);
	line(445, 230, 445, 295);
	line(450, 230, 450, 295);
	line(455, 230, 455, 295);
	line(420, 250, 460, 250);
	line(420, 270, 460, 270);
	line(420, 290, 460, 290);
    //building #5
    strokeWeight(6);
	line(180, 215, 200, 215);
	line(180, 225, 200, 225);
	line(180, 235, 200, 235);
	line(180, 245, 200, 245);
	line(180, 255, 200, 255);
	line(180, 265, 200, 265);
	line(180, 275, 200, 275);
	line(180, 285, 200, 285);
    //building #6
	strokeWeight(3);
	line(200, 232, 225, 232);
	line(200, 267, 225, 267);
	line(212.5, 200, 212.5, 295);
    //END OF WINDOW MAKING
	//grass
	fill(42, 83, 47);
	noStroke();
	rect(0, 299, 480, 141);

	//picnic blanket
    fill(220, 125, 145); //pink color
    stroke(185, 100, 100); //darker pink color outline
    quad(150, 340, 310, 340, 330, 400, 130, 400); //blanket
    //PERSON SITTING ON BLANKET
    //arms
    fill(230, 200, 170);
    noStroke();
    rect(170, 340, 8, 30);
    rect(212, 340, 8, 30);

    //pants
    fill(104, 104, 55); 
    noStroke();
    ellipse(185, 380, 45, 25);
    ellipse(205, 380, 45, 25);
    //shirt
    fill(234, 234, 131);
    noStroke();
    rect(177.5, 313, 35, 57);
    ellipse(195, 369, 38, 9);
    rect(170, 320, 10, 20);
    rect(210, 320, 10, 20);
    //shoulders
    circle(177.5, 321, 15);
    circle(212.5, 321, 15);
    //sleeve lines
    stroke(200, 200, 100);
    strokeWeight(2); 
    line(178, 327, 178, 340);
    line(212, 327, 212, 340);
    //neck
    fill(200, 170, 140);
    noStroke();
    rect(190, 305, 10, 8);
    //head shape
    fill(230, 200, 170);
    ellipse(195, 295, 23, 28);
    //hair
    fill(80, 45, 25);
    ellipse(195, 285, 25, 20);
    ellipse(191, 290, 20, 30);
    triangle(195, 288, 207, 288, 195, 303);
    //ear
    fill(230, 200, 170);
    stroke(200, 180, 140);
    strokeWeight(1);
    ellipse(200, 295, 4, 7);
}

function firework1() { //yellow-orange firework
	var x;
	var y;
	var a = map(mouseY, 0, height, 0, 20);
	var h = map(mouseY, 0, height, 0, 20);
	var b = a / 4;
	var angle = 360;
	beginShape();
	for (var i = 0; i < angle; i ++) {
		strokeWeight(0.2);
		noFill();
		var q = map(i, 0, 180, 0, TWO_PI);
		x = (a - b) * cos(q) + (h) * cos(((a + b)/ b) * q);
		y = (a - b) * sin(q) + (h) * sin(((a + b)/ b)* q);
		vertex(x, y);
	}
	endShape(CLOSE);
}

function firework2() { //purple-pink firework
	var x;
	var y;
	var a = map(mouseY, 0, height, 0, 35);
	var h = map(mouseY, 0, height, 0, 35);
	var b = a / 8;
	var angle = 360;
	beginShape();
	for (var i = 0; i < angle; i ++) {
		strokeWeight(0.2);
		noFill();
		var q = map(i, 0, 180, 0, TWO_PI);
		x = (a - b) * cos(q) + h * cos(((a + b)/ b) * q / 2);
		y = (a - b) * sin(q) + h * sin(((a + b) / b) * q / 2);
		vertex(x, y);
	}
	endShape(CLOSE);
}

function firework3() { //blue firework
	var x;
	var y;
	var a = map(mouseX, 0, 240, 0, 20);
	var h = map(mouseY, 0, 240, 0, 20);
	var b = a / 15;
	var angle = 360;
	beginShape();
	for (var i = 0; i < angle; i ++) {
		strokeWeight(0.08);
		noFill();
		var q = map(i, 0, 180, 0, TWO_PI);
		x = (a - b) * cos(q) + h * cos(((a + b)/ b) * q);
		y = (a - b) * sin(q) + h * sin(((a + b) / b) * q);
		vertex(x, y);
	}
	endShape(CLOSE);
}

function firework4() { //pink-red firework
	var x;
	var y;
	var a = map(mouseX, 0, 400, 0, 50);
	var h = map(mouseY, 0, 400, 0, 40);
	var b = a / 20;
	var angle = 360;
	beginShape();
	for (var i = 0; i < angle; i ++) {
		strokeWeight(0.2);
		noFill();
		var q = map(i, 0, 180, 0, TWO_PI);
		x = (a - b) * cos(q) + h * cos(((a + b)/ b) * q);
		y = (a - b) * sin(q) + h * sin(((a + b) / b) * q);
		vertex(x, y);
	}
	endShape(CLOSE);
}

function firework5() { //green-dark green firework
	var x;
	var y;
	var a = map(mouseX, 0, 240, 0, 18);
	var h = map(mouseX, 0, 240, 0, 18);
	var b = a / 7;
	var angle = 360;
	beginShape();
	for (var i = 0; i < angle; i ++) {
		strokeWeight(0.4);
		noFill();
		var q = map(i, 0, 180, 0, TWO_PI);
		x = (a - b) * cos(q) + h * cos(((a + b)/ b) * q);
		y = (a - b) * sin(q) + h * sin(((a + b) / b) * q);
		vertex(x, y);
	}
	endShape(CLOSE);
}



This was the starting process where I made the night sky, and added a moon and stars. The stars add with seconds, so every star represents a second.
This was after I made the city skyline, I started by making rectangles of different sizes with a yellow fill and black stroke outline. I made the windows by putting black lines over the yellow fills.
This was my inspiration/reference for the fireworks project. I didn’t do nearly as much as in this image, but I did base a lot of ideas from this.