Month: December 2018
hamster
Jisoo Geum Final Project
I am uploading a zip file instead of the sketch file since the program contains sound.
My final project is an educational program that teaches the user to learn (hopefully) about the Korean alphabet: Hangul. Hangul is very easy to learn because it does not require people to memorize the meaning of each character. Since Hangul is an alphabet system like English, anyone can read without knowing the meaning itself. I only focused on the Consonant letters of Hangul so the alphabets showing up on the program does not make a full word or a letter.
As I was writing the program, I realized how complicated it is to teach a language even though I initially thought Hangul was relatively simple. Thus, I am planning to expand on this project and hopefully make a program that covers not only consonants but also vowels and maybe some simple words.
(My original plan was to make the user draw on top of the text using turtle graphics, but somehow the code didn’t work. I canceled out the turtle graphics part. )
black cat
Final Project-Urban Wildlife-Veronica Wang
In this interactive game/animation:
(click on the canvas first)
Press left arrow to add birds, press right arrow to add chimneys. Bird nests and raccoons will show up according to the added elements. The position of mouseY changes the color of the sky. As more birds are added, bird sound gets louder.
//Veronica Wang
//Section B
//yiruiw@andrew.cmu.edu
//Final Project
var Y_AXIS = 1; //gradient sky axis
var c1, c2; //gradient sky colors
var PREFIX = "https://courses.ideate.cmu.edu/15-104/f2018/wp-content/uploads/2018/12/";
//var PREFIX = "";
var birdSound;
var trainSound;
var bV = 0.2;
var houseList = []; //array of houses
var allTrees = []; //trees
var birdList = []; //birds
var raccoonList = []; //raccoons
var flap = true;
var nestCount = 0;
var birdperNest = 3; //for every three birds draw a nest
var trainList = []; //trains
var rachouseCount = 0;
frameCount = 200;
function preload(){
birdSound = loadSound(PREFIX + "birds.wav");
trainSound = loadSound(PREFIX + "train.wav");
trainSound.setVolume(0.5);
}
function setup() {
createCanvas(500, 300);
//sky colors
c1 = color(244, 248, 255); //light blue
c2 = color(94, 164, 186); //dark teal blue
drawBackground();
//draw houses
for(var i = 0; i < 10; i++) {
var newX = random(80, 420);
var newY = random(120, 200);
if (houseList.length < 1){
houseList.push(makeHouse(newX, newY));
}
else{
while (checkifLess(newX, newY, houseList, 30)){
newX = random(80, 420);
newY = random(120, 200);
}
houseList.push(makeHouse(newX, newY));
}
}
//draw trees
for(var i = 0; i < 40; i++) {
allTrees.push(makeTree());
}
sortTree(allTrees);
sortTree(houseList);
//draw creatures
birdList.push(makeBird(width / 2,height / 2, 15));
raccoonList.push(makeRac(width / 2, height / 2, 5));
}
function draw() {
//play sound
birdSound.setVolume(bV);
if (frameCount % 100 == 0){
birdSound.play();
}
//set volume to be proportional to number of birds
bV = (map(birdList.length, 0, 20, 0, 1));
drawBackground();
drawStairs();
//initial number of artificial nests
nestCount = 0;
rachouseCount = 0;
//raccoon house counter
for (var i = 0; i < houseList.length; i++) {
if (houseList[i].rh){
rachouseCount += 1;
}
}
//add raccoons
if (raccoonList.length < rachouseCount * 2){
raccoonList.push(makeRac(random(0, 500), random(150, 220)));
}
//drawing raccoons and removing them from array if out of canvas
for (var i = 0; i < raccoonList.length; i++) {
raccoonList[i].draw();
raccoonList[i].rx += raccoonList[i].vel;
if (racoutofBound(raccoonList[i])){
raccoonList.splice(i, 1);
i -= 1;
}
}
//draw houses
for (var i = 0; i < houseList.length; i++) {
houseList[i].draw();
}
//draw trees
for (var i = 0; i < allTrees.length; i++){
if (i % 3 == 0){
allTrees[i].draw1();
} else if (i % 3 == 1){
allTrees[i].draw2();
} else {
allTrees[i].draw3();
}
if (allTrees[i].nest){
nestCount += 1;
}
}
drawTracks();
//bird wing flap
if (frameCount % 40 == 0){
flap = !(flap);
}
//if bird is out of canvas, take it out of the array
for (var i = 0; i < birdList.length; i++) {
if (birdoutofBound(birdList[i])){
birdList.splice(i, 1);
i -= 1;
}
}
//draw birds
for (var i = 0; i < birdList.length; i++) {
if (flap){
birdList[i].draw2();
} else {
birdList[i].draw();
}
birdList[i].bx += birdList[i].xvel * noise(1);
birdList[i].by += birdList[i].yvel * noise(1);
};
//adding random movement and scale birds
if (frameCount % 100 == 0){
for (var i = 0; i < birdList.length; i++) {
birdList[i].xvel += random(-3, 3) * (map(pow(2, birdList[i].by / 50), 0, pow(2, 300 / 50), 1, 100)) / 35;
birdList[i].yvel += random(-1, 1) * (map(pow(2, birdList[i].by / 50), 0, pow(2, 300 / 50), 1, 100)) / 35;
}
}
//night sky filter
var darkness = map(mouseY, 0, height, 0, 200);
fill(0, 0, 0, darkness);
noStroke();
rect(0, 0, width, height);
//add nest to empty trees
if (birdList.length > 0 & int(birdList.length / birdperNest) < 40){
if (int(birdList.length / birdperNest) > nestCount){
var seltree = int(random(0, allTrees.length));
while (allTrees[seltree].nest){
seltree = int(random(0, allTrees.length));
}
allTrees[seltree].nest = true;
} else if (int(birdList.length / birdperNest) < nestCount){
var seltree = int(random(0, allTrees.length));
if (allTrees[seltree].nest == true){
allTrees[seltree].nest = false;
}
}
}
//draw train
if (frameCount % 400 == 0) {
trainList.push(makeTrain());
trainSound.play();
}
for (var i = 0; i < trainList.length; i++) {
trainList[i].x -= trainList[i].vel;
trainList[i].draw();
};
if (trainList.length > 0){
if (trainList[0].x < -750){
trainList.splice(0, 1);
}
}
}
//if raccoon is out of canvas
function racoutofBound(bird){
if (bird.rx < 0){
return true;
} else if (bird.rx > width){
return true;
} else if (bird.ry < 0){
return true;
} else if (bird.ry > height){
return true;
}
return false;
}
//if bird is out of canvas
function birdoutofBound(bird){
if (bird.bx < 0){
return true;
} else if (bird.bx > width){
return true;
} else if (bird.by < 0){
return true;
} else if (bird.by > height){
return true;
}
return false;
}
//sort tree order by y position
function sortTree(treelist){
n = treelist.length;
for (var i = 0; i < n; i++){
for (var j = 0; j < n - i - 1; j++){
if (treelist[j].y > treelist[j+1].y){
var temp = treelist[j];
treelist[j] = treelist[j+1];
treelist[j+1] = temp;
}
}
}
}
//draw tree outside of houses
function ispointIn(x, y, house){
var x1 = house.x;
var x2 = house.x + house.w;
var y1 = house.y - house.w / 3;
var y2 = house.y + house.h * house.f;
if (x < x1){
return false;
} else if (x > x2){
return false;
} else if (y < y1){
return false;
} else if (y > y2 + 13){
return false;
}
return true;
}
//goes through list to check if point is outside the boundary
function hListcheck(x, y, list, n){
if (list.length < 1){
return false;
}
if (n < list.length - 2){
return (ispointIn(x, y, list[n]) || hListcheck(x, y, list, n + 1));
} else {
return ispointIn(x, y, list[n]);
}
}
//make sure houses are not overlapping
function checkifLess(x, y, list, mindist){
var chck = false;
for (var i = 0; i < list.length; i++) {
var objdist = dist(x, y, list[i].x, list[i].y);
if (objdist < mindist){
chck = true;
}
}
return chck;
}
//house object
function makeHouse(locX, locY){
var num = 75;
var house = { x: locX,
y: locY,
w: map(pow(2, locY / num), 0, pow(2, 300 / num), 1, 100), //proportionally scale house in the distance
f: floor(random() * 2 + 1), //random number of floors from 1-3
rh: false, //raccoon houses
draw: drawHouse
};
return house;
}
function drawHouse(){
noStroke();
fill(173, 110, 110);
var h = this.w / 2;
rect(this.x, this.y, this.w, h * this.f); //body of house
rect(this.x + this.w * 0.7, this.y - this.w / 3,
this.w / 5, this.w / 3); //chimney
triangle(this.x, this.y,
this.x + this.w / 2, this.y - this.w / 3,
this.x + this.w, this.y); //roof
if(this.f == 1){
//gradient
for (var i = 0; i < this.y / 10; i++) {
var op2 = map(i, 0, 50, 0, 200);
stroke(201, 141, 141, op2);
line(this.x, i * this.y * 0.005 + this.y,
this.x + this.w, i * this.y * 0.005 + this.y);
}
drawWindow(this.x + this.w / 5, this.y + this.w / 6,
this.w * 0.3, this.w / 5);
drawShrub(this.x, this.y + h,
this.w * 0.5, this.w * 0.3);
}else{
//gradient
for (var i = 0; i < this.y / 5; i++) {
var op3 = map(i, 0, 50, 0, 200);
stroke(201, 141, 141, op3);
line(this.x, i * this.y * 0.005 + this.y,
this.x + this.w, i * this.y * 0.005 + this.y);
}
drawWindow(this.x + this.w / 5, this.y + this.w / 6,
this.w * 0.3, this.w / 5);
drawWindow(this.x + this.w / 5, this.y + this.w * 0.6,
this.w * 0.3, this.w / 5);
drawShrub(this.x, this.y + this.w,
this.w * 0.4, this.w * 0.3);
}
if(this.rh){
fill(135, 81, 132);
rect(this.x + this.w,
this.y + h / 5, this.w / 6, (h * this.f) * 0.75);
triangle(this.x + this.w, this.y + h * this.f,
this.x + this.w, this.y + (h * this.f) / 2,
this.x + this.w + this.w / 3, this.y + h * this.f);
}
}
function drawWindow(x, y, w, h){
noStroke();
fill(239, 233, 218);
rect(x, y, w, h);
}
function drawShrub(x, y, w, h){
noStroke();
fill(143, 168, 104);
ellipse(x, y, w, h);
ellipse(x + 5, y, w * 0.8, h * 0.5);
ellipse(x + 3, y - 2, w * 0.8, h * 0.8);
}
function makeTree(){
var num1 = 75;
var tempY = random(120, 200);
var tempX = random(0, 450)
var mult = map(pow(2, tempY / num1), 0, pow(2, 300 / num1), 1, 100) / 40;
var tX = tempX + 3 * mult;
var tY = tempY + 30 * mult;
while (hListcheck(tX, tY, houseList, 0)){
tempY = random(120, 200);
tempX = random(0, 450)
tX = tempX + 3 * mult;
tY = tempY + 30 * mult;
}
var tree = { x: tempX,
y: tempY,
w: map(pow(2, tempY / num1), 0, pow(2, 300 / num1), 1, 100), //proportionally scale house in the distance
m: map(pow(2, tempY / num1), 0, pow(2, 300 / num1), 1, 100) / 40,
draw1: tree1draw,
draw2: tree2draw,
draw3: tree3draw,
nest: false
};
return tree;
}
function tree1draw(){
noStroke();
push();
translate(this.x, this.y);
scale(this.m, this.m);
fill(122, 98, 66);
rect(3, 0, 3, 30);
fill(95, 140, 99, 180);
ellipse(0, -5, 30, 35);
ellipse(15, -5, 20, 25);
ellipse(5, 8, 50, 20);
if(this.nest == true){
fill(89, 68, 49);
rect(0, 0, 10, 10);
fill(193, 164, 137);
ellipse(5, 5, 4, 4);
}
pop();
}
function tree2draw(){
noStroke();
push();
translate(this.x, this.y);
scale(this.m, this.m);
fill(122, 98, 66);
rect(5, 0, 3, 30);
fill(95, 120, 96, 200);
triangle(18, 18, -6, 18, 6, -30);
if(this.nest == true){
fill(89, 68, 49);
rect(0, 0, 10, 10);
fill(193, 164, 137);
ellipse(5, 5, 4, 4);
}
pop();
}
function tree3draw(){
noStroke();
push();
var mult = this.w / 40;
translate(this.x, this.y);
scale(mult, mult);
fill(122, 98, 66);
rect(3, 0, 3, 30);
fill(108, 132, 102, 200);
ellipse(4, -17, 20, 20);
ellipse(4, -8, 30, 20);
ellipse(4, 5, 40, 25);
if(this.nest == true){
fill(89, 68, 49);
rect(0, 0, 10, 10);
fill(193, 164, 137);
ellipse(5, 5, 4, 4);
}
pop();
}
function drawBackground(){
//draw background gradient
setGradient(0, 0, width, height * 0.45, c1, c2, Y_AXIS);
//mountain layer 1
noStroke();
fill(75, 137, 138);
beginShape();
curveVertex(0, height);
curveVertex(0, height);
curveVertex(0, 200);
curveVertex(0, 180);
curveVertex(190, 60);
curveVertex(280, 80);
curveVertex(350, 70);
curveVertex(420, 100);
curveVertex(520, 80);
curveVertex(width, height);
curveVertex(width, height);
endShape();
//gradient mask
for (var i = 0; i < 500; i++) {
var op = map(i, 100, 500, 0, 255);
stroke(255, 255, 255, op);
line(0, i * 0.6, width, i * 0.6);
}
//mountain layer 2
noStroke();
strokeWeight(1);
fill(75, 147, 154);
beginShape();
curveVertex(0, height);
curveVertex(0, height);
curveVertex(0, 120);
curveVertex(0, 110);
curveVertex(100, 70);
curveVertex(200, 130);
curveVertex(300, 90);
curveVertex(400, 130);
curveVertex(500, 120);
curveVertex(500, 130);
curveVertex(width, height);
curveVertex(width, height);
endShape();
//gradient mask
for (var i = 0; i < 500; i++) {
var op = map(i, 100, 500, 0, 255);
stroke(255, 183, 80, op);
line(0, i, width, i);
}
}
function drawStairs(){
noStroke();
fill(99, 88, 77);
for (var i = 0; i < 15; i++) {
rect(i * 5 + 30, i * 3 + 190, 8, 1.5);
rect(i * 5 + 40, -i * 2 + 190, 8, 1);
rect(i * 5 + 30, i * 3 + 120, 1 + i * 0.5, 1)
};
rect(35, 190, 2, 45);
rect(28, 190, 2, 45);
rect(28, 210, 8, 2);
rect(110, 162, 1, 35);
rect(116, 162, 1, 35);
rect(110, 170, 6, 1);
strokeWeight(2);
line(1, 1, 100, 100);
for (var j = 0; j < 30; j++) {
fill(117, 107, 98);
rect(j * 2 + 440, j * 3 + 130, 1 + j * 0.7, 1);
};
}
function drawTracks(){
stroke(122, 102, 82);
strokeWeight(2);
line(0, 280, 500, 280);
strokeWeight(1);
line(0, 275, 500, 275);
for (var i = 0; i < 15; i++) {
rect(i * 40, 273, 1, 6);
};
}
function makeTrain(){
var train = { x: 500,
y: 277,
vel: random(5, 15),
draw: drawTrain
};
return train;
}
function drawTrain(){
noStroke();
fill(80);
triangle(this.x, this.y - 5, this.x + 25, this.y - 5, this.x + 25, this.y - 20);
rect(this.x + 12, this.y - 40, 10, 15);
rect(this.x + 20, this.y - 40, 50, 35);
rect(this.x + 22, this.y - 50, 15, 25);
rect(this.x + 55, this.y - 59, 30, 4);
rect(this.x + 70, this.y - 16, 16, 8);
rect(this.x + 80, this.y - 16, 8, 8);
rect(this.x + 88, this.y - 13, 18, 3);
fill(140, 89, 88);
rect(this.x + 16, this.y - 45, 40, 25);
fill(140, 100, 88);
rect(this.x + 60, this.y - 55, 20, 45);
fill(201, 216, 215);
rect(this.x + 64, this.y - 52, 12, 18);
fill(96, 83, 58);
ellipse(this.x + 30, this.y - 5, 15, 15);
ellipse(this.x + 70, this.y - 5, 15, 15);
for (var i = 1; i < 5; i++) {
fill(80);
rect(this.x + 100 * i, this.y - 55, 90, 3);
rect(this.x + 100 * i, this.y - 13, 100, 3);
fill(140, 120, 88);
rect(this.x + 5 + 100 * i, this.y - 52, 80, 45);
fill(140, 130, 98);
rect(this.x + 5 + 100 * i, this.y - 22, 80, 15);
fill(201, 216, 215);
rect(this.x + 12 + 100 * i, this.y - 48, 30, 18);
rect(this.x + 48 + 100 * i, this.y - 48, 30, 18);
fill(96, 83, 58);
ellipse(this.x + 20 + 100 * i, this.y - 5, 15, 15);
ellipse(this.x + 70 + 100 * i, this.y - 5, 15, 15);
};
fill(0);
drawSmoke(this.x, this.y);
}
function drawSmoke(x, y){
fill(255, 255, 255, 100);
ellipse(x + 30, y - 60, 20, 10);
ellipse(x + 50, y - 70, 15, 8);
}
function makeBird(x, y) {
var num = 50;
var bird = {"bx": x,
"by": y,
"bsz": size,
"bsca": (map(pow(2, y / num), 0, pow(2, 300 / num), 1, 100)) / 35,
"xvel": random(-10, 10) * (map(pow(2, y / num), 0, pow(2, 300 / num), 1, 100)) / 35,
"yvel": random(-5, 5) * (map(pow(2, y / num), 0, pow(2, 300 / num), 1, 100)) / 35,
};
bird.draw = birdDraw;
bird.draw2 = birdDraw2;
return bird;
}
function birdDraw(){
noFill();
stroke(0);
strokeWeight(2);
push();
translate(this.bx, this.by);
scale(this.bsca);
ellipseMode(CENTER);
arc(35, 35, 100, 100, PI * 1.25, PI * 1.5);
arc(-35, 35, 100, 100, PI * 1.5, PI * 1.75);
fill(0);
ellipse(0, 0, 5, 5);
pop();
}
function birdDraw2(){
noFill();
stroke(0);
strokeWeight(2);
push();
translate(this.bx, this.by);
scale(this.bsca);
rotate(PI/10);
arc(35, 35, 100, 100, PI * 1.25, PI * 1.5);
fill(0);
ellipse(0, 0, 5, 5);
pop();
push();
translate(this.bx, this.by);
scale(this.bsca);
rotate(-PI / 10);
arc(-35, 35, 100, 100, PI * 1.5, PI * 1.75);
pop();
}
//make raccoon
function makeRac(x, y){
var rac;
var num = 50;
rac = {
"rx": x ,
"ry": y,
"rsz": size,
"bsca": (map(pow(2, y / num), 0, pow(2, 300 / num), 1, 100)) / 400,
"vel": random(-2, 2) * (map(pow(2, y / num), 0, pow(2, 300 / num), 1, 50)) / 35
};
rac.draw = racDraw;
return rac;
}
//draw raccoon
function racDraw(){
var inv = -1;
push();
translate(this.rx, this.ry);
fill(0);
noStroke();
beginShape();
if (this.vel < 0){
scale(this.bsca, this.bsca);
} else{
scale(this.bsca * -1, this.bsca);
}
vertex(0, 0);
vertex(5, -10);
vertex(3, -20);
vertex(7, -30);
vertex(5, -40);
vertex(8, -45);
vertex(20, -40);
vertex(65, -55);
vertex(85, -65);
vertex(150, -60);
vertex(190, -30);
vertex(180, 20);
vertex(190, 50);
vertex(180, 80);
vertex(170, 80);
vertex(170, 75);
vertex(175, 73);
vertex(176, 55);
vertex(140, 25);
vertex(110, 25);
vertex(80, 80);
vertex(70, 80);
vertex(70, 75);
vertex(75, 75);
vertex(80, 50);
vertex(70, 10);
vertex(50, 10);
vertex(30, 5);
vertex(10, 10);
vertex(0, 0);
endShape();
beginShape();
vertex(200, -25);
vertex(192, 10);
vertex(200, 18);
vertex(210, -20);
endShape();
beginShape();
vertex(220, -15);
vertex(230, -8);
vertex(220, 30);
vertex(210, 22);
endShape();
beginShape();
vertex(240, -3);
vertex(250, 5);
vertex(242, 20);
vertex(232, 25);
endShape();
beginShape();
fill(255);
vertex(50, 10);
vertex(30, -15);
vertex(20, -13);
vertex(15, -5);
vertex(15, -5);
vertex(20, 0);
vertex(26, 0);
vertex(35, 6);
endShape();
fill(0);
ellipse(23, -8, 5, 5);
rect(112, 50, 15, 7);
rotate(PI / 4);
rect(60, -40, 10, 40);
rect(120, -80, 10, 30);
pop();
}
//interactions
function keyPressed(){
if(keyCode === RIGHT_ARROW){
if (rachouseCount < houseList.length){
var selhouse = int(random(0, houseList.length));
while (houseList[selhouse].rh == true){
selhouse = int(random(0, houseList.length));
}
houseList[selhouse].rh = true;
}
}
if(keyCode === LEFT_ARROW){
birdList.push(makeBird(random(0, 500), random(0, 200)));
}
}
//Linear gradient code from p5js examples https://p5js.org/examples/color-linear-gradient.html
function setGradient(x, y, w, h, c1, c2, axis) {
noFill();
if (axis == Y_AXIS) { // Top to bottom gradient
for (var i = y; i <= y + h; i++) {
var inter = map(i, y, y + h, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x + w, i);
}
}
}
In this project I want to create an interactive animation on cohabitation wiht urban wildlife in cities. As we are displacing natural habitats to make way for urban sprawl, effects of a loss of biodiversity and edge effects from habitat fragmentation are becoming more pronounced. In my studio I am currently working on a thesis project dealing with the environment and cohabitation/negotiation of boundaries between human and more-than-human species, and creating installations for endangered species as well as synanthropic species to share urban space. I am inspired by the works of Joyce Hwang and Sarah Gunawan , and I want to create an animation that documents the vision of such installation projects and their impacts on our environment. Especially the bird landing pads and composting chimneys for raccoons.
In this animation, trains pass by at a certain interval of time, pressing left arrow adds a bird, and for every 3 birds added, an artificial bird nest attached to trees will pop up. (Nests will start disappearing when birds leave the screen). Pressing right arrow adds a compost chimney attached to houses, and every chimney attracts 2 raccoons.
Working on this project I spent a large chunk of my time illustrating the creatures and houses which in hindsight could have been done much easier if I just drew them and upload them to imgur. I also had trouble with overlapping objects and had to create functions that sort the order or the object array and also draws objects outside of the boundary of other objects. I feel like I reviewed everything we learned this semester through this project.
Sound Test
howl
spirit
kiki
totoro
Yoo Jin Shin- Final Project
// Yoo Jin Shin
// yoojins@andrew.cmu.edu
// Section D
// Final Project
// All scenes global variables
var yaxis = 1;
var xaxis = 2;
var frames = [];
var frameCounts = 0;
var textSpeed = 3;
var slider;
var sliderValue;
// Yeosu global variables
var c1, c2, c3, c4;
var terrainSpeed1 = 0.0001;
var terrainDetail1 = 0.003;
var terrainSpeed2 = 0.00012;
var terrainDetail2 = 0.0045;
var terrainSpeed3 = 0.00007;
var terrainDetail3 = 0.0006;
var clouds = [];
var trees = [];
var textX = 1;
var sunMouse;
var birdLoad;
var bird1;
var birds = [];
// Grand Canyon global variables
var terrainSpeed4 = 0.00003;
var terrainDetail4 = 0.0005;
var terrainSpeed5 = 0.00012;
var terrainDetail5 = 0.007;
var terrainSpeed6 = 0.00007;
var terrainDetail6 = 0.0065;
var textX3 = 1;
var c9;
// Las Vegas global variables
var c5, c6, c7, c8;
var buildings = [];
var snowflakes = [];
var drops = [];
var textX2 = 1;
var buildingMouse;
var carLoad;
var car1;
var cars = [];
function preload(){
// Loading sprite sheet for girl character via direct links from imgur
// Creds to https://www.gameart2d.com/freebies.html
var filenames = [];
filenames[0] = "https://i.imgur.com/oEJGbCm.png";
filenames[1] = "https://i.imgur.com/QsZoWMJ.png";
filenames[2] = "https://i.imgur.com/kyo4lhi.png";
filenames[3] = "https://i.imgur.com/XmPYK4a.png";
filenames[4] = "https://i.imgur.com/w80hQ6A.png";
filenames[5] = "https://i.imgur.com/0BiNaBy.png";
filenames[6] = "https://i.imgur.com/WL7kjhR.png";
filenames[7] = "https://i.imgur.com/z6agkKq.png";
filenames[8] = "https://i.imgur.com/Vxi5Eu6.png";
filenames[9] = "https://i.imgur.com/mrjcctG.png";
filenames[10] = "https://i.imgur.com/oDP8zsr.png";
filenames[11] = "https://i.imgur.com/DsNFucK.png";
filenames[12] = "https://i.imgur.com/8Y3e8BW.png";
filenames[13] = "https://i.imgur.com/aQUjC1v.png";
filenames[14] = "https://i.imgur.com/6yQMDLO.png";
filenames[15] = "https://i.imgur.com/fJZPSul.png";
filenames[16] = "https://i.imgur.com/vghvvNP.png";
filenames[17] = "https://i.imgur.com/oh2WsXz.png";
filenames[18] = "https://i.imgur.com/yPh4Upu.png";
filenames[19] = "https://i.imgur.com/k0wd9HK.png";
for (var i = 0; i < filenames.length; i++) {
frames.push(loadImage(filenames[i]));
}
// Loading bird and car images created using illustrator
birdLoad1 = "https://i.imgur.com/RQSUNmm.png";
bird1 = loadImage(birdLoad1);
carLoad1 = "https://i.imgur.com/yKCei98.png";
car1 = loadImage(carLoad1);
}
function setup() {
createCanvas(480, 480);
drawSlider();
// Yeosu: Define gradient colors
c1 = color(225, 217, 199); // sky top color - grey
c2 = color(254, 180, 144); // sky bottom color - orange
c3 = color(50, 50, 2); // ground left - lighter green
c4 = color(27, 20, 2); // ground right - dark green
// Yeosu: Initialize clouds
for (var i = 0; i < 3; i++) {
var cloudX = random(width);
clouds[i] = drawClouds(cloudX);
}
// Yeosu: Initialize trees
for (var i = 0; i < 7; i++) {
var treeX = random(width);
var t = drawTrees(treeX);
trees[i] = t;
}
// Yeosu: Initialize birds
for (var i = 0; i < 7; i++) {
var birdX = random(width);
birds[i] = drawBird(birdX);
}
// Las Vegas: Define gradient colors
c5 = color(0, 0, 0); // sky top color - black
c6 = color(61, 48, 52); // sky bottom color - purpley
// Las Vegas: Initialize buildings
for (var i = 0; i < 6; i++) {
var rx = random(width);
buildings[i] = drawBuilding(rx);
}
// Las Vegas: Initialize cars
for (var i = 0; i < 10; i++) {
var carX = random(width);
cars[i] = drawCar(carX);
}
imageMode(CENTER);
}
function drawSlider() {
slider = createSlider(5, 60, 30);
slider.style(200, '100px');
slider.position(20, 450);
}
function draw() {
// Set slider to adjust frameRate
var frameRateSpeed = slider.value();
frameRate(frameRateSpeed);
// Change scene every 160 frames, then loop
// Loop: Yeosu - GrandCanyon1 - LasVegas - GrandCanyon2
if (frameCounts <= 160) { // 160
drawYeosu();
}
else if (frameCounts >= 160 & frameCounts < 320) {
drawGrandCanyon(); // transition: light to dark sky
}
else if (frameCounts >= 320 & frameCounts < 480) {
drawLasVegas();
}
else if (frameCounts >= 480 & frameCounts < 640) {
drawGrandCanyon2(); // transition: dark to light sky
}
else if (frameCounts === 640) {
frameCounts = 0;
}
frameCounts++;
}
// =====================================================================
// ==============================YEOSU==================================
// =====================================================================
function drawYeosu() {
setGradient(0, 0, width, height / 2 + 70, c1, c2, yaxis); // sky
drawSun();
drawMountain1();
drawMountain2();
drawOcean();
drawSunReflection();
updateClouds();
removeClouds();
addClouds();
setGradient(0, 390, width, 480, c3, c4, xaxis); // ground
updateTrees();
removeTrees();
addTrees();
drawMe();
drawFog();
updateBird();
removeBird();
addBird();
writeText();
}
function setGradient(x, y, w, h, c1, c2, axis) {
// Top to bottom gradient
if (axis == yaxis) {
for (var i = y; i <= y + h; i++) {
var inter = map(i, y, y + h, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x + w, i);
}
}
// Left to right gradient
else if (axis == xaxis) {
for (var i = x; i <= x + w; i++) {
var inter = map(i, x, x + w, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(i, y, i, y + h);
}
}
}
function drawMountain1(){
noStroke();
fill(204, 157, 135);
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail1) + (millis() * terrainSpeed1);
var y = map(noise(t), 0, 1.8, height / 4 - 10, height);
vertex(x, y);
}
vertex(width, height);
vertex(0, height);
endShape();
}
function drawFog() {
for (var y = 200; y < height + 5; y++) {
var f = map(y, height / 2 - 40, 550, 0, 100);
stroke(255, f);
line(0, y, width, y);
}
}
function drawMountain2(){
fill(147, 126, 115);
noStroke();
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail2) + (millis() * terrainSpeed2);
var y = map(noise(t), 0, 2, height / 4 + 60, height);
vertex(x, y);
}
vertex(width,height);
vertex(0,height);
endShape();
}
function drawOcean() {
fill(170, 146, 121);
noStroke();
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail3) + (millis() * terrainSpeed3);
var y = map(noise(t), 0, 2, height - 230, height);
vertex(x, y);
}
vertex(width, height);
vertex(0, height);
endShape();
}
function drawSun() {
// All sun parts based on mouseY
sunMouse = constrain(mouseY, 0, height / 3 + 30);
noStroke();
// Sunglow
// Color less intense and size smaller as sun goes farther up
fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.02);
ellipse(width / 3, sunMouse + 40, sunMouse - 10, sunMouse - 10);
fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.03);
ellipse(width / 3, sunMouse + 40, sunMouse*1.1, sunMouse*1.1);
fill(253, 254 - sunMouse, 221 - sunMouse, 20 - sunMouse*0.05);
ellipse(width / 3, sunMouse + 40, sunMouse*1.2 + 10, sunMouse*1.2 + 10);
// Sunrays
fill(253, 254, 221, 30);
triangle(width / 3, sunMouse + 20, width / 3 - 40, height / 3 + 90, width / 3 - 10, height /3 + 80); // left big
triangle(width / 3, sunMouse + 20, width / 3 + 40, height / 3 + 80, width / 3 + 10, height /3 + 70); // right big
triangle(width / 3, sunMouse + 20, width / 3 - 50, height / 3 + 90, width / 3 - 30, height /3 + 80); // left small
triangle(width / 3, sunMouse + 20, width / 3 + 50, height / 3 + 80, width / 3 + 30, height /3 + 70); // right small
triangle(width / 3, sunMouse + 20, width / 3 - 70, height / 3 + 70, width / 3 - 80, height /3 + 70); // left small2
triangle(width / 3, sunMouse + 20, width / 3 + 70, height / 3 + 90, width / 3 + 80, height /3 + 80); // right small2
// Sun
fill(253, 254, 221, sunMouse + 30);
ellipse(width / 3, sunMouse + 40, sunMouse - 20, sunMouse - 20);
}
function drawSunReflection() {
// Size of reflection on ocean corresponds to sun size/distance away
var x = 10;
var y = 47;
var w = sunMouse;
var h = 10;
noStroke();
// Outer darker glow
fill(248, 172, 137, 100);
push();
rectMode(CENTER);
rect(width / 3, 2 * height / 3 + y, w, h, 10);
rect(width / 3, 2 * height / 3 + y - 13, w * 0.8, h, 10);
rect(width / 3, 2 * height / 3 + y - 26, w * 0.6, h, 10);
// Inner lighter glow
fill(253, 254, 221, 50);
rect(width / 3, 2 * height / 3 + y - 4, w * 0.9, h * 0.8, 10);
rect(width / 3, 2 * height / 3 + y - 17, w * 0.7, h * 0.8, 10);
rect(width / 3, 2 * height / 3 + y - 30, w * 0.5, h * 0.8, 10);
pop();
}
function updateClouds(){
for (var i = 0; i < clouds.length; i++) {
clouds[i].move();
clouds[i].display();
}
}
function removeClouds(){
var keepClouds = [];
for (var i = 0; i < clouds.length; i++) {
if (clouds[i].x - this.width / 2 < width) {
keepClouds.push(clouds[i]);
}
}
clouds = keepClouds;
}
function addClouds(){
var newCloud = 0.01;
if (random(0, 1) < newCloud) {
clouds.push(drawClouds(random(width)))
}
}
function moveClouds(){
this.x += this.speed;
}
function displayClouds(){
var b = random(165, 180);
fill(255, 240, 240, 30);
ellipse(this.x, this.y, this.width, this.height);
ellipse(this.x + 50, this.y + 10, this.width - 20, this.height - 70);
ellipse(this.x - 50, this.y - 5, this.width - 70, this.height - 10);
}
function drawClouds(newCloudX) {
var cloud = {
x: newCloudX,
y: random(30, height / 2),
width: random(150, 250),
height: random(20, 50),
speed: random(0.5, 1.5),
move: moveClouds,
display: displayClouds
}
return cloud;
}
function updateTrees() {
for (var i = 0; i < trees.length; i++) {
trees[i].move();
trees[i].display();
}
}
function removeTrees() {
var keepTrees = [];
for (var i = 0; i < trees.length; i++) {
if (trees[i].x < width) {
keepTrees.push(trees[i]);
}
}
trees = keepTrees;
}
function addTrees() {
var newTree = 0.02;
if (random(0, 1) < newTree) {
trees.push(drawTrees(random(width)));
}
}
function moveTrees() {
this.x += this.speed;
}
function displayTrees() {
// Tree height based on mouseY, mapped to a reasonable extent
var treeMouse = map(mouseY, 0, height, height / 3, 0);
var treeMouseCon = constrain(treeMouse, 0, height)
// Trunk
stroke(c4);
strokeWeight(4);
line(this.x, this.y + 20 - treeMouseCon, this.x, this.y + 40);
// Leaves
fill(c3, 20);
stroke(c3);
strokeWeight(7);
strokeJoin(ROUND);
triangle(this.x, this.y - treeMouseCon, this.x + 20, this.y + 25, this.x - 20, this.y + 25);
// Add snow if on Grand Canyon scene
if (frameCounts >= 160 & frameCounts < 320 || frameCounts >= 480 && frameCounts < 640) {
fill(250);
This project was inspired by my love of taking photos, especially of nature and cityscapes. I tried recreating the feel and weather of three shots below in a looping generative landscape. Follow me! You can speed up or slow my pace using the slider and control objects like the sun and buildings using the mouse.
Since this doesn’t load properly on WP, access zip file here!