//Carly Sacco
//Section C
//csacco@andrew.cmu.edu
//Project 11: Generative Landscape
//creates the components on the water
var waterSpeed = 0.00008;
var waterDetail = 0.0005;
//creates the components for the icebergs
var iceSpeed = 0.0005;
var iceDetail = .05;
//snow array
var snow = [];
function setup() {
createCanvas(480, 280);
//initial collection of snow
for (var i = 0; i < 100; i += 1) {
var flake = random(width);
snow[i] = drawSnow(flake);
}
frameRate(10);
}
function draw() {
//sky
background(176, 203, 245);
//icebergs
noFill();
beginShape();
stroke(255);
for (var x = 0; x < width; x += 1) {
var t = (x * iceDetail) + (millis() * iceSpeed);
var y = map(noise(t), 0,1, height/7, height);
vertex(0, 900)
vertex(width, 800)
vertex(x, y);
}
endShape();
//calls the function to make water
makeWater();
//penguin body
fill('black');
noStroke();
ellipse(280, 220, 35, 40);
ellipse(280, 195, 25, 25);
//penguin stomach
fill('white');
ellipse(280, 225, 25, 45);
ellipse(280, 195, 15, 15);
//penguin eyes
fill('black');
ellipse(276, 191, 3, 3);
ellipse(284, 191, 3, 3);
//penguin body
fill('orange');
triangle(276, 195, 284, 195, 280, 200);
//boat
push();
noStroke();
translate(60, 30);
fill('red')
quad(40, 200, 250, 200, 230, 260, 60, 260);
fill('white');
rect(100, 150, 80, 50);
fill('black')
ellipse(110, 165, 15, 15);
ellipse(140, 165, 15, 15);
ellipse(170, 165, 15, 15);
pop();
//calling the functions to make the snow
snowFall();
drawSnow();
addSnow();
}
//makes the water
function makeWater() {
noFill();
beginShape();
stroke(66, 114, 189);
for (var x = 0; x < width; x++) {
var t = (x * waterDetail) + (millis() * waterSpeed);
var y = map(noise(t), 0,1, height/2, height);
vertex(0, 800)
vertex(width, 800)
vertex(x, y);
}
endShape();
}
//continues to add snow that appears
function addSnow() {
var moreSnow = 5;
if(1 < moreSnow) {
snow.push(drawSnow(height));
}
}
//calls for the snow to appear and move
function snowFall() {
for (i = 0; i < snow.length; i +=1) {
snow[i].displaySnow();
snow[i].moveSnow();
}
}
//actually drawing what the snow looks like
function drawSnow(width) {
var sno = {
x: random(0, 480),
y: 0,
radius: random(5, 10),
speed: 1,
moveSnow: function() {
this.y += this.speed;
},
displaySnow: function() {
noStroke();
fill(255);
ellipse(this.x, this.y, this.radius, this.radius);
},
}
return sno;
}
For my project I had decided I wanted to do a winter themed one since it has started to get very cold here. Therefore, instead of mountains I chose to do icebergs and did that by making the sharp edges seem to be floating by the boat. After I added the snow for my objects and boat to fit the theme I thought it would be cute to add the penguin.
/*
* Angela Lee
* Section E
* ahl2@andrew.cmu.edu
* Project 11 Generative Landscape
*/
// tallest mountains
var tallMtnDetail = 0.005; // detail in mountains
var tallMtnSpeed = 0.0001; // speed of mountains
// medium mountains
var medMtnDetail = 0.0075;
var medMtnSpeed = 0.0002;
// beach
var beachDetail = 0.003;
var beachSpeed = 0.0004;
// array for ripples
var ripples = [];
var yellow, pink;
function setup() {
createCanvas(480, 300);
frameRate(10);
// boundaries for ripples
var top = height * 5/8 + 10;
var bottom = height - 10;
// first ripples
for (var i = 0; i < 10; i++) {
var rippleX = random(width);
var rippleY = random(top, bottom);
ripples[i] = makeRipples(rippleX, rippleY);
}
// gradient for the water
yellow = color(255, 219, 140);
pink = color(247, 132, 124);
}
function draw() {
noStroke();
background(255, 156, 161);
makeSun(); // setting sun
makeTallMtn(); // tallest mountains
makeMedMtn(); // middle mountains
//makeWater();
gradientWater();
// ripple functions
updateRipple();
removeRipple();
addRipple();
makeBeach();
}
//----------------- FUNCTIONS BELOW THIS LINE -----------------------------
// SETTING SUN
function makeSun() {
// sun rays
noStroke();
fill(255, 161, 135);
ellipse(width/2, height * 3/8, 275, 275);
// sun
stroke(255);
strokeWeight(1);
fill(247, 217, 82);
ellipse(width/2, height * 3/8, 175, 175);
}
// TALLEST MOUNTAINS
function makeTallMtn() {
fill(252, 119, 165);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * tallMtnDetail) + (millis() * tallMtnSpeed);
var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
vertex(x, y);
}
vertex(width, height);
endShape();
}
// MEDIUM MOUTAINS
function makeMedMtn() {
fill(230, 99, 160);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * medMtnDetail) + (millis() * medMtnSpeed);
var y = map(noise(t), 0, 1, height / 8 * 3, height / 8 * 5);
vertex(x, y);
}
vertex(width, height);
endShape();
}
// OCEAN
function gradientWater() {
noFill();
for (var y = height * 5/8; y < height; y++) {
var inter = map(y, height * 5/8, height, 0, 1);
var c = lerpColor(yellow, pink, inter);
stroke(c);
line(0, y, width, y);
}
}
// BEACH
function makeBeach() {
fill(252, 195, 182);
strokeWeight(1);
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * beachDetail) + (millis() * beachSpeed);
var y = map(noise(t), 0, 1, height * 7/8, height * 19/20);
vertex(x, y);
}
vertex(width, height);
endShape();
}
//----------------- RIPPLE OBJ & FUNCTIONS BELOW THIS LINE -----------------------------
// RIPPLE OBJECT
function makeRipples(xPos, yPos) {
var makeRipple = {x: xPos,
y: yPos,
// longer ripples are in the front, shorter ones in the back
length: map(yPos, height * 5/8, height, 5, 75),
// thinner ripples in the back, thicker ones in the front
weight: map(yPos, height * 5/8, height, 1, 4),
// faster ripples in the front, slower ripples in the back
speed: map(yPos, height * 5/8, height, 1, 4),
move: moveRipple,
draw: drawRipple}
return makeRipple;
}
// MOVING THE RIPPLE
function moveRipple() {
// x position changes by speed
this.x += this.speed;
// if the ripple leaves the frame, reset x position
// to the left side of the frame
if (this.x > width + this.length) {
this.x === -this.length;
}
}
// ADDING RIPPLES
// using a tiny probability, add ripples
function addRipple() {
if (random(0, 1) < 0.075) {
ripples.push(makeRipples(-75, random(height * 5/8, height)));
}
}
// REMOVING RIPPLES
function removeRipple() {
// an array for ripples to keep
var keepRipples = [];
for (var i = 0; i < ripples.length; i++) {
if (ripples[i].x < width) {
keepRipples.push(ripples[i]);
}
}
ripples = keepRipples;
}
// UPDATE AND DISPLAY RIPPLE
function updateRipple() {
for (var i = 0; i < ripples.length; i++) {
ripples[i].move();
ripples[i].draw();
}
}
// DRAWING THE RIPPLE
function drawRipple() {
strokeWeight(this.weight);
stroke(255);
line(this.x, this.y, this.x + this.length, this.y);
}
For my landscape, I was inspired the 80s vaporwave illustration style and color. I created a sunset scene and had fun with showing depth through details. For instance, the sizes and speeds of the mountains and ripples are all dependent on the “distance” they would be away from the viewer (the farther something is, the slower and smaller it is).
//alcai@andrew.cmu.edu
//alice cai
//section E
//week 11 assignment A
//terrain variables
var terrainSpeed = -0.0003;
var terrainDetail = 0.005;
var terrainSpeed2 = -0.0004;
var terrainDetail2 = 0.007;
//lantern variables
var List = [];
var moving = -5;
var end = -20;
function setup(){
createCanvas (480,480);
frameRate(10);
//call # of lanterns
for (var j = 0; j < 20; j++) {
var px = random(width);
var py = random(height / 3);
List[j] = makeLant(px, py);
}
//define gradient colors
yello=color(255, 187, 0);
orang=color(250, 133, 0);
}
function draw() {
background(100, 50, 122);
//call moon
moon();
//draw dessert mountains
mount();
//water
fill(10, 12, 71);
rect(0, height/3 * 2, width, height);
//render lanterns
lantRender();
}
//draw a mooon
function moon(){
noStroke();
fill(255, 237, 186, 30);
ellipse(width/2, height/3, 200,200);
fill(255, 237, 186);
ellipse(width/2, height/3, 150,150);
}
function mount(){
//two mountain ranges
noStroke();
beginShape();
fill(122, 55, 80);
vertex(0, height);
for (var x = 0; x < width; x++) {
var t2 = (x * terrainDetail2) + (millis() * terrainSpeed2);
var y = map(noise(t2), 0, 1, 100, 300);
vertex(x, y);
}
vertex(width, height);
endShape();
noStroke();
beginShape();
fill(53, 40, 105);
vertex(0, height);
for (var x = 0; x < width; x++) {
var t1 = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t1), 0, 1, 250, 300);
vertex(x, y);
}
vertex(width, height);
endShape();
}
//make lantern with variable parameters, return object lant
function makeLant(px,py) {
var lant = {x: px,
y: py,
width: random(0,50),
thic: random(20,30),
speed: moving,
update: lantUpdate,
draw: lantDraw}
return lant;
}
//draw lantern
function lantDraw() {
noFill();
noStroke();
//random size adds flickering
var size = this.thic + random(0,5);
var thic = this.width;
push();
translate(this.x, this.y * 3);
//gradient line
for (var i = 0; i < size; i++) {
var inter = map(i, 0, size, 0, 1);
var c = lerpColor(orang, yello, inter);
stroke(c);
strokeWeight(thic);
line(0, i, 20, i);
}
pop();
}
//move the lanters and have them start over when they hit the end
function lantUpdate() {
//speed of moving but with random to make wind/random travel speed effect
this.x += this.speed + random(-5,5);
if (this.x <= end) {
this.x += width - end;
}
}
//render lantern, add to list array
function lantRender() {
for (var i = 0; i < List.length; i++) {
List[i].update();
List[i].draw();
}
}
sketch
This project took inspiration from the Disney movie Tangled, specifically from the final, super romantic scene of the lantern lighting. I wanted to recreate this scene with the warm colors and floating lanterns. The randomized sizes created flickering and the size varation created depth to the lanters that lit up the sky. The lanterns float across the screen like they are in the sky.
lantern scene from tangledpurply lantern scene from tangled
//Shannon Ha
//Section D
//sha2@andrew.cmu.edu
//Project 11 Generative Landscape
var terrainSpeed = 0.0001;
var terrainDetail = 0.006;
var martians = [];
function setup() {
createCanvas(480, 300);
for (var i = 0; i < 4; i++){ //create initial collection of martians displayed on screen.
var rx = random(width);
martians[i] = makeMartian(rx);
}
for (var i = 0; i < stars; i++) { //randomly generates star size and position.
sX.push(random(0, width)); // x position of star
sY.push(random(0, height / 3)); // y position of star
starSize.push(random(0.1, 1)); // star size
}
frameRate(15);
}
function draw() { // calls all the objects
background(43, 14, 7);
drawStars();
drawMountain();
drawMountainB();
//calls martian objects
updateAndDisplayMartians();
removeMartians();
addMartians();
// draw distant planet A
fill(130, 67, 52);
noStroke();
ellipse(400, 20, 30, 30);
// draw distant planet B
fill(176, 91, 70);
ellipse(350, 15, 10, 10);
}
var stars = 300; //number of star points
var sX = []; //x position array
var sY = []; //y position array
var starSize = [];// star size array
function drawStars() {
noStroke();
for (var i = 0; i < stars; i++) { // draws the stars
stroke(random(100, 255)); // randomize grayscale for stroke to give the twinkle effect
strokeWeight(starSize[i]);
point(sX[i], sY[i], 10, 10);
}
}
function drawMountain(){ //background terrain
push();
fill(79, 16, 0);
noStroke();
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);// adjusts flatness of terrain
var y = map(noise(t), 0,1, height/2.5, height * 0.2);
vertex(x, y);
}
vertex(width, height);
endShape();
pop();
}
function drawMountainB(){ //terrain in the front
push();
fill(138, 31, 4);
noStroke();
beginShape();
vertex(0, height);
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed * 2);
var y = map(noise(t), 0,1, height , height * 0.1);
vertex(x, y);
}
vertex(width, height);
endShape();
pop();
}
function updateAndDisplayMartians(){
// Update the martians' positions, and display them
for (var i = 0; i < martians.length; i++){
martians[i].move();
martians[i].display();
}
}
function removeMartians(){ // removes all martians that go off the canvas.
var martiansToKeep = [];
for (var i = 0; i < martians.length; i++){
if (martians[i].x + martians[i].breadth > 0) {
martiansToKeep.push(martians[i]);
}
}
martians = martiansToKeep; // remembers the remaining martians on canvas.
}
function addMartians(){ // adds new martians onto canvas
var newMartiansLikelihood = 0.017;
if (random(0,1) < newMartiansLikelihood) {
martians.push(makeMartian(0));
}
}
function martianMove() { // allows the martians to glide across screen
this.x += this.speed;
}
function displayMartian() { //draws the martian.
fill(12, 63, 117);
noStroke();
push();
translate(this.x, height - 60);
// body
ellipse(20, 30, this.breadth, this.height);
// white part of eye
fill(255);
ellipse(20, 20, this.breadth / 2, this.breadth / 2);
//blue part of eye
fill(105, 160, 219);
ellipse(20, 20, 10, 10);
//antennas
stroke(105, 160, 219);
strokeWeight(4);
line(10, 10, 5, 5);
line(30, 10, 35, 5);
//ends of antenna
fill(random(255), random(100), random(200));
noStroke();
ellipse(5, 5, 10, 10);
ellipse(35, 5, 10, 10);
pop();
}
function makeMartian(birthLocationX){ // martian characteristics
var alien = {x: birthLocationX,
breadth: 30,
height: 50,
speed: random(3, 7),
move: martianMove,
display: displayMartian};
return alien;
}
Rough sketch.
Screenshot of the music video I took inspiration from.
For this project, I wanted to create a fictional landscape of Mars, so I took a bit of inspiration from the iconic Britney Spears’ Oops I did it again Music Video (I wanted to add an astronaut but I didn’t know how to remove the background of a picture I found online) and added my own twist by putting in blue aliens that greet you with their antennas as you pass glance over the Martian landscape. I had a lot of fun making this project as it helped me understand the use of objects and characteristics better!
let flowers = [];
let grass = [];
let clouds = [];
function setup() {
createCanvas(600,600);
//inital placement for flowers
for (let i = 0; i < 50; i++) {
let firstX = random(width);
let firstY = random(height);
flowers[i] = makingFlower(firstX,firstY)
}
// inital placement for grass
for (let gx = 0; gx < 400; gx++) {
let grassX = random(width);
let grassY = random(height);
grass[gx] = makingGrass(grassX,grassY);
}
// initial placement for clouds
for (let j = 0; j < 7; j++) {
let cloudx = random(width);
let cloudy = random(height);
clouds[j] = makingCloud(cloudx, cloudy);
}
}
function draw() {
background(105,130,80);
//drawing the grass
updateAndDisplayGrass();
addingGrass();
removingGrass();
//drawing the flowers
updateAndDisplayflowers();
addingFlowers();
removingFlowers();
// drawing the clouds
updateAndDisplayClouds();
addingClouds();
removingClouds();
}
////////////////////////////////////flowers//////////////////////////
///removing flowers from the array once they go off screen
function removingFlowers() {
var keeping = [];
for (var i = 0; i < flowers.length; i++) {
if (flowers[i].x + flowers[i].r > 0) {
keeping.push(flowers[i]);
}
}
flowers = keeping; //keeping certain flowers in the flowers array
}
//update all the flowers in the array
function updateAndDisplayflowers(){
for (var i = 0; i < flowers.length; i++){
flowers[i].move();
flowers[i].display();
}
}
//adding new flowers to the array according to a certain liklihood
function addingFlowers() {
var newflowerliklihood = 0.05;
var initialX = random(width);
var initialY = 0;
if (random(0,1) < newflowerliklihood) {
flowers.push(makingFlower(initialX,initialY));
}
}
//the flower object
function makingFlower(firstX,firstY) {
var flr = {x: firstX,
y: firstY,
r: round(random(10,40)),
move: moveflowers,
display: showflowers}
return flr;
}
//specifying the drawing of the flower
function showflowers() {
noStroke();
fill(230, 80, 50); //red petals
ellipse(this.x+3, this.y, 3, 4);
ellipse(this.x-3, this.y, 3, 4);
ellipse(this.x, this.y-3, 3, 4);
ellipse(this.x, this.y+3, 3, 4);
fill(230, 130, 50); // orange center
ellipse(this.x, this.y, 5, 5);
fill(90, 40, 30); // red inner center
ellipse(this.x, this.y, 1, 1);
}
//speciftying the movement of the flower
function moveflowers() {
this.y = this.y + 1
}
/////////////////////////////////// grass////////////////////////////////
function removingGrass() {
var keepingGrass = [];
for (var i = 0; i < grass.length; i++) {
if (grass[i].x > -10) {
keepingGrass.push(grass[i]);
}
}
grass = keepingGrass;
}
function updateAndDisplayGrass(){
for (var i = 0; i < grass.length; i++){
grass[i].move();
grass[i].display();
}
}
function addingGrass() {
var newgrassliklihood = 0.5;
var initialX = random(width);
var initialY = 0;
if (random(0,1) < newgrassliklihood) {
grass.push(makingGrass(initialX,initialY));
}
}
function makingGrass(grassX,grassY) {
var gss = {x: grassX,
y: grassY,
move: moveGrass,
display: showGrass}
return gss;
}
function showGrass() {
strokeWeight(random(1,2));
stroke(130,160,140);
line(this.x, this.y, this.x-2, this.y+2);
}
function moveGrass() {
this.y = this.y + 1
}
/////////////////////clouds///////////////////////////////////////////////
function removingClouds() {
var keepingClouds = [];
for (var i = 0; i < clouds.length; i++) {
if (clouds[i].x > -10) {
keepingClouds.push(clouds[i]);
}
}
clouds = keepingClouds;
}
function updateAndDisplayClouds(){
for (var i = 0; i < clouds.length; i++){
clouds[i].move();
clouds[i].display();
}
}
function addingClouds() {
var newcloudliklihood = 0.02;
var initialX = random(width);
var initialY = 0;
if (random(0,1) < newcloudliklihood) {
clouds.push(makingCloud(initialX,initialY));
}
}
function makingCloud(cloudX,cloudY) {
var cld = {x: cloudX,
y: cloudY,
move: moveCloud,
display: showCloud}
return cld;
}
function showCloud() {
noStroke();
fill(150,180,190,20); // light blue
beginShape();
vertex(this.x , this.y);
quadraticVertex(this.x - 236, this.y - 351 , this.x + 7 , this.y - 357);
bezierVertex(this.x -17, this.y -215, this.x + 132, this.y + 180, this.x, this.y);
endShape(CLOSE)
}
function moveCloud() {
this.y = this.y + 3
}
a landscape by Gustav Klimt I was inspired by
For this project, I was really inspired by the prompt of looking outside of a window. I love flowers and the peacefulness of watching clouds pass. I also love the colors in Gustav Klimpt’s landscapes, so I really wanted to incorporate this into my project, as well as get some practice drawing curves.
//Julia Nishizaki
//Section B
//jnishiza@andrew.cmu.edu
//Project 11 - Generative Landscape
var landscapeScale = 0.005; //detail in hills
var landscapeSpeed = 0.00075; //speed of hills going by
var hillColor = '#92CA6D'; //light green
var houses = []; //array for houses
var trees = []; //array for trees
var train = { ////train variables
wY: 200, //Y of windows
wW: 325, //width of windows
wH: 275, //height of windows
corners: 30, //roundness of window corners
wWeight: 25, //stroke weight of light gray
backgroundColor: 255, //white
mainColor: '#475AA8', //light blue
wColor: '#2A357A', //dark blue, color of window and seats
divXL: 61, //X coordinate of left divider
divXR: 419, //X coordinate of right divider
}
function setup() {
createCanvas(480, 480);
for (var i = 0; i < 5; i ++) { //first houses
var rx = random(width);
houses[i] = makeHouses(rx);
}
for (var i = 0; i < 3; i ++) { //first trees
var tx = random(width);
trees[i] = makeTrees(tx);
}
frameRate(30);
}
function draw() {
background('#8ED9EF'); //blue sky
//creates hills in the background
stroke(hillColor);
for (var x = 0; x < width; x ++) {
var l = (x * landscapeScale) + (millis() * landscapeSpeed);
var y = map(noise(l), 0, 1, 100, 230); //constrains hills
line(x, y, x, height); //creates vertical lines, forming a solid shape
}
displayHouses(); //houses
removeOldHouses();
addHouses();
displayTrees(); //trees
removeOldTrees();
addTrees();
drawTrain(); //train
}
function displayHouses() { //displays and updates house location
for (var i = 0; i < houses.length; i ++) {
houses[i].move();
houses[i].draw();
}
}
function removeOldHouses() { //gets rid of old houses, puts the houses that are still on the canvas in a new array
var housesToKeep = [];
for (var i = 0; i < houses.length; i ++) {
if (houses[i].x + houses[i].breadth > 0) {
housesToKeep.push(houses[i]);
}
}
houses = housesToKeep;
}
function addHouses() { //adds new houses into the array
if (random(0, 1) < 0.02) {
houses.push(makeHouses(width));
}
}
function moveHouses() { //moves the houses
this.x += this.speed;
if (this.x < -this.breadth) {
this.x == width + this.breadth;
}
}
function drawHouses() { //draws the houses
noStroke();
rectMode(CORNER);
fill(this.r, this.g, this.b); //randomizes color
push();
translate(this.x, this.y);
rect(0, -this.height, this.breadth, this.height); //house rectangle
//roof
fill(255);
triangle(-2, -this.height + 1, this.breadth + 2, -this.height + 1, this.breadth / 2, -this.height - this.roofH);
//door
rect(this.doorX, - this.doorH, this.doorW, this.doorH);
pop();
}
function makeHouses(locationX) { //house variables
var hse = {x: locationX,
y: random(225, 275),
r: random(255),
g: random(255),
b: random(255),
roofH: round(random(10, 25)),
height: round(random(25, 50)),
breadth: round(random(30, 60)),
doorX: random(10, 20),
doorW: 10,
doorH: 15,
speed: -6.0,
move: moveHouses,
draw: drawHouses}
return hse;
}
//trees
function displayTrees() { //dispays and updates tree locations
for (var i = 0; i < trees.length; i ++) {
trees[i].movet();
trees[i].drawt();
}
}
function removeOldTrees() { //gets rid of old trees
var treesToKeep = [];
for (var i = 0; i < trees.length; i ++) {
if (trees[i].xt + trees[i].breadtht > 0) {
treesToKeep.push(trees[i]);
}
}
trees = treesToKeep;
}
function addTrees() { //adds new trees
if (random(0, 1) < 0.1) {
trees.push(makeTrees(width));
}
}
function moveTrees() { //moves trees
this.xt += this.speedt;
if (this.xt < -this.breadtht) {
this.xt == width + this.breadtht;
}
}
function drawTrees() { //draws trees
noStroke();
rectMode(CORNER);
colorMode(HSB, 100); //switches color mode to HSB to assist with random colors
fill(this.ht, 55, this.bt); //random colors between yellow-green to green
push();
translate(this.xt, height * 3 / 4);
rect(0, -this.heightt, this.breadtht, this.heightt, 50, 50, 0, 0);
pop();
}
function makeTrees(locationX) { //tree variables
var trs = {xt: locationX,
bt: random(50, 85),
ht: random(17, 25),
heightt: round(random(50, 160)),
breadtht: round(random(100, 130)),
speedt: -10.0,
movet: moveTrees,
drawt: drawTrees}
return trs;
}
//train
function drawTrain() {
colorMode(RGB);
drawWindow(width / 2); //draws center window
drawWindow(-118); //draws left window
drawWindow(width + 118); //draws right window
//light blue panels
noStroke();
rectMode(CORNER);
fill(train.mainColor);
rect(0, 0, width, train.wY - (train.wH / 2) - 10); //top panel
rect(0, train.wY + (train.wH / 2) + 10, width, height - (train.wY + (train.wH / 2)) - 10); //bottom panel
//seats
drawSeats(train.divXL, 0, 0, 40); //left seat
drawSeats(train.divXR, width - 200, 40, 0); //right seat
//table
rectMode(CENTER);
rect(width / 2, height - 105, 150, 20, 5, 5, 5, 5);
//section dividers, light gray
drawDividers(train.divXL);
drawDividers(train.divXR);
}
function drawWindow(x) { //creates center window
rectMode(CENTER);
noFill();
stroke(train.backgroundColor); //creates light gray area around the windows
strokeWeight(train.wWeight);
rect(x, train.wY, train.wW + train.wWeight, train.wH + train.wWeight, train.corners, train.corners, train.corners, train.corners);
stroke(train.wColor); //creates blue window border
strokeWeight(10);
rect(x, train.wY, train.wW, train.wH, train.corners, train.corners, train.corners, train.corners);
}
function drawSeats(x1, x2, UL, UR) {
fill(train.wColor);
rect(x1 - 45, height - 200, 90, 200, 30, 30, 0, 0); //seat back
rect(x2, height - 50, 200, 50, UL, UR, 0, 0); //left seat cushions
}
function drawDividers(x) {
strokeWeight(5);
stroke(200);
line(x, train.wY - (train.wH / 2) - 7.5, x, height); //line dividing sections
}
For this project, I wanted to create a landscape outside of a train window. I decided to use three layers, some bushes or trees in the foreground, houses in the middle ground, and hills in the background. I tried to change the speeds of the different layers, with the tree layer the fastest and the hill layer the slowest, in order to give the illusion of perspective, and that you’re looking out of a window as everything flies by.
I had started out wanting to do a sunset, with the view of a car driving by it. I didn’t want to create a jagged moving landscape, so I decided to do a desert instead. I was first going to make cactuses, but then I made the ground black and realized I wanted a more futuristic look. So I decided my image would have the sunset, black ground, and then geometric shapes with their shadows. Because I had used the bezier() function in the past, I decided to use that for the sunset, having the anchor parts react with the sun, almost like the sky was melting.
During the project I changed my objects from pyramids to stars to, finally, sailboats. I added to the black water horizon, putting color lines under the sun to look like a water reflection, and adding vertical lines to the water with an invisible ball pushing them to look like the boats were pushing the current.
// Nawon Choi
// Section C
// nawonc@andrew.cmu.edu
// Project-11 Landscape
// var buildings = [];
var trainCars = [];
var shapes = [];
// canvas height - 50
var yHorizon = 200 - 50;
function setup() {
createCanvas(480, 200);
// create an initial train car
var rw = random(100, 150);
trainCars.push(makeTrainCar(-50, rw));
frameRate(10);
}
function draw() {
background("#A1C6EA");
displayHorizon();
updateAndDisplayTrainCars();
removeTrainCarsThatHaveSlippedOutOfView();
addNewCars();
// railroad sign
stroke(0);
strokeWeight(2);
line(width - 50, height / 3, width - 50, yHorizon);
fill("yellow");
ellipse(width - 50, height / 3, 40, 40);
fill(0);
textSize(40);
text("X", width - 62, height / 2.5);
}
function updateAndDisplayTrainCars(){
// Update the building's positions, and display them.
for (var i = 0; i < trainCars.length; i++){
trainCars[i].move();
trainCars[i].display();
}
}
function removeTrainCarsThatHaveSlippedOutOfView(){
// If a building has dropped off the left edge,
// remove it from the array. This is quite tricky, but
// we've seen something like this before with particles.
// The easy part is scanning the array to find buildings
// to remove. The tricky part is if we remove them
// immediately, we'll alter the array, and our plan to
// step through each item in the array might not work.
// Our solution is to just copy all the buildings
// we want to keep into a new array.
var carsToKeep = [];
for (var i = 0; i < trainCars.length; i++){
if (trainCars[i].x + trainCars[i].w > 0) {
carsToKeep.push(trainCars[i]);
}
}
trainCars = carsToKeep; // remember the surviving buildings
}
function addNewCars() {
var l = trainCars.length - 1;
var newW = floor(random(100, 150));
var newX = 0 - newW;
// only add a new car after the last one is completely revealed
if (trainCars[l].x >= 0) {
trainCars.push(makeTrainCar(newX, newW));
}
}
// method to update position of the car every frame
function carMove() {
this.x += 3;
}
function carDisplay() {
// draw car body
fill(this.cr, this.cg, this.cb);
rect(this.x, yHorizon - (this.h + 3), this.w, this.h);
// draw wheels
fill("#6b6e6a");
if (this.nWheels >= 2) {
ellipse(this.x + 5, yHorizon, 10, 10);
ellipse(this.x + this.w - 5, yHorizon, 10, 10);
if (this.nWheels == 4) {
ellipse(this.x + 15, yHorizon, 10, 10);
ellipse(this.x + this.w - 15, yHorizon, 10, 10);
} else if (this.nWheels == 3) {
ellipse(this.x + (this.w / 2), yHorizon, 10, 10);
}
}
}
function makeTrainCar(birthLocationX, carWidth) {
var car = {x: birthLocationX,
w: carWidth,
h: floor(random(50, 70)),
nWindows: floor(random(0, 3)),
nWheels: floor(random(2, 5)),
cr: floor(random(0, 255)),
cg: floor(random(0, 255)),
cb: floor(random(0, 255)),
move: carMove,
display: carDisplay}
return car;
}
function displayHorizon(){
noStroke();
// grass
fill("#3a6933");
rect(0, yHorizon, width, 50);
// train track
fill("#35524A");
rect (0, yHorizon, width, 5);
}
For this project, I tried to create a moving landscape in which the subject was moving, but the viewer was still. I depicted a railroad crossing of train cars with varying widths, heights, colors, and wheel numbers. It was interesting to play with random vs fixed variables. For instance, the train cars had to generate right after the last car, instead of at a random frequency. I also tried to create more visual interest by adding a railroad crossing sign in the foreground. I think if I had more time, I would have added interesting patterns to each car, such as windows or texture to the cars.
In this project, I was able to create a generative landscape with customized features. I really enjoyed sceneries that has a complete reflection on a water surface, and decided to create an animation with a mountain and its reflection on the lake. I added a fun component of ducks swimming around to create a fun element.
Brainstorming process
//Charmaine Qiu
//Section E
//charmaiq@andrew.cmu.edu
//Project 11
//set the speed and detail for terrain
var terrainSpeed = 0.0005;
var terrainDetail = 0.008;
//create empty array for ducks on screen
var ducks = [];
function setup() {
createCanvas(480, 200);
frameRate(10);
//set the number of ducks that appears in the beginning randomly on screen
for (var i = 0; i <3; i++){
var rx = random(width);
ducks[i] = makeDuck(rx);
}
}
function draw() {
//set background visuals
//the sky
background('#95dddd');
//the river
fill('#419696')
noStroke();
rect(0, height / 2, width, height);
//the sun and its reflection
fill('red');
ellipse(width - 60, 10, 60, 60);
fill('#6e1616');
ellipse(width - 60, height - 10, 60, 60);
//draw mountain and ripple function
mountains();
ripples();
//draw the ducks
push();
translate(0.1 * width, 0.1 * height);
scale(0.8);
updateAndDisplayDucks();
removeDucksThatHaveSlippedOutOfView();
addNewDucksWithSomeRandomProbability();
pop();
}
function mountains(){
//create the mountain
fill('#e1a952');
noStroke();
beginShape();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
var y = map(noise(t), 0,1, 0, height / 2);
vertex(x, y);
}
vertex(width, height/2);
vertex(0, height/2)
endShape();
//create the reflection
fill('#dd5a62');
beginShape();
noStroke();
for (var x = 0; x < width; x++) {
var t = (x * terrainDetail) + (millis() * terrainSpeed);
//inverse the y component to flip the mountain upside-down
var y = map(noise(t), 0,1, height, height / 2);
vertex(x, y);
}
vertex(width, height/2);
vertex(0, height/2)
endShape();
}
function ripples(){
//create the ripples
frameRate(7);
stroke(255);
//set individual random values for x and y coordinates of ripples
rX = random(width / 2 - 50, width / 2 + 50);
rY = random(height / 2 + 10, height);
rX2 = random(width / 2 - 50, width / 2 + 50);
rY2 = random(height / 2 + 10, height);
rX3 = random(width / 2 - 50, width / 2 + 50);
rY3 = random(height / 2 + 10, height);
//set individual random values for width and weight of ripples
rWidth = random(5, 20);
rWeight = random(1, 4);
rWidth2 = random(5, 20);
rWeight2 = random(1, 4);
rWidth3 = random(5, 20);
rWeight3 = random(1, 4);
//draw out the lines of ripples
strokeWeight(rWeight);
line(rX, rY, rX + rWidth, rY);
strokeWeight(rWeight2);
line(rX2, rY2, rX2 + rWidth2, rY2);
strokeWeight(rWeight3);
line(rX3, rY3, rX3 + rWidth3, rY3);
}
function updateAndDisplayDucks(){
// Update the duck's positions, and display them.
for (var i = 0; i < ducks.length; i++){
ducks[i].move();
ducks[i].display();
}
}
function removeDucksThatHaveSlippedOutOfView(){
// copy all the ducks that's kept into a new array.
var ducksToKeep = [];
for (var i = 0; i < ducks.length; i++){
if (ducks[i].x + ducks[i].breadth > 0) {
ducksToKeep.push(ducks[i]);
}
}
ducks = ducksToKeep; //remember the surviving ducks
}
function addNewDucksWithSomeRandomProbability() {
// With a very tiny probability, add a new duck to the end.
var newDuckLikelihood = 0.007;
if (random(0,1) < newDuckLikelihood) {
ducks.push(makeDuck(width));
}
}
// method to update position of duck every frame
function duckMove() {
this.x += this.speed;
}
function duckDisplay() {
// draw the ducks
var headHeight = 20;
fill(255);
noStroke();
push();
//translate duck to lower part of canvas
translate(this.x, height - 40);
ellipse(0, -headHeight, this.breadth, headHeight);
fill(0);
ellipse(0, -headHeight, 5, 5);
fill("#70547c");
arc(10, -10, 30, 30, 0, PI);
fill("#f8e184");
arc(10, -10, 10, 10, 0, PI);
fill("green");
arc(-10, -20, 10, 10, 0, PI);
pop();
}
//the function to create the duck object
function makeDuck(birthLocationX) {
var mdk = {x: birthLocationX,
breadth: 20,
speed: -1.0,
move: duckMove,
display: duckDisplay}
return mdk;
}