sketchvar buildings = [];
var people = [];
var hillVar= 0.009
function setup() {
createCanvas(480, 480);
// create an initial collection of buildings
for (var i = 0; i < 10; i++){
var rx = random(width);
var ry = random(10, 50);
buildings[i] = makeBuilding(rx);
people[i] = makePeople(rx);
}
frameRate(10);
}
function draw() {
background(33, 28, 77);
drawHill()
displayStatusString();
displayHorizon();
updateAndDisplayBuildings();
removeBuildingsThatHaveSlippedOutOfView();
addNewBuildingsWithSomeRandomProbability();
updateAndDisplayPeople();
removePeople();
addNewPeople()
drawTrainCart()
}
function makePeople(birthLocationX) {
var k ={x: birthLocationX,
breadth:round(random(9,15)),
speed:-4,
peopleHeight:round(random(24,30)),
move:peopleMove,
display:peopleDisplay,
color:color(random(50,240),random(50,240),random(50,240))}
return k
}
function peopleMove() {
this.x += this.speed
}
function peopleDisplay() {
push();
fill(this.color)
translate(this.x, height-190);
strokeWeight(1);
stroke(0);
ellipse(-0,this.peopleHeight/2,this.breadth,this.peopleHeight) //body
fill(160)
ellipse(0,-this.peopleHeight/2+13,8,8) //head
pop()
}
function updateAndDisplayPeople(){
for (var i = 0; i <people.length; i++){
people[i].move();
people[i].display()
}
}
function removePeople(){
var peopleToKeep = [];
for (var i = 0; i <people.length; i++){
if (people[i].x+people[i].breadth>0){
peopleToKeep.push(people[i])
}
}
people = peopleToKeep
}
function addNewPeople(){
var newPeopleLikelihood=0.1;
if(random(0,1)<newPeopleLikelihood){
people.push(makePeople(width));
}
}
function drawTrainCart(){
noStroke()
var cartwidth = 70
fill(66, 85, 102)
rect(0,0,cartwidth,height)
rect(480-cartwidth,0,cartwidth,height)
rect(cartwidth,0,width-(cartwidth*2),50)
fill(161, 104, 80)
quad(cartwidth,height-120,width-cartwidth,height-120,480,480,0,480)
push()
//drink
fill(232, 184, 100)
quad(320,460-10,315,430-10,365,430-10,360,460-10)
arc(340,460-10,40,13,0,PI,OPEN)
fill(210, 184, 100)
ellipse(340,430-10,50,15)
//cup
fill(255,255,255,80);
quad(320,460-10,310,400-10,370,400-10,360,460-10)
stroke(174, 203, 230)
strokeWeight(4)
line(320,460-10,310,400-10)
line(370,400-10,360,460-10)
arc(340,460-10,40,13,0,PI,OPEN)
fill(191,151,135)
ellipse(340,400-10,60,17)
noStroke()
fill(255, 246, 199,32)
quad(140,0,340,0,500,480,-20,480)
pop()
}
function drawHill() {
push()
noStroke()
fill(6, 31, 12)
beginShape()
for (var h = 0; h<width; h++){
var a = (h*hillVar)+(millis()*0.0002)
var y = map(noise(a),0,1,height/8,height/9*5);
vertex(h,y)
}
vertex(480,480);
vertex(0,480)
endShape()
pop()
}
function updateAndDisplayBuildings(){
// Update the building's positions, and display them.
for (var i = 0; i < buildings.length; i++){
buildings[i].move();
buildings[i].display();
//trees[i].move();
//trees[i].display();
}
}
function removeBuildingsThatHaveSlippedOutOfView(){
// 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 buildingsToKeep = [];
for (var i = 0; i < buildings.length; i++){
if (buildings[i].x + buildings[i].breadth > 0) {
buildingsToKeep.push(buildings[i]);
}
}
buildings = buildingsToKeep; // remember the surviving buildings
}
function addNewBuildingsWithSomeRandomProbability() {
// With a very tiny probability, add a new building to the end.
var newBuildingLikelihood = 0.008;
if (random(0,1) < newBuildingLikelihood) {
buildings.push(makeBuilding(width));
}
}
// method to update position of building every frame
function buildingMove() {
this.x += this.speed;
}
// draw the building and some windows
function buildingDisplay() {
push()
var floorHeight = 20;
var bHeight = this.nFloors * floorHeight;
fill(12, 12, 51);
stroke(185);
push();
translate(this.x, height - 170);
rect(0, -bHeight, this.breadth, bHeight);
noStroke()
triangle(0,-bHeight+1,0+(this.breadth/2),-bHeight-10,this.breadth,-bHeight+1)
stroke(200);
for (var i = 0; i < this.nFloors; i++) {
fill(247, 235, 111)
strokeWeight(random(0.1,2))
rect(5, -15 - (i * floorHeight), this.breadth - 10,5);
}
strokeWeight(3)
line(0+(this.breadth/2),-bHeight-10,this.breadth+5,-bHeight+1)
line(0+(this.breadth/2),-bHeight-10,-5,-bHeight+1)
pop();
}
function makeBuilding(birthLocationX) {
var bldg = {x: birthLocationX,
breadth: 50,
speed: -3.0,
nFloors: round(random(2,8)),
move: buildingMove,
display: buildingDisplay}
return bldg;
}
function displayHorizon(){
stroke(0);
line (0,height-170, width, height-170);
fill(40, 40, 41)
rect(0,height-170,width,170)
}
function displayStatusString(){
noStroke();
fill(0);
var statusString = "# Buildings = " + buildings.length;
text(statusString, 5,20);
}
I was inspired by the view of Hong Kong where there are many skyscrapers but they are always accompanied by a mountain in the backdrop. All of Hong Kong’s major financial districts are close to tall mountain ranges. This creates a very interesting composition in my opinion. I included the people of varying height and color to suggest how crowded it is in Hong Kong. The image shows a person viewing out of a train that has a table attached to the window drinking a glass of apple juice. The surrounding is dark and I think that helps the image tells a more interesting story.