LookingOutwards-11

Amber Vittoria’s illustration for Gucci Knitwear

use of soft and blurred colors, rounded body features

Amber Vittoria is a New York based artist and illustrator who is skillfully good at combing the analog and the digital in illustration. I came across an illustration project from her that is a commission for Gucci’s DIY knitwear collection. Exclusively working with female form and body parts in his drawing, she visualizes all kinds of stylized bodies into fashion campaign. The beginning of this practice is because of she recognizes that most of women cannot relate to the unrealistic image of women being used in fashion content and she hope to create these unique characters in a storytelling way. The soft and blurred colors portraits non-traditional, or non-idealised, representations of the female form with rounded body features and colorful flowers. Besides the visuals, I also admire how she take advantage of her creative experience to discuss these topics with the public.

Artist Website: https://www.ambervittoria.com/

LO 11 – Female Practitioners

Creator: Allison Parrish
Piece: Semantic Similarity Chatbot
Date: 2018

Allison Parrish is a programmer and a linguist. Allison currently works at NYU as a faculty member. She also graduated from NYU with her master’s degree. A lot of her projects involve bots and poetry as these are the topics she is most interested in. All of her projects that I have seen mix language and coding to create unique tools and artwork. The Semantic Similarity Chatbot is a creation of hers which allows people to text with historical figures of their choice. She wrote programs that dissected the way that different characters wrote and then added AI that could replicate similar patterns. One of the coolest aspects of this project in my opinion is that fact that it was created for her students to modify. She started with a few people from history, but as a project, she had her students write more code to add even more unique figures. I really enjoy the concept of this and love that she taught her students through such an interesting project.

https://gist.github.com/aparrish/114dd7018134c5da80bae0a101866581

bot screenshot

Project-11

sketch
var 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.

LO-11

Eva Schindling explores the boundaries of technology, science, design, and art through her large collection of projects. Her projects include sculptures, digital imagings, and software systems. I was particularly interested in her work that involves physics and science that affects our daily lives such as sound, light, and motion. Schindling demonstrates superb data visualization skills in her project, Liquid Sound Collision. The software uses fluid dynamic qualities to visualize and mix sound. The relationship between the amplitude of the music and the velocity of the water creates a visually and auditory stunning piece of work. I found her other project, “Ana + Kata”, very interesting. She explores 4-dimensional relationships and represents them as solid volumes. The resulting solids resemble ghosted volumes that feel like an optical illusion. It feels intuitive at first to understand the shape, but upon careful inspection, some lines don’t match up and create a very interesting illusion. I feel that this piece of work has really captivated me with how I could interpret the work.

http://www.evsc.net/category/home

LO – 11

For this week’s looking outwards focusing on Women Practitioners, I decided to research into Angela Washko, who ‘is an artist, writer, and facilitator devoted to creating new forums for discussions of feminism in the spaces most hostile toward it.’ I thought that because she purposefully works in realms and topics of feminism and is currently a tenure-track Assistant Professor of Art at Carnegie Mellon University, it would be especially appropriate for this week’s prompt.

I looked at her project The Game: The Game, which explores and presents the issues and circumstances present around the practices of male pickup artists, which is then presented in the format of a dating simulator. It provides an interesting and female centric look at the social constructs of dating and the systematically dangerous and manipulative implications of the culture. It provides a very interesting look into the language and social formalities of ‘pick-up’ culture and its psychological/predatory implications.

I really liked the way she chose the explore the topic through a somewhat morbid lens without holding back or romanticizing the issue, particularly because dating simulators tend to over-romanticize certain behaviors that the audience as a whole could do to become more critical of. The interactive quality of the game brings another layer of immersion into the game as well, illustrating how well the medium supports the topic/issue that is being presented.

Project 11-Landscape

sketch
/*
Lauren Kenny
lkenny@andrew.cmu.edu
Section A

This draws a moving scene.
*/

var buildings = [];
var clouds = [];
var hills = [];
var noiseParam=0;
var noiseStep=0.05;


function setup() {
    createCanvas(480, 300); 
    
    // create an initial collection of buildings
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    frameRate(10);

    // create an initial collection of clouds
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        clouds[i] = makeCloud(rx);
    }

    // creates initial hills
    for (var i=0; i<width/5; i++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height);
        hills.push(value);
        noiseParam+=noiseStep;
    }

}


function draw() {
    background(255,140,102);
    // draws outline around canvas
    stroke(0);
    strokeWeight(10);
    fill(255,140,102);
    rect(0,0,width,height);

    // draws sun
    strokeWeight(3);
    fill(183,52,52);
    circle(width/2,height/1.2,400);
    fill(229,134,81);
    circle(width/2,height/1.2,300);
    fill(225,185,11);
    circle(width/2,height/1.2,200);
    
    
    // begins the hill shape
    var x=0;
    stroke(0);
    strokeWeight(3);
    fill(93, 168, 96);
    beginShape();
    curveVertex(0, height);
    curveVertex(0, height);
    // loops through each of the values in the hills array
    for (i=0; i<hills.length; i++) {
        curveVertex(x, hills[i]);
        x+=15;
    }
    curveVertex(width, height);
    curveVertex(width, height);
    endShape();
    //removes the first value from the list and appends a new one
    //onto the end to make the terrain move
    hills.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    hills.push(value);
    noiseParam+=noiseStep;

    displayHorizon();

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

    updateAndDisplayClouds();
    removeCloudsThatHaveSlippedOutofView();
    addNewCloudsWithSomeRandomProbability();

    
}


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

function updateAndDisplayClouds() {
    // update the clouds' positions and display them
    for (var i=0; i<clouds.length; i++) {
        clouds[i].move();
        clouds[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 removeCloudsThatHaveSlippedOutofView() {
    var cloudsToKeep = [];
    for (var i=0; i<clouds.length; i++) {
        if (clouds[i].x + clouds[i].width>0) {
            cloudsToKeep.push(clouds[i]);
        }
    }
    clouds = cloudsToKeep;
}


function addNewBuildingsWithSomeRandomProbability() {
    // add a new building
    var newBuildingLikelihood = 0.007; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

function addNewCloudsWithSomeRandomProbability() {
    // add a new cloud
    var newCloudLikelihood = 0.001;
    if (random(0,1) < newCloudLikelihood) {
        clouds.push(makeCloud(width));
    }
}


// method to update position of building every frame
function buildingMove() {
    this.x += this.speed;
}

// updates the position of every cloud frame
function cloudMove() {
    this.x += this.speed;
}
    

// draw the building and some windows
function buildingDisplay() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(53,156,249); 
    stroke(0);
    strokeWeight(3); 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    fill(255);
    //rect(this.breath/2, bHeight-20, this.breath/5, bHeight/5);
    rect(5, -35, 10, (bHeight/5));
    pop();

}

function cloudDisplay() {
    fill(255);
    noStroke();
    //stroke(0);
    //strokeWeight(3);
    push();
    //translate(this.x, height-40);
    ellipse(this.x, this.y, this.width, this.height);
    ellipse(this.x+this.width/2, this.y+3, this.width, this.height);
    ellipse(this.x-this.width/2, this.y+3, this.width, this.height);
    pop();
}


function makeBuilding(startX) {
    var bldg = {x: startX,
                breadth: 50,
                speed: -1.0,
                nFloors: round(random(2,8)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function makeCloud(startX) {
    var cloud = {x: startX,
                y: random(20,90),
                width: random(10,20),
                height: random(10,20),
                speed: -1.0,
                move: cloudMove,
                display: cloudDisplay}
    return cloud;
}


function displayHorizon(){
    noStroke();
    fill(155,27,66);
    rect(0, height-50, width, 50);
    stroke(0);
    strokeWeight(3);
    line (0, height-50, width, height-50);

}

Looking Outward-11

This project is called Botanicals. It was created by Kate Hartman as a way to form a stronger connection between humans and plants. This project uses Arduino and other software to read what a plant needs and then communicate that to its human. I love that this project plays on something light and funny, but also very relevant and useful. Kate Hartman is based in Toronto and teaches at OCAD University about Wearable and Mobile Technology.

Project 11: Generative Landscape

hc
var buildings = [];
var mountains = [];
var trees = [];
var noiseParam = 0;
var noiseStep = 0.01;
var people = [];
var img;

function preload(){
    //calling the superman image
    img = loadImage("https://i.imgur.com/21p2JQR.png");
}

function setup() {
    createCanvas(480, 480); 
    imageMode(CENTER);
    // create an initial collection of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    // mountains
    for (var i = 0; i <= width/4; i++) {
        var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
        mountains.push(value);
        noiseParam += noiseStep;
    }
}


function draw() {
    background(204, 241, 255); 
    //drawing clouds
    cloud(50, 70);
    push();
    scale(0.7);
    cloud(480, 150);
    pop();
    drawMountains(); //drawing the mountains
    displayStatusString();
    displayHorizon();
    //drawing the buildings
    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability();
    image(img, 250, 150, img.width * 0.2, img.height * 0.2); //superman
    //drawing the trees
    updateAndDisplayTrees(); 
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability(); 
    //drawing the people
    updateAndDisplayPeople();
    removePeopleThatHaveSlippedOutOfView();
    addNewPeopleWithSomeRandomProbability(); 
}

function cloud(x, y){
    //drawing the cloud
    push();
    translate(x, y);
    noStroke();
    fill(255, 237, 209, 95);
    ellipse(0, 10, 70, 50);
    ellipse(25, 0, 90, 60);
    ellipse(50, 10, 80, 45);
    pop();
}

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

function removeBuildingsThatHaveSlippedOutOfView(){
    //removing the buildings
    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.015;
    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() {
    var floorHeight = 20;
    var bHeight = this.nFloors * floorHeight; 
    fill(59, 107, 130); 
    stroke(100); 
    push();
    translate(this.x, height - 40);
    rect(0, -bHeight, this.breadth, bHeight);
    stroke(220); 
    fill(207, 226, 232);
    if (bHeight > 55){
        for (var i = 0; i < this.nFloors; i++) {
            rect(5, -15 - (i * floorHeight), this.breadth - 40, 10);
            rect(35, -15 - (i * floorHeight), this.breadth - 40, 10);
        }
    }else{
        fill(255, 246, 230);
        rect(0, -bHeight, this.breadth, bHeight);
        noStroke();
        fill(240, 182, 74);
        triangle(-10,-bHeight,this.breadth/2,-bHeight-30,this.breadth+10,-bHeight);
        fill(150, 100, 45);
        rect(20, 0, this.breadth - 40, -20);
    }
    pop();
}


function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 60,
                speed: -3.5,
                nFloors: round(random(2,8)),
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function drawMountains(){
    mountains.shift();
    var value = map(noise(noiseParam), 0, 1, height * 0.2, height * 0.9);
    mountains.push(value);
    noiseParam += noiseStep;
    stroke(135, 173, 141);
    fill(135, 173, 141);
    beginShape(); 
    vertex(0, height);
    for (var i = 0; i < width/4; i++) {
        vertex(i*5, mountains[i]);
        vertex((i+1)*5, mountains[i+1]);
    }
    vertex(width, height);
    endShape();
}

//drawing trees
function updateAndDisplayTrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function removeTreesThatHaveSlippedOutOfView(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}

function addNewTreesWithSomeRandomProbability() {
    var newTreeLikelihood = 0.025; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

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

function makeTree(birthLocationX) {
    var trees = {x: birthLocationX,
                breadth: 20,
                speed: -3.5,
                treeHeight: round(random(50,100)),
                move: treeMove,
                display: treeDisplay}
    return trees;
}


function treeDisplay() {
    push();
    translate(this.x, height - 30);
    noStroke(); 
    fill(107, 83, 71);
    rect(-5, 0, 10, 15); //tree trunk
    fill(66, 161, 61); 
    //leaves
    triangle(-this.breadth+10, -30, 0, -this.treeHeight, this.breadth-10, -30);
    triangle(-this.breadth+5, 0, 0, -this.treeHeight*0.7, this.breadth-5, 0);
    pop();
}

//Drawing people
function updateAndDisplayPeople(){
    for (var i = 0; i < people.length; i++){
        people[i].move();
        people[i].display();
    }
}

function removePeopleThatHaveSlippedOutOfView(){
    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 addNewPeopleWithSomeRandomProbability() {
    var newPeopleLikelihood = 0.005; 
    if (random(0,1) < newPeopleLikelihood) {
        people.push(makePeople(width));
    }
}


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

function peopleDisplay() {
    push();
    translate(this.x, height - 25);
    noStroke(); 
    fill(0);
    ellipse(0, -20, 40, 50); //head
    rect(-35, 0, 70, 50, 80); //body
    push();
    rotate(radians(-7));
    ellipse(25, -15, 15, 110); //arm
    pop();
    pop();
}

function makePeople(birthLocationX) {
    var ppl = {x: birthLocationX,
                breadth: round(random(5, 10)),
                speed: -3.5,
                pHeight: round(random(20,25)),
                move: peopleMove,
                display: peopleDisplay}
    return ppl;
}

function displayHorizon(){
    fill(53, 97, 44);
    rect (0,height-50, width, height-50); 
}


function displayStatusString(){
    noStroke(); 
    fill(0); 
}

Looking Outwards 11: A Focus on Women Practitioners

Emily Gobeille is a designer who specializes in merging technology and design to create an immersive design experience. She spent her years studying many disciplines, including web, prints, motion graphics, games, and installations. She also is one of the founders of Designer I/O, which specializes in the design and development of interactive installations. The company’s clients and partners usually include children museums.

I decided to look at one of her Designer I/O projects called Mimic. It is an “interactive installation that allows visitors to engage in a dialogue with a robot arm through gesture.” The robot can track the people’s movements and also has the ability to react to individuals actions accordingly. The robot can break down its impressions into three feelings: trust, curiosity, and interest, which will affect the robot’s responses. Depending on the individual’s movement and emotions, Mimic will react to many people simultaneously, changing its behavior. I personally find this interactive robot interesting for its skill to acknowledge the viewer’s reactions. 

Project 11 – Generative Landscape

sketch
var houses = [];
var sky;

function preload() {
    sky = loadImage("https://i.imgur.com/FaHkkqz.jpg");
}

function setup() {
    createCanvas(480, 435);
    background(220);
    for (var i = 0; i < 10; i ++) {
        houses[i] = makeHouse(i * 0.5);
    }
    frameRate(10);
}

function draw() {
    background(0, 30, 140);
    image(sky, 0, -100, 480, 600);
    moon();
    updateAndDisplayHouses();
    removeHouses();
    addNewHouses();
    man();
    gondola();
}

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

function removeHouses() {
    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 addNewHouses() {
    //probability
    var newHouseLikelihood = 5;
    if (random(0, 200) < newHouseLikelihood) {
        houses.push(makeHouse(width));
    }
}

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

function houseDisplay() {
    //draws the houses
    var floorHeight = 10;
    var bHeight = this.nFloors * floorHeight;
    fill(100);
    stroke(0);
    strokeWeight(1);
    push();
    translate(this.x, height);
    rect(0, -bHeight, this.breadth, bHeight);
    //windows
    for (var i = 0; i < this.nFloors; i++) {
        for (var j = 0; j < this.breadth / 20; j++) {
            fill(255);
            rect(j * 15 + 10, -(i * floorHeight), 5, 5);
        }
    }
    pop();
}

function makeHouse(birthLocationX) {
    var hse = {x: birthLocationX,
                breadth: 50,
                speed: -1.0,
                nFloors: round(random(3,8)),
                move: houseMove,
                display: houseDisplay}
    return hse;
}

function moon() {
    fill(255, 255, 181);
    noStroke();
    circle(240, 400, 300);
}

function gondola() {
    noStroke();
    fill(0);
    rect(150, 420, 200, 20);
    ellipse(145, 425, 40, 15);
    ellipse(355, 425, 40, 15);
    noFill();
    stroke(0);
    strokeWeight(10);
    arc(250, 410, 250, 30, radians(0), radians(180));
    arc(150, 415, 50, 40, radians(90), radians(180));
    arc(350, 415, 50, 40, radians(0), radians(90));
    //oar
    stroke(0);
    strokeWeight(4);
    line(180, 340, 155, 438);
}

function man() {
    fill(0);
    noStroke();
    circle(150, 348, 20);
    quad(145, 340, 145, 390, 160, 390, 150, 340);
    rect(145, 390, 10, 30);
    stroke(0);
    strokeWeight(4);
    line(155, 370, 170, 370);
    line(153, 373, 167, 377);
}

Man paddles through the Hudson at night, admiring the city.