Project 11

Continuing my inspiration from the artwork associated with Vaporwave, I decided to pursue my generative landscape project using the aesthetics, color palette, and symbols associated with the genre. Furthermore, to add to the surrealist atmosphere of the piece, I stylistically juxtaposed the Vaporwave landscape with a minimalist depiction of a train and dog. The interior of the train serves as the non-moving element of the drawing and has a window by which the Vaporwave setting can be seen. The two javascript objects that I used were telephone poles, a common symbol in Vaporwave art, that vary in thickness, height, and number of cross beams, and imported images of a marble bust, the Windows 95 logo, and an error message that vary in position and speed. Additionally, I used a noise function to generate a mountain in the background to complete the scene.

sketch – CopyDownload

var telephonePoles = [];
var images = [];
var showImage = [];
var mountainValue = [];
var noiseParam = 0;
var noiseStep = .1;

function preload() {
    // call loadImage() and loadSound() for all media files here
    images[0] = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/error-1.png");
    images[1] = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/floralshoppe-1.png");
    images[2] = loadImage("https://courses.ideate.cmu.edu/15-104/f2020/wp-content/uploads/2020/11/windows-1.png")
}


function setup() {
	frameRate(100);
    // you can change the next 2 lines:
    createCanvas(480, 480);
    //frameRate(20);
    //create telephonePoles
    for (var i = 0; i < 5; i++){
    	var tx = random(width);
    	var tt = random(1,5);
    	var th = random(50, height/2 - 70);
    	var tb = floor(random(1,4));
    	var pole = makePoles(tx,tt,th,tb);
    	telephonePoles.push(pole);
    	var image = makeImages(random(width/2,width),random(130,310));
    	showImage.push(image);
    }
    for(var i = 0; i <= width/5; i++){
    	var n = noise(noiseParam);
    	var value = map(n,0,1,0,height/2);
    	mountainValue.push(value);
    	noiseParam += noiseStep;
    }
}

var chooseColor;
function draw() {
    // you can replace any of this with your own code:
    //var chooseColor = random(floor(0,5));
    if (chooseColor == 0){
    	background(255,113,206);
    } else if (chooseColor == 1){
    	background(1,205,254);
    } else if (chooseColor == 2){
    	background(5,255,161);
    } else if (chooseColor == 3){
    	background(185,103,255);
    } else {
    	background(255,251,150)
    }
    drawGrid();
    drawMountain();
    for (var i = 0; i < 5; i++){
    	var t = telephonePoles[i];
    	t.move();
 		t.drawPole();
    }
    for (var i = 0; i < showImage.length; i++){
    	var m = showImage[i];
    	m.moveImg();
    	m.drawImage();
    }
    //image(images[0],random(0,width),height/2);
    drawTrain();
    drawChair();
    drawLegs();
    push();
    translate(width,0);
    scale(-1,1);
    drawChair();
    pop();
    drawDog();
    newPole();
    newImage();
    removeImage();
    removePole();
    moveMountain();
    if (frameCount % 100 == 0){
		chooseColor = floor(random(0,5));
    }
}

function drawTrain() {
	noStroke();
	fill(193,143,171);
	rect(0,0,width,120);
	rect(0,320,width,height);
	fill(221,194,59);
	//window
	beginShape();
		vertex(0,110);
		vertex(width,110);
		vertex(width,330);
		vertex(0,330);
	beginContour();
		vertex(10,320);
		vertex(width-10,320);
		vertex(width-10,120);
		vertex(10,120);
	endContour();
	endShape(CLOSE);
}

function drawChair() {
	noStroke();
	fill(84,68,70);
	beginShape();
		vertex(20,height);
		vertex(20,280);
		curveVertex(40,300);
		curveVertex(50,height);
	endShape(CLOSE);
	rect(30,height - 50, 100, height, 5);
}

function drawDog() {
	fill("white");
	noStroke();
	//head
	circle(400,340,50);
	//body
	fill("white")
	ellipse(400,400,60,100);
	//tail
	fill("black");
	beginShape();
		vertex(395,445);
		curveVertex(405,460);
		vertex(375,470);
		curveVertex(415,460);
		vertex(405,450);
	endShape(CLOSE);
	//ears
	push();
	translate(32,-20);
	quad(350,340,355,370,335,350,347,345);
	pop();
	push();
	translate(287,-20);
	translate(width,0);
	scale(-1,1);
	quad(350,340,355,370,335,350,347,345);
	pop();
}

function drawLegs() {
	//legs
	fill("black");
	rect(370,400,20,50,40);
	push();
	translate(40,0);
	rect(370,400,20,50,40);
	pop();
}

function drawGrid() {
	stroke("white");
	strokeWeight(.5);
	for (var yShift = 0; yShift < height/2; yShift += 10){
		line(0,height/2 + yShift,width,height/2 + yShift);
	}
	for (var xShift = -width*40; xShift < width*40; xShift += 60){
		line(width/2,height/2,xShift,height);
	}
}

function poleDraw() {
	noStroke();
	fill("black");
	//trunk
	push();
	translate(0,-this.tall);
	rect(this.x,height/2,this.thickness, this.tall);
	//beams
	for (var i = 0;i < this.beamNumber; i++){
		rect(this.x - 20,height/2, 40, this.thickness/2);
		translate(0, this.thickness);
	}
	pop();
}

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

function newPole() {
	var newPoleProb = .7;
	if (random(0,1) < newPoleProb){
		telephonePoles.push(makePoles(width,random(1,5),random(50, height/2 - 70),
			floor(random(1,4))));
	}
}

function removePole() {
	var polesToKeep = [];
	for (var i = 0; i < telephonePoles.length; i++){
		if(telephonePoles[i].x > 0){
			polesToKeep.push((telephonePoles[i]));
		}
	}
	telephonePoles = polesToKeep;
}

function removeImage() {
	var imageKeep = [];
	for (var i = 0; i < showImage.length; i++){
		if(showImage[i].x > 0) {
			imageKeep.push(showImage[i]);
		}
	}
	showImage = imageKeep;
}

function newImage() {
	var newImageProb = .009;
	if (random(0,1) < newImageProb){
		showImage.push(makeImages(width,random(130,310)));
	}
}
function makePoles(poleX, poleThick, poleHeight,poleBeam) {
	var telephonePole = {x: poleX, thickness: poleThick,
				speed: -1.0, drawPole: poleDraw,
				tall: poleHeight, beamNumber: poleBeam,
				move: poleMove}
	return telephonePole;
}

function imageDisplay(){
	image(images[this.chooseImage],this.x,this.y);
}

function imageMove(){
	this.x += this.speed;
}
function makeImages(imageX,imageY) {
	var m = {x: imageX, y: imageY,
			speed: random(-6.0,-1.0),
			chooseImage: floor(random(0,images.length)),
			drawImage: imageDisplay, moveImg: imageMove};
	return m;
}

function drawMountain() {
	noStroke();
	fill(0,100);
	for( var i = 0; i < width/5; i++){
	beginShape();
		vertex(0,height/2);
		for( var i = 0; i <= width/5; i++){
			vertex(5*i,mountainValue[i]);
			vertex(5*(i+1),mountainValue[i+1]);
		}
		vertex(width,height/2);
	endShape(CLOSE);
	}
}

function moveMountain() {
	mountainValue.shift();
	var n = noise(noiseParam);
	var value = map(n,0,1,0,height/2);
	mountainValue.push(value);
	noiseParam += noiseStep;
}

Looking Outwards 11

A project that I find inspiring is the Ideogenetic Machine (2011) by Nova Jiang. The project is an installation that uses a custom software to combine the artist’s drawings with portraits of people interacting with the installation. The installation features a camera that captures images of the people and draws them into panels of the comic. I admire this installation because it elevates any person into the hero of a unique story. With this installation, anybody can be the protagonist of an epic tale.

Nova Jiang is an artist that creates sculptures and installations, many of which are interactive. She studied at UCLA to get her Master of Fine Arts in Media Art. She currently works in Los Angeles, but has exhibited her work throughout the world.

Image created by Nova Jiang’s Ideogenetic Machine

Project 11: Generative Landscape (Among Us)

For this project, I wanted to make my landscape like you are scrolling through the cafeteria in the Among Us game with different crewmates (dead or alive) moving past you.

amongus
var diams = [];
var lastOdd = false;
var crewMate = makeCharacter(160, 250);
var buddies = [];


function setup() {
    createCanvas(400, 600);
    background(165,167,154);
    //set up the grid for the cafeteria floor tiles
    for (var row=0; row < 7; row++){
    	d_row = []
    	if (row % 2 == 0) {
    		for (var col=0; col < 4; col++){
    			if (col % 2 == 0) {
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    			else {
    				d_row.push(bigDiamond(col*105+35, row*105+35)) 
    			}
    		}
    		diams.push(d_row)
    	}
    	else {
    		for (var col=0; col < 5; col++){
    			if (col % 2 == 0){
    				d_row.push(bigDiamond(col*105+35, row*105+35))
    			}
    			else{
    				d_row.push(smallDiamond(col*105, row*105+35))
    			}
    		}
    		diams.push(d_row)
    	}
    }
    //set up the array for the crew members that appear
    for (var i=0; i < 3; i++) {
    	buddies[i] = (makeCrew());
    }
    frameRate(8);
}

function draw() {
	background(165,167,154);
	displayDiamond();
	updateFloor();
	elimRow();
	updateRow();
	crewMate.draw();
	crewMate.update();
	drawbuddies();
	removebuddies();
	addMate();
	updatebuddies();
}
//update the among us character function drawn so the guy looks like he is walking
function updateCharacter(){
	if (this.pos == 5){
		this.pos = 1;
	}
	else {
		this.pos += 1;
	}
}
//display character with x, y positions and color associated to them
function drawCharacter() {
	if (this.pos == 1) {
		push();
		translate(this.charx, this.chary);
		AmongUs1(color(this.col));
		pop();
	}
	else if (this.pos == 2) {
		push();
		translate(this.charx, this.chary);
		AmongUs2(color(this.col));
		pop();
	}
	else if (this.pos == 3) {
		push();
		translate(this.charx, this.chary);
		AmongUs3(color(this.col));
		pop();
	}
	else if (this.pos == 4) {
		push();
		translate(this.charx, this.chary);
		AmongUs4(color(this.col));
		pop();
	}
	else {
		push();
		translate(this.charx, this.chary);
		AmongUs5(color(this.col));
		pop();
	}
}

//make the guy an object
function makeCharacter(x, y) {
	var c = getColor();
	var guy = {charx: x, chary: y, pos: 1, update: updateCharacter, draw: drawCharacter, col: c}
	return guy;
}

//display crew with x, y positions and color associated to them
function drawCrew() {
	if (this.fig == 0) {
		if (this.pos == 1) {
			push();
			translate(this.charx, this.chary)
			AmongUs1(color(this.col));
			pop();
		}
		else if (this.pos == 2) {
			push();
			translate(this.charx, this.chary)
			AmongUs2(color(this.col));
			pop();
		}
		else if (this.pos == 3) {
			push();
			translate(this.charx, this.chary)
			AmongUs3(color(this.col));
			pop();
		}
		else if (this.pos == 4) {
			push();
			translate(this.charx, this.chary)
			AmongUs4(color(this.col));
			pop();
		}
		else {
			push();
			translate(this.charx, this.chary)
			AmongUs5(color(this.col));
			pop();
		}
	}
	else {
		push();
		translate(this.charx, this.chary)
		Dead1(color(this.col));
		pop();
	}
}
//updates crewmate positions with different speeds (to go down canvas if walking and up if dead)
function updateCrew() {
	if (this.fig == 0) {
		this.chary += this.speed;
		if (this.pos == 5) {
			this.pos = 1;
		}
		else {
			this.pos += 1
		}
	}
	else {
		this.chary -= this.speed;
	}
}
//choose a random x position for newly generated crewmates
function getX() {
	var x = random(20, 330)
	if (x >= 160) {
		x += 70;
	}
	else {
		x -= 20;
	}
	return x;
}
//choose starting position at top of canvas for walking crewmates and bottom for dead crewmates so it looks like they are all moving with the screen
function start(f) {
	if (f == 0) {
		return 0
	}
	else {
		return 600
	}
}
//return a random speed from the array, to be assigned to individual crewmate
function getVelocity(status) {
	if (status == 0){
		return Math.floor(random(1,6));
	}
	else {
		return 5;
	}
}
//return a random color from the array, to be assigned to individual crewmate
function getColor() {
	var cols = ['red', 'orange', 'yellow', 'limegreen', 'green', 'blue', 'cyan', 'hotpink', 'brown', 'gray', 'white'];
	var index = Math.floor(Math.random() * cols.length)
	return cols[index];
}

//assign object properties to the crew (crewmates onscreen)
function makeCrew() {
	var x = getX();
	var f = Math.floor(random(0,2));
	var y = start(f);
	var v = getVelocity(f);
	var c = getColor();
	var crew = {charx: x, chary: y, speed: v, update: updateCrew, pos: 1, fig: f, draw: drawCrew, col: c}
	return crew
}
//draw new crewmates
function drawbuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].draw();
	}
}

function updatebuddies() {
	for (var i=0; i < buddies.length; i++){
		buddies[i].update();
	}
}
//remove crewmates as they pass offscreen
function removebuddies() {
	keep = []
	for (var i=0; i < buddies.length; i++){
		if (buddies[i].chary +600 > 0) {
			keep.push(buddies[i])
		}
	}
	buddies = keep;
}
//add new crewmates with a probability of 2%
function addMate() {
	var threshold = 0.02
	if (random(0,1) < threshold) {
		buddies.push(makeCrew())
	}
}
//draw all the stages of walking for one crewmate
function AmongUs1(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(20,9);
	curveVertex(15,29);
	curveVertex(15,64);
	curveVertex(21,77);
	curveVertex(32,75);
	curveVertex(33,63);
	curveVertex(39,63);
	curveVertex(42,75);
	curveVertex(52,72);	//front of foot
	curveVertex(57,60);
	curveVertex(56,42);
	curveVertex(59,24);
	curveVertex(50,10);
	curveVertex(35,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}

function AmongUs2(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(15,57);
	curveVertex(5,68);
	curveVertex(19,78);
	curveVertex(34,63);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(22,6);
	curveVertex(15,30);
	curveVertex(15,56);
	curveVertex(24,65);
	curveVertex(34,65);
	curveVertex(42,66);
	curveVertex(55,79);
	curveVertex(68,70);
	curveVertex(52,59);	//front of foot
	curveVertex(55,47);
	curveVertex(55,34);
	curveVertex(58,21);
	curveVertex(47,7);
	curveVertex(33,2);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs3(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(46,56);
	curveVertex(48,73);
	curveVertex(19,72);
	curveVertex(19,62);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(19,10);
	curveVertex(15,35);
	curveVertex(17,61);
	curveVertex(25,68);
	curveVertex(28,75);
	curveVertex(24,83);
	curveVertex(36,82);
	curveVertex(41,71);
	curveVertex(39,60);	//front of foot
	curveVertex(49,58);
	curveVertex(57,50);
	curveVertex(56,35);
	curveVertex(58,25);
	curveVertex(54,14);
	curveVertex(45,8);
	curveVertex(32,4);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs4(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(40,60);
	curveVertex(56,79);
	curveVertex(66,65);
	curveVertex(54,52);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(25,4);
	curveVertex(16,24);
	curveVertex(15,54);
	curveVertex(19,61);
	curveVertex(8,61);
	curveVertex(5,74);
	curveVertex(19,76);
	curveVertex(28,69);
	curveVertex(32,63);	//front of foot
	curveVertex(45,63);
	curveVertex(56,56);
	curveVertex(58,38);
	curveVertex(58,26);
	curveVertex(54,12);
	curveVertex(43,3);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
function AmongUs5(c) {
	stroke(0);
	strokeWeight(5);
	fill(c)
	//backpack
	beginShape();
	curveVertex(16,23);
	curveVertex(4,28);
	curveVertex(4,57);
	curveVertex(18,62);
	endShape(CLOSE);
	//back leg
	beginShape();
	curveVertex(32,61);
	curveVertex(34,76);
	curveVertex(49,76);
	curveVertex(50,56);
	endShape(CLOSE);
	//body
	beginShape();
	curveVertex(24,3);
	curveVertex(17,24);
	curveVertex(16,51);
	curveVertex(15,59);
	curveVertex(23,59);
	curveVertex(10,64);
	curveVertex(12,72);
	curveVertex(32,70);
	curveVertex(37,62);	//front of foot
	curveVertex(49,62);
	curveVertex(56,54);
	curveVertex(58,34);
	curveVertex(58,23);
	curveVertex(54,13);
	curveVertex(47,5);
	curveVertex(35,1);
	endShape(CLOSE);
	//goggles
	fill(204,227,238);
	beginShape();
	curveVertex(31,16);
	curveVertex(56,18);
	curveVertex(59,29);
	curveVertex(55,33);
	curveVertex(32,33);
	curveVertex(24,24);
	endShape(CLOSE);
}
//draw a dead crewmate
function Dead1(c) {
	stroke(0);
	strokeWeight(5);
	fill(255);
	//bone sticking out
	beginShape();
	curveVertex(33,39);
	curveVertex(32,29);
	curveVertex(27,22);
	curveVertex(32,18);
	curveVertex(35,23);
	curveVertex(37,17);
	curveVertex(41,21);
	curveVertex(38,32);
	curveVertex(38,42);
	endShape(CLOSE);
	fill(c);
	//arm
	beginShape();
	curveVertex(2,39);
	curveVertex(12,34);
	curveVertex(20,38);
	curveVertex(18,60);
	curveVertex(6,59);
	endShape(CLOSE);
	//half body
	beginShape();
	curveVertex(15,37);
	curveVertex(28,40);
	curveVertex(34,37);
	curveVertex(44,40);
	curveVertex(58,38);
	curveVertex(57,66);
	curveVertex(45,74);
	curveVertex(41,62);
	curveVertex(35,62);
	curveVertex(32,74);
	curveVertex(17,73);
	curveVertex(14,49);
	endShape(CLOSE);

}
//draw the cafeteria floor
//make small diamond tile object
function smallDiamond(x, y) {
	var diamond = {diamondx: x, diamondy: y, diamondw: 70, diamondh: 35, speed: -5.0, draw: drawDiamond, update: updateDiamond}
	return diamond;
}
//draw small diamond
function drawDiamond() {
	noStroke();
	fill(133,135,124);
	beginShape();
	vertex(this.diamondx,this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy-this.diamondh);
	vertex(this.diamondw+this.diamondx, this.diamondy);
	vertex(this.diamondx+this.diamondw/2,this.diamondy+this.diamondh);
	endShape(CLOSE);
}
//update position of the tile with speed
function updateDiamond() {
	this.diamondy += this.speed;
}
//make big diamond tile object
function bigDiamond(cx, cy) {
	var bigdiam = {leftD: smallDiamond(cx-70, cy), topD: smallDiamond(cx-35, cy-35), rightD: smallDiamond(cx, cy), bottomD: smallDiamond(cx-35, cy+35), draw: drawBigDiamond, update: updateBigDiamond}
	return bigdiam;
}
//make big diamond tile from smaller diamond tiles
function drawBigDiamond() {
	this.leftD.draw()
	this.topD.draw()
	this.rightD.draw()
	this.bottomD.draw()
}
//update position of big diamond tiles
function updateBigDiamond() {
	this.leftD.update();
	this.topD.update();
	this.rightD.update();
	this.bottomD.update();
}
//draw the diamonds
function displayDiamond() {
	for (var i=0; i < diams.length; i++){
		for (var j=0; j < diams[i].length; j++){
			diams[i][j].draw();
		}
	}
}
//update the positons of the diamonds as the screen scrolls
function updateFloor() {
	for (var i=0; i < diams.length; i++) {
		for (var j=0; j < diams[i].length; j++) {
			diams[i][j].update();
		}
	}
}
//get rid of rows that have slipped offscreen
function elimRow(){
	keepRow = false;
	for (var i=0; i < diams[0].length; i++) {
		if (lastOdd == false){
			if (i % 2 == 0) {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0) {
					keepRow = true
				}
			}
			else {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
		}
		else {
			if (i % 2 == 0) {
				if (diams[0][i].bottomD.diamondy + diams[0][i].bottomD.diamondh > 0){
					keepRow = true
				}
			}
			else {
				if (diams[0][i].diamondy + diams[0][i].diamondh > 0){
					keepRow = true
				}
			}
		}
	}
	if (keepRow == false){
		diams.shift();
	}
}
//update the new rows added such that they match the original cafeteria tile pattern
function updateRow() {
	if (diams.length < 7){
		n_row = []
		if (lastOdd == true){
			for (var col=0; col < 4; col++){
				if (col % 2 == 0) {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    		else {
	    			n_row.push(bigDiamond(col*105+35, 665)) 
	    		}
			}
			diams.push(n_row);
			lastOdd = false;
		}
		else {
			for (var col=0; col < 5; col++){
	    		if (col % 2 == 0){
	    			n_row.push(bigDiamond(col*105+35, 665))
	    		}
	    		else {
	    			n_row.push(smallDiamond(col*105, 665))
	    		}
	    	}
	    	diams.push(n_row);
	    	lastOdd = true;
		} 
	}
}

LO-11-Women Practitioners

Jenny Sabin Studio, Ada, 2018-2019. 

Jenny Sabin, Ada, 2018-2019. Source.

Ada is a project by Jenny Sabin’s studio for the Microsoft Research Artist in Residence program. The project was named after Ada Lovelace, one of the first computer programmers and a woman as well. This project uses AI and architecture to create an interactive pavilion using responsive photo-luminescence. The project uses 3d printed nodes to connect fiberglass rods, with a knitted main structure that contains the responsive aspects of the pavilion.  

This project was fascinating to me in its manipulation of what architecture tends to be– static. The pavilion constantly changes in response to the clients it is made for–humans. Thus, the pavilion explores the bounds on which architecture can morph in real time as a response to human stimulus and movements. By integrating the light responsive aspect, the pavilion has yet another transformative variable that generates constant new experiences of Ada. The exploration Jenny Sabin does in this project introduces the possibilities of architecture that become fluid and almost free form to an extent using real time data sets that respond to the environment. It is inspiring in the ways Jenny Sabin uses Ada and artificial intelligence to connect humans to material forms and thus forming an intimate conversation between the pavilion and us where we are able to communicate through interpreted data.

Looking Outwards 11: A Focus on Women Practitioners

The artist I chose to research this week is Karolina Sobecka. Sobecka was born in Warsaw, Poland and has been known to work across many disciplines, specifically synthesizing art and science. She received her BFA from the School of the Art Institute of Chicago, and her MFA in Experimental Animation and Integrated Media from the California Institute of the Arts. Much of her work is interventionist or interactive in nature, serving to promote environmental and social activism. One project of hers I focused on was entitled “Cloud Machine.” This is a small device sent into the atmosphere to develop and disperse miniature clouds in our atmosphere.

Karolina Sobecka’s “Cloud Machine” as it creates clouds through water vapor dispersal (2014).

This project is quite interesting to me and it creates a unique juxtaposition between manmade and natural processes in a way that is almost performative. Further, it is a also a legitimate response to a climate issue, as scientists have proposed developing larger-scale, but conceptually similar devices to achieve the same effect of global cooling. I appreciate how Sobecka uses her artistic and engineering skills to address a relevant issue.

Project 11 – Generative Landscape

For this project, I wanted to create a bustling city environment. I created an iPhone in the middle with someone pressing the record button, imagining that they are in a driving car and want to take in the city.

sketch
/* 
 * Amy Lee 
 * amyl2
 * Section B 
 */ 

// Variables for people 
var px = [];
var py = [];
var pdx = [];
var pc = [];
var skin = []; 
var pWidth = []; 
var pHeight = []; 

// Variables for clouds 
var cx = [];
var cy = [];
var cdx = [];
var cWandH = []; 

var buildings = [];
var houses = []; 

function preload() {
    // loading image files 
    finger = loadImage("https://i.imgur.com/DPWPwwe.png"); 
    police = loadImage("https://i.imgur.com/9xYWNnM.png"); 
    taxi = loadImage("https://i.imgur.com/ywwvyoP.png")
} 

function setup() {
    createCanvas(480,480); 
    frameRate(20); 

    // Finger 
    fin = new Object(); 
    fin.image = finger; 
    fin.x = 200;
    fin.y = 460; 
    fin.dx = 1; 
    fin.dy = 1; 
    fin.width = 290; 
    fin.height = 200; 
    fin.move = fingerMove; 
    fin.draw = fingerDraw;

    pol = new Object(); 
    pol.image = police; 
    pol.x = 700; 
    pol.y = 255; 
    pol.dx = 15; 
    pol.width = 240; 
    pol.height = 240; 
    pol.move = polMove; 
    pol.draw = polDraw; 

    tax = new Object(); 
    tax.image = taxi; 
    tax.x = 900; 
    tax.y = 275; 
    tax.dx = 10; 
    tax.width = 230
    tax.height = 230 
    tax.move = taxiMove; 
    tax.draw = taxiDraw; 

    // People
    for (var i = 0; i < 10; i ++){
        px[i] = random(25, width - 25); 
        py[i] = 350; 
        pdx[i] = random(1,3); 
        pc[i] = color(random(255), random(255), random(255));
        skin[i] = color(random(55,200), 80, 90); 
        pWidth[i] = random(20,50); 
        pHeight[i] = random(30,80); 
    }

    // Clouds 
    for (var i = 0; i < 5; i ++){
        cx[i] = random(20,460); 
        cy[i] = random(30,90); 
        cdx[i] = 2; 
        // cloud width and height 
        cWandH[i] = random(20,30); 
    }

    // Building 
    for (var j = 0; j < 5; j ++){
        var bx = random(width); 
        buildings[j] = makeBuildings(bx); 
    }

    // House 
    for (var k = 0; k < 3; k ++){
        var hx = random(width); 
        houses[k] = makeHouses(hx); 
    }

    frameRate(10); 
} 

function draw() {
//  background(130,208,218); 
    background(200,241,208);

    sidewalk(); 
    road(); 

    // Draw clouds, make them move right, and reappear if they move off canvas 
    for (var i = 0; i < 5; i++){
       cloud(cx[i], cy[i], cdx[i], cWandH[i], cWandH[i]);
       cx[i] += cdx[i]; 

       if (cx[i] > width + 10){
           cx[i] = -40; 
       }
   }

    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 

    updateAndDisplayHouses();
    removeHousesThatHaveSlippedOutOfView();
    addNewHousesWithSomeRandomProbability(); 

    // Make buildings reappear if they go off the right side of the canvas 
    // Reappear on the left side 
    for (var j = 0; j < buildings.length; j++){
        if (buildings[j].x > width + 20) {
           buildings[j].x = -60; 
       }
   }

    // Make houses reappear if they go off the right side of the canvas 
    // Reappear on the left side 
    for (var k = 0; k < houses.length; k ++){
        if (houses[k].x > width + 20) {
            houses[k].x = -100; 
        }
    }

    // Make people reappear if they go off the right side of the canvas 
    // Reappear on the left side     
    for (var i = 0; i < 10; i ++){
        people(px[i], py[i], pdx[i], pc[i],skin[i],pWidth[i], pHeight[i]); 
        px[i] += pdx[i]; 

        if(px[i] > width+50){
           px[i] = -50; 
        }
    }

    pol.draw(); 
    pol.move(); 

    tax.draw(); 
    tax.move();  

    drawiPhone();  
    fin.draw(); 
    fin.move(); 

    if (frameCount >= 60){
    record(); 
    }

}

 function people(px, py, pdx, pc,skin, pWidth, pHeight){
    fill(pc); 
    noStroke(); 
    // Shirt 
    ellipse(px, py, pWidth, pHeight); 
    // Head 
    fill(skin); 
    ellipse(px,py-25,20,20); 
 }


function fingerDraw(){
    image(finger, this.x, this.y, this.width, this.height); 
}

// Move finger to record button 
function fingerMove(){ 
    if (fin.x > 142 & this.y > 378){
    this.x -= this.dx; 
    this.y -= this.dy; 
    }
}

function polDraw(){
    image(police, this.x, this.y, this.width, this.height); 
}

function polMove(){
    this.x -= this.dx; 
    if (this.x <= -800){
        this.x = 500; 
    }
}

function taxiDraw(){
    image(taxi, this.x, this.y, this.width, this.height); 
}

function taxiMove(){
    this.x -= this.dx; 
    if (this.x <= -1000){
        this.x = 500; 
    }
}

//              BUILDINGS                   //
function updateAndDisplayBuildings(){
    // Update the building's positions, and display them.
    for (var j = 0; j < buildings.length; j++){
        buildings[j].move();
        buildings[j].display();
    }
}

function removeBuildingsThatHaveSlippedOutOfView(){
    var buildingsToKeep = [];
    for (var j = 0; j < buildings.length; j++){
        if (buildings[j].x + buildings[j].breadth > 0) {
            buildingsToKeep.push(buildings[j]);
        }
    }
    buildings = buildingsToKeep; // remember the surviving buildings
}

function addNewBuildingsWithSomeRandomProbability() {
    // With a very tiny probability, add a new building to the end.
    var newBuildingsLikelihood = .0006; 
    if (random(0,1) < newBuildingsLikelihood) {
        buildings.push(makeBuildings(width));
    }
}

// Make buildings move to right 
function buildingsMove() {
    this.x += this.speed;

}

function buildingsDisplay() {
    var floorHeight = 30;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke(); 
    fill(this.col); 
    translate(this.x, height - 40);
    // Drawing the actual buildings
    rect(0, -bHeight-110, this.breadth, bHeight);
//    fill(18, 126, 190);  
    // Windows 
    for (var i = 0; i < this.nFloors; i++) {
        fill(18, 126, 190);  
        rect(5, -130 - (i * floorHeight), this.breadth - 10, 10);
    }
    // Building antennae 
    stroke(18,126,190); 
    strokeWeight(2); 
    line(5,-bHeight-110,5,-bHeight-120); 
    line(10,-bHeight-110,10, -bHeight-130); 
    noStroke(); 
    pop();
}

function makeBuildings(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 60,
                speed: 4.0,
                col: color(121,204,221),
                nFloors: round(random(5,10)),
                move: buildingsMove,
                display: buildingsDisplay}
    return bldg;
}

//              HOUSES                   //
function updateAndDisplayHouses(){
    for (var k = 0; k < houses.length; k++){
        houses[k].move(); 
        houses[k].display(); 
    }
}

function makeHouses(birthLocationX){
    var houses = {x: birthLocationX,
                 breadth: 100,
                 speed: 4.0, 
                 col1: color(232,175,104),
                 col2: color(182,110,125),
                 nFloors: round(random(2,4)), 
                 move: housesMove, 
                 display: housesDisplay}
    return houses; 
}

function removeHousesThatHaveSlippedOutOfView() {
    var housesToKeep = []; 
    for (var k = 0; k < houses.length; k++){
        if (houses[k].x + houses[k].breadth > 0) {
            housesToKeep.push(houses[k]); 
        }
    }
    houses = housesToKeep; 
}


function addNewHousesWithSomeRandomProbability() {
    var newHousesLikelihood = .0001; 
    if (random(0,1) < newHousesLikelihood) {
        houses.push(makeHouses(width)); 
    }
}

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

function housesDisplay() {
    var floorHeight = 20; 
    var hHeight = this.nFloors * floorHeight; 
    push(); 
    noStroke(); 
    fill(this.col1); 
    translate(this.x, height-30); 
    rect(0, -hHeight - 110, this.breadth, hHeight); 
    fill(this.col2); 
    triangle(0, -hHeight - 110, this.breadth, -hHeight - 110, this.breadth/2, -hHeight - 140); 
    rect(30, -hHeight - 90, this.breadth - 60, hHeight - 20); 
    fill(252, 197, 132); 
    ellipse(50, -hHeight - 110 , 8, 8); 
    pop(); 
}

function cloud(cx, cy, cdx, cWandH, cWandH){
    push(); 
    stroke(255); 
    strokeWeight(20); 
    line(cx, cy, cx+30, cy); 
    pop(); 
    fill(255);
    ellipse(cx,cy,cWandH, cWandH); 
    ellipse(cx+10,cy-10,cWandH, cWandH); 
    ellipse(cx+20,cy,cWandH, cWandH); 
}

function drawiPhone(){
    fill(0); 
    // top rectangle
    rect(130,40,200,60); 
    // left side 
    rect(130,40,20,400); 
    // right side 
    rect(330,40,20,400); 
    // bottom rectangle 
    rect(130,380,200,60) 
    // home button 
    fill(255); 
    ellipse(236,416,31,31); 
    fill(33);
    ellipse(240,416,33,33);  
    // small rectangle at top 
    fill(58); 
    rect(215,65,50,10); 
    // glass shine 
    push(); 
    stroke(255); 
    strokeWeight(10); 
    line(160,140,200,110); 
    line(160,170,240,110); 
    line(240,360,310,305); 
    line(272,370,315,336); 
    pop(); 
} 

function sidewalk(){
    noStroke(); 
    fill(236,205,158); 
    rect(0,330,480,70); 
    fill(132,64,64); 
    rect(0,390,480,10); 
}

function road(){
    fill(180,145,126); 
    rect(0,400,480,80); 
}

// REC button on iPhone 
function record(){
    fill(255,0,0); 
    ellipse(270,124,13,13); 
    textSize(20);     
    text("REC", 280, 130); 
}

















Project 11: Landscape

peachsketch
var Stars = [];
var Planets = [];
var asteroids = [];
var terrain = [];
var noiseParam = 0;
var noiseStep = 0.007;

function setup() {
    createCanvas(480, 300); 
    // create an initial collection of stars, planets, and asteroids
    for (var i = 0; i < 100; i++){
        var rx = random(width);
        var ry = random(height);
        Stars[i] = makeStar(rx, ry);
    }
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        var ry = random(height);
        Planets[i] = makePlanet(rx, ry);
    }
    for (var i = 0; i < 2; i++){
        var rx = random(width);
        var ry = random(height);
        asteroids[i] = makePlanet(rx, ry);
    }
//set up noise function to create scrolling planet terrain
  for (i = 0; i<=width/5; i++){
    var n = noise(noiseParam);
    var value = map(n, 0,1,height/2, height)
    terrain.push(value)
    noiseParam+= noiseStep
  }

    frameRate(20);
}

function draw() {
    background(0); 

    updateStars();
    removeStars();
    addNewStars(); 

    updatePlanets();
    removePlanets();
    addNewPlanets(); 

    updateasteroids();
    removeasteroids();
    addNewasteroids(); 

mars();
insideSpaceship();
astronaut();
}

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

function removeStars(){
    var StarsToKeep = [];
    for (var i = 0; i < Stars.length; i++){
        if (Stars[i].x + Stars[i].breadth > 0) {
            StarsToKeep.push(Stars[i]);
        }
    }
    Stars = StarsToKeep; 
}


function addNewStars() {
    var newStarLikelihood = 0.2; 
    if (random(0,1) < newStarLikelihood) {
        Stars.push(makeStar(width, random(height)));
    }
}

// method to update position of Star every frame
function StarMove() {
    this.x += this.speed;
}
    
// draw Stars
function StarDisplay() {
    fill(255);  
    push();
    translate(this.x, this.y);
    ellipse(0, this.breadth, this.nsize)
    pop();
}

function makeStar(birthLocationX, birthLocationY) {
    var star = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -2.0,
                nsize: round(random(1,8)),
                move: StarMove,
                display: StarDisplay}
    return star;
}

//view scrolling landscape from inside spaceship
function insideSpaceship(){
	noStroke()
fill(151, 163, 194)
	rect(0, height/9*7, width, height);
	rect(0,0, width, height/9);
	rect(0,0, width/9, height)
	rect(width/9*8, 0, width, height);
noFill();
strokeWeight(10);
stroke(61, 81, 133)
beginShape();
	vertex(width/9, height/9);
	vertex(width/9*8, height/9);
	vertex(width/9*8, height/9*7);
	vertex(width/9, height/9*7);
	vertex(width/9, height/9);
endShape();
strokeWeight(2);
var lx = 80;
var ly = 10;
var pt = 15
for (i=0; i<4; i++){
	line(lx, 0, lx, height/9)
	line(lx, height/9*7, lx, height)
	lx+=110
	line(0, ly, width, ly)
	ly += 250
	}
line(0, 120, width/9, 120)
line(width/9*8, 120, width, 120)
strokeWeight(7)
	point(width/9 + 10, height/9 +10)
	point(width/9 + 10, height/9*7 - 10)
	point(width/9*8-10, height/9 +10)
	point(width/9*8-10, height/9*7 - 10)
noStroke();
}

//draw astronaut looking out spaceship window
function astronaut(){
fill(255)
	ellipse(70, 230, 100);
	rect(30, 240, 80,100)
fill(143, 150, 168)
	ellipse(85,225, 60)
stroke(143, 150, 168)
strokeWeight(4);
	line(85, 270, 85, height)
noFill()
stroke(181, 199, 247)
	ellipse(85,225, 60)
noStroke();
}

function updatePlanets(){
    for (var i = 0; i < Planets.length; i++){
        Planets[i].move();
        Planets[i].display();
    }
}

function removePlanets(){
    var PlanetsToKeep = [];
    for (var i = 0; i < Planets.length; i++){
        if (Planets[i].x + Planets[i].breadth > 0) {
            PlanetsToKeep.push(Planets[i]);
        }
    }
    Planets = PlanetsToKeep; 
}

function addNewPlanets() {
    var newPlanetLikelihood = 0.01; 
    if (random(0,1) < newPlanetLikelihood) {
        Planets.push(makePlanet(width, random(height)));
    }
}

function PlanetMove() {
    this.x += this.speed;
}
    
function PlanetDisplay() {
    fill(this.clr);  
    push();
    translate(this.x, this.y);
    ellipse(0, this.breadth, this.nsize)
    pop();
}

function makePlanet(birthLocationX, birthLocationY) {
    var Planet = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                clr: color(random(1, 255), random(1, 255), random(1, 255)),
                speed: -1.0,
                nsize: round(random(10,50)),
                move: PlanetMove,
                display: PlanetDisplay}
    return Planet;

}

function updateasteroids(){
    for (var i = 0; i < asteroids.length; i++){
        asteroids[i].move();
        asteroids[i].display();
    }
}

function removeasteroids(){
    var asteroidsToKeep = [];
    for (var i = 0; i < asteroids.length; i++){
        if (asteroids[i].x + asteroids[i].breadth > 0) {
            asteroidsToKeep.push(asteroids[i]);
        }
    }
    asteroids = asteroidsToKeep;
}

//asteroids appear the least frequently - "surprise element"
function addNewasteroids() {
    var newasteroidLikelihood = 0.005; 
    if (random(0,1) < newasteroidLikelihood) {
        asteroids.push(makeasteroid(width, random(height)));
    }
}

//make the asteroid move in both x direction and y direction
function asteroidMove() { 
    this.x += this.speed;
    this.y += this.speedy;
}
    
// draw asteroids
function asteroidDisplay() {
    fill(random(255), random(255), random(255));  
    push();
    translate(this.x, this.y);
    ellipse(0, 5, this.nsize)
    beginShape();
    	vertex(5,5);
    	vertex(15,5);
    	vertex(9,7);
    	vertex(15,10);
    	vertex(9,13);
    	vertex(10,15);
    	vertex(5,15);
    endShape();
    pop();
}

function makeasteroid(birthLocationX, birthLocationY) {
    var asteroid = {x: birthLocationX,
                breadth: 50,
                y:birthLocationY,
                speed: -5.0,
                speedy: -1.0,
                nsize: 10,
                move: asteroidMove,
                display: asteroidDisplay}
    return asteroid;
}
//generate landscape of planet in foreground, placed low on screen so low frequency of apearance
function mars (){
    var n = noise(noiseParam);
    var value = map(n, 0,1,height/5*3, height)
    terrain.push(value)
    terrain.shift();
    noiseParam+= noiseStep
  for (i = 0; i<=width/5; i++){
    noStroke();
    fill(222, 106, 11)
    beginShape();
    vertex(0, height)
    vertex(width, height)
    vertex(i*5, terrain[i])  
    endShape();
  if (terrain[i] < terrain[i+1] & terrain[i] < terrain[i-1]){
  drawAlien(i)
  }
}
}

  function drawAlien(i){ 
  fill(0,255,0)

  ellipse(i*5, terrain[i]-10, 10);
  stroke(0,255,0)
  strokeWeight(2);
    line(i*5,terrain[i]-20, i*5, terrain[i]-10)
   strokeWeight(10)
    ellipse(i*5, terrain[i]-5, 5)
   noStroke()
    fill(255)
   ellipse(i*5, terrain[i]-5, 8)
   fill(0)
     ellipse(i*5, terrain[i]-5, 5)

}

For this assignment, I had a lot of fun deciding what I wanted my landscape to be. However, I found that there were a lot of components that I wanted to introduce, but wasn’t able to efficiently generate them in a concise amount of code. I ended up utilizing methods from different classes to generate different aspects of my landscape – for example, objects in the background similar to what was provided in the sample code, as well as usage of the noise function for objects in the foreground. I was partially inspired by the game Among Us as well as a music video called “Where the Sea Sleeps.”

Looking Outwards – 11

One project that I admire is “Bot Party,” helmed by Phoenix Perry and aided by Freida Abtan, both women artists. The project is a game that requires the players to help the robots communicate with each other through audio interaction. They utilize a ‘bot to skin and skin to bot’ communication protocol – the user physically connects the bots so that they may send encoded messages to each other. I admire that the project is both thoughtful in its simplistic message, while simultaneously is efficient as well as aesthetically pleasing. It also utilizes robots for a considerably unique purpose. Phoenix Perry amusingly calls herself a cultural engineer, game designer, instigator, as well as “feminist killjoy.” She was educated at NYU Tandon. I admire her in that while she has evidently found personal success, she has used that success to help others – she founded the Code Liberation Institute, which teaches women how to program games, as well as Dozen Eyes Games, a studio aimed at games and installations that generate social change. She also gives lectures, and in general, her active pursuit of positive change in the world of a male dominated profession is really inspiring.

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.