I took inspiration from a scene in cyberpunk edgerunner and made a city landscape based on that. I am surprised by the flexibility of object, the properties can be manipulated in different ways to create completely different stuff. For example, the pillars, foreground, and background buildings are created with one single object.
//Jason Jiang
//Section E
//setting up arrays of objects
var bldg = [];
var bldgBack = []
var pillar = []
var vhc = []
//number of objects in each array
var bldgN = 6;
var bldgBackN = 11;
var vhcN = 2;
//color palatte for buildings
var palatte = ['#7670b2', '#5ab6b0', '#5ab6b0', '#3f5c60', '#1c4167', '#3f5c60', '#7e9868'];
//image links of assets
var facadeLink = [
"https://i.imgur.com/oPA4x4y.png",
"https://i.imgur.com/xeOW3sz.png",
"https://i.imgur.com/gbr6ySL.png",
"https://i.imgur.com/WqUehK3.png"];
var facadeImg = [];
var vehicleLink = [
"https://i.imgur.com/gFtwhqV.png",
"https://i.imgur.com/KX1dLCi.png",
"https://i.imgur.com/Fo43Kep.png"];
var vehicleImg = [];
//load assets
function preload(){
train = loadImage("https://i.imgur.com/BFxe31d.png");
for (var i = 0; i < facadeLink.length; i++){
facadeImg[i] = loadImage(facadeLink[i]);
}
for (var i = 0; i < vehicleLink.length; i++){
vehicleImg[i] = loadImage(vehicleLink[i]);
}
}
function setup() {
createCanvas(400, 200);
imageMode(CENTER);
colorMode(HSB);
//create front building arrays
for(var i = 0; i < bldgN; i++){
//randomly pick color from array
var palatteIndex = floor(random(palatte.length));
//randomly pick an image from array
var facadeIndex = floor(random(facadeImg.length));
var b = building(80*i, random(-height/3, height/3), random(80, 100), color(palatte[palatteIndex]), facadeImg[facadeIndex]);
bldg.push(b);
}
//create back building arrays
for(var i = 0; i < bldgBackN; i++){
var b = building(40*i, random(150), 40, color(20, 10, 30, 0.5), -1);
bldgBack.push(b);
}
//create pillars
for (var i = 0; i < 2; i++) {
var p = building(200*i, 70, 20, color(80), -1);
pillar.push(p);
}
//creating vehicles
for (var i = 0; i < 2; i++) {
//randomly pick an image from array
var vehicleIndex = floor(random(vehicleImg.length));
//randomize vehicle moving direction
if (random(1) <= 0.5){
//vehicles from left to right
var v = vehicle(random(-width/2, 0), random(50, 150), random(5, 10), vehicleImg[vehicleIndex]);
}
else{
//vehicles from right to left
var v = vehicle(random(width, 1.5*width), random(50, 150), random(-5, -10), vehicleImg[vehicleIndex]);
}
vhc.push(v);
}
}
function draw() {
background(200, 20, 100);
//update information in each frame
updateObjs();
updateArray();
//add train image
image(train, 200, 90);
}
function updateObjs(){
//updating building background
for(var i = 0; i < bldgBack.length; i++){
bldgBack[i].move(2);
bldgBack[i].display();
}
//updating building foreground
for(var i = 0; i < bldg.length; i++){
bldg[i].move(5);
bldg[i].display();
}
//updating pillars
for(var i = 0; i < pillar.length; i++){
pillar[i].move(5);
pillar[i].display();
}
//updating vehicles
for (var i = 0; i < vhc.length; i++) {
vhc[i].move();
vhc[i].display();
}
}
//displaying buildings
function buildingDisplay(){
//draw rectangles
noStroke();
fill(this.color);
rect(this.x, this.y, this.w, height-this.y);
var centerX = this.x + 0.5*this.w ;
var centerY = this.y + 0.5*(height - this.y);
//see if the detail property of object is an image, since not pillars and background buildings dont need facade details on them
if (this.detail != -1){
//add details on building facade
push();
translate(centerX, centerY);
image(this.detail, 0, 0, 0.8*this.w, 0.95*(height-this.y));
pop();
}
}
//update building position
function buildingMove(s){
this.x -= s;
}
//displaying vehicles
function vehicleDisplay(){
push();
//flip the image if going from right to left
if(this.s < 0){
scale(-1, 1);
image(this.detail, -this.x, this.y);
}
else{
image(this.detail, this.x, this.y);
}
pop();
}
//update vehicles position and age
function vehicleMove(){
this.x += this.s;
this.age += 1;
}
function updateArray(){
//replacing foreground buildings outside canvas
for(var i = 0; i < bldg.length; i++){
if (bldg[i].x <= -bldg[i].w){
var palatteIndex = floor(random(palatte.length));
var facadeIndex = floor(random(facadeImg.length));
var b = building(400, random(-height/3, height/3), random(80, 100), color(palatte[palatteIndex]), facadeImg[facadeIndex]);
bldg[i] = b;
}
}
//replacing background buildings outside canvas
for(var i = 0; i < bldgBack.length; i++){
if (bldgBack[i].x <= -bldgBack[i].w){
var b = building(400, random(150), 40, color(20, 10, 30, 0.5), -1);
bldgBack[i] = b;
}
}
//replacing pillars outside canvas
for(var i = 0; i < pillar.length; i++){
if (pillar[i].x <= -pillar[i].w){
var p = building(400, 70, 20, color(80), -1);
pillar[i] = p;
}
}
//replacing vehicles after a certain time
for(var i = 0; i < vhc.length; i++){
if (vhc[i].age > 200){
var vehicleIndex = floor(random(vehicleImg.length));
if (random(1) <= 0.5){
var v = vehicle(random(-width/2, 0), random(50, 150), random(5, 10), vehicleImg[vehicleIndex]);
}
else{
var v = vehicle(random(width, 1.5*width), random(50, 150), random(-5, -10), vehicleImg[vehicleIndex]);
}
vhc[i] = v;
}
}
}
//create building objects
function building(buildingX, buildingY, buildingWidth, buildingColor, buildingDetail) {
var b = { x: buildingX,
y: buildingY,
w: buildingWidth,
color: buildingColor,
detail: buildingDetail,
display: buildingDisplay,
move: buildingMove
}
return b;
}
//create vehicle objects
function vehicle(vehicleX, vehicleY, vehicleSpeed, vehicleDetail) {
var v = { x: vehicleX,
y: vehicleY,
s: vehicleSpeed,
age: 0,
detail: vehicleDetail,
display: vehicleDisplay,
move: vehicleMove
}
return v;
}