Final Project

sketch

//thien le, section d, project

var pressValue = 255;
var circValOne = 255;
var circValTwo = 255;
var circValThree = 255;
var cityImg;
var iceImg;
var forestImg;
var smoke = [];
var x;
var y;
var dx;

function preload() {
  cityImg = loadImage ("https://i.imgur.com/hmWYq6y.png")
  iceImg = loadImage ("https://i.imgur.com/bcdmnoM.png12")
  forestImg = loadImage ("https://i.imgur.com/SiHq9rT.png")
}


function setup() {
  createCanvas(550, 300);
  background("#edc399");
  //smoke
  for (var i = 0; i < 80; i ++) {
        var startLocX = random(0, 270);
        var startLocY = random(0, 300);
        smoke[i] = makesmoke(startLocX, startLocY);
    }

//clouds
  x = int(random(0, 270));
  y = int(random(250, 300));
  //random colors
  //velocity of cloud
  dx = int(2);
  dy = int(5);
}

function draw() {
  screenText();
  threeButtons();
  cloud(x, y, dx);
    x += dx;
    //once cloud hits the right, it switches side
    if (dx >= 0 & x > 250){
        dx = -dx
    }
    else if (dx < 0 && x - 10 < 0){
        dx = -dx
    }
  
}
  

function screenText() {
  push();
  fill(255);
  textSize(8);
  text('P R E S S  1 ,  2 ,  O R  3  O N  K E Y B O A R D  T O  S T A R T !', 300, 30)
  pop();
}

function aOrB() {
  push();
  fill(255);
  textSize(10);
  text("A", 355, 255)
  text("B", 470, 255)
  pop();

}
function choiceText() {
  push();
  fill(255);
  textSize(8);
  text('P R E S S  A  O R  B  T O  C H O O S E', 350, 270);
  pop();
}

function badChoice() {
  push();
  fill("red");
  textSize(15);
  textStyle(BOLD);
  text('CONTINUE PRESSING B', 340, 260);
  pop();
}
function threeButtons() { //buttons that will display 3 facts about climate change
    noStroke();
    fill(circValOne);
    circle(350, 70, 50, 50);
    fill(circValTwo);
    circle(420, 70, 50, 50);
    fill(circValThree);
    circle(490, 70, 50, 50);
}

function keyTyped() {
  //city
  if (key === '1') {
    circValOne = ("#cc7161");
    circValTwo = 255;
    circValThree = 255;
    fill(255);
    image(cityImg, 0, 0, 270, height);
    cityButton();
    cityFact();
    choiceText();
    aOrB();
    //ice
  } 
  if (key === 'a') {
    background("#014421");
    push();
    textSize(15);
    textAlign(CENTER);
    fill(255);
    text('YAY YOU SAVED THE EARTH!', 150, 150)
    pop();
  }
  if (key === 'b') {
     smokeDisplay();
     badChoice();
  }
  if (key === '2') {
    circValTwo = ("#cc7161");
    circValOne = 255;
    circValThree = 255;
    image(iceImg, 0, 0, 270, height);
    iceButton();
    iceFact();
    choiceText();
    //forest
  } 
  else if (key === '3') {
    circValThree = ("#cc7161");
    circValTwo = 255;
    circValOne = 255;
    image(forestImg, 0, 0, 270, height);
    forestButton();
    forestFact();
    choiceText();
  }
}

function cityButton(){
  push();
  rectMode(CENTER);
  fill("#638a7e");
  rect(360, 200, 100, 80, 20);
  rect(480, 200, 100, 80, 20);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  text('Walk, bike, or take public transportation', 310, 180, 100, 80);
  text('Drive personal vehicle', 430, 185, 100, 80);
  pop();
}

function iceButton(){
  push();
  rectMode(CENTER);
  fill("#638a7e");
  rect(360, 200, 100, 80, 20);
  rect(480, 200, 100, 80, 20);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  text('Utilize smart power in homes', 310, 185, 100, 80);
  text('Leave lights on everywhere', 430, 185, 100, 80);
  pop();
}

function forestButton(){
  push();
  rectMode(CENTER);
  fill("#638a7e");
  rect(360, 200, 100, 80, 20);
  rect(480, 200, 100, 80, 20);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  text('Encourage politicians to fund parks', 310, 180, 100, 80);
  text('Use lots of paper', 430, 190, 100, 80);
  pop();
}

function cityFact() {
  push();
  rectMode(CENTER);
  fill("#edc399");
  rect(420, 130, 230, 60);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  //climate fact
  fill(255);
  text('Each year 1.2 trillion gallons of untreated sewage, stormwater, and industrial waste are dumped into US water', 310, 107, 230, 100);
  pop();
}

function iceFact() {
  //climate fact
  push();
  rectMode(CENTER);
  fill("#edc399");
  rect(420, 130, 230, 60);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  //climate fact
  fill(255);
  text('95% of the oldest and thickest ice in the Arctic is already gone', 310, 115, 230, 100);
  pop();
}

function forestFact() {
  //climate fact
  push();
  rectMode(CENTER);
  fill("#edc399");
  rect(420, 130, 230, 60);
  pop();
  push();
  textAlign(CENTER);
  fill(255);
  //climate fact
  fill(255);
  text('Deforestation emits more greenhouse gas emissions than 85 million cars would over their entire lifetime', 310, 107, 230, 100);
  pop();
}

//smoke object
function drawsmoke() {
    noStroke();
    //fill(255);
    push();
    translate(this.x, this.y);
    fill(200, 200);
    ellipse(1, 10, this.starH, this.starH);
    pop();
}

function makesmoke(startLocX, startLocY) {
    var smoke = {x: startLocX, 
               y: startLocY, 
               starH: random(10, 30),
               speed: -1, 
               move: smokeMove, 
               draw: drawsmoke}
    return smoke;
}

function smokeMove() { //update position of smoke
    this.x += this.speed
    if (this.x <= 0) {
        this.x += 50
    }
}

function smokeDisplay() { 
     for(i = 0; i < smoke.length; i ++) {
        smoke[i].move();
        smoke[i].draw();
    }
}

//cloud
function cloud(x, y, dx) {
    fill(200, 200);
    ellipse(x - 30, y + 20, 20, 20)
    ellipse(x - 15, y + 10, 30, 40)
    ellipse(x + 5, y + 5, 20, 30)
    ellipse(x, y, 20, 10)
}

Final Project

In this game you try to keep the penguin alive. If the penguin touches the water you lose. the penguin has to jump between ice cubes floating across the screen. the ice cubes are objects stored in an array. the penguin can jump when it is touching the ice cube. two challenges appear while playing. one makes the ice cubes smaller, and one makes the ice cubes move faster. if you navigate through these challenges you can get to safety and win the game. I attached a video of me completing the game because it might not be a game you can complete first try.

I wanted to create a fun game that had a relation to climate change. since climate change is melting ice which might cause harm to wildlife, I made this game where the ice is melting. If I had more time I might add more challenges and make the movement of the ice cubes look more realistic, like they are actually in water.

sketch
var ice = []
var penguinY = 0; 
var penguinX = 300;    
var penguinDy = 0; 
var count = 0
var menu = 0

function setup() {
  createCanvas(600,600)

  //creating the 4 icecubes
  for (i = 0; i < 4; i++) {
    iceX = random(width)
    iceY = 440
    size = 70
    ice[i] = makeIce(iceX, iceY, size)
  }
}

function draw() {

  //menu page
  if (menu < 1) {
    fill("lightgreen")
    rect(0,0,800,600)
    textAlign(CENTER)
    textFont('Helvetica')
    textSize(18)
    fill("black")
    text("The ice is melting!", 400,220)
    text("get to safety!", 400,370)
    fill("red")
    text("use the arrow keys to move left and right", 400,280)
    text("spacebar to jump", 400,310)
    text("press spacebar to begin", 400, 450)
    
    }

    //win page
  else if (count >= 3200){
      fill(220)
      noStroke()
      background("lightblue")
      ellipse(400,650,1200,400)
      textSize(18)
      fill(0)
      text("you made it to safety!",400,300)
      translate(400,420)
      drawPenguin(0,0)
      noLoop()
    }
  
  else {
  
  //scenary
  background("lightblue")
  fill("blue")
  rect(0, height - 100, width, 100)
  //sun that rotates
  push()
  translate(100,100)
  rotate(radians(count))
  drawSun()
  pop()
  
  stroke(0)

  //checking if penguin is on any icecube or above the icecubes
  if (penguinY <= 440 &
    (penguinX >= ice[0].fx && penguinX <= ice[0].fx+75) ||
    (penguinX >= ice[1].fx && penguinX <= ice[1].fx+75) ||
    (penguinX >= ice[2].fx && penguinX <= ice[2].fx+75) ||
    (penguinX >= ice[3].fx && penguinX <= ice[3].fx+75)
    ) { 
    penguinY = min(395, penguinY + penguinDy);
     
    //checking if penguin is below the icecubes
  } else { 
    
    penguinY = min(height, penguinY + penguinDy);
  }
 
  //showing the penguin and ice
  drawPenguin(penguinX,penguinY)
  showIce()

  //penguin gravity
  penguinDy = penguinDy + .25;

  //penguin left/right movement
  if (keyIsDown(LEFT_ARROW)){
    penguinX-=5
  }
  if (keyIsDown(RIGHT_ARROW)){
    penguinX+=5
  }

  // if you touch the water "you lose"
  if (penguinY >= 550) {
    textSize(18)
    text("You Lose",400,300)
    fill(255)
    drawDeadPenguin(penguinX,penguinY)
    noLoop()
  }
  //use this count to initate challenges levels
  count+=1

  //challenge level 1
  countdown(900)

  if (count >= 1100 & count <= 1500){
    ice[0].icesize = 30
    ice[1].icesize = 30
    ice[2].icesize = 30
    ice[3].icesize = 30
  }

  if (count >= 1500 && count <= 2000){
    ice[0].icesize = 70
    ice[1].icesize = 70
    ice[2].icesize = 70
    ice[3].icesize = 70
  }

  //challenge level 2
  countdown(1800)

  if (count >= 2000 && count <= 2400){
    ice[0].icespeed = -4
    ice[1].icespeed = -5
    ice[2].icespeed = -6
    ice[3].icespeed = -7
  }

  if (count >= 2400 && count <= 2401){
    ice[0].icespeed = random(-1.5,-3)
    ice[1].icespeed = random(-1.5,-3)
    ice[2].icespeed = random(-1.5,-3)
    ice[3].icespeed = random(-1.5,-3)
  }
  
  //approaching the end text
  if (count >= 2600 && count <= 2800){
    textSize(22)
    text("you are approaching the end",400,300)
}
}
}



//penguin jump
function keyPressed() {
  
  if (keyCode === 32) {
    if (penguinY >= 360 && (
      (penguinX >= ice[0].fx && penguinX <= ice[0].fx+75) ||
      (penguinX >= ice[1].fx && penguinX <= ice[1].fx+75) ||
      (penguinX >= ice[2].fx && penguinX <= ice[2].fx+75) ||
      (penguinX >= ice[3].fx && penguinX <= ice[3].fx+75)
      )) { 
    penguinDy = -10;
      }   
      menu = 1
      
      
  }
  
}

//two functions for alive penguin and dead penguin
function drawPenguin(x,y){
  fill(0);
  noStroke();
  ellipse(x, y+2, 46, 81);
  fill(255);
  ellipse(x, y+10, 31, 56);
  ellipse(x-5, y-20, 21, 21);
  ellipse(x+5, y-20, 21, 21);
  fill(255,150,40);
  triangle(x-7, y-15, x+7, y-15, x,y-3);
  ellipse(x+8, y+42, 15, 8);
  ellipse(x-8, y+42, 15, 8);
  fill(0);
  ellipse(x-8, y-21, 8, 8);
  ellipse(x+8, y-21, 8, 8);
  ellipse(x-21, y+10, 12, 40);
  ellipse(x+21, y+10, 12, 40);
  
}

function drawDeadPenguin(x,y){
  fill(0);
  noStroke();
  ellipse(x, y+2, 46, 81);
  fill(255);
  ellipse(x, y+10, 31, 56);
  ellipse(x-5, y-20, 21, 21);
  ellipse(x+5, y-20, 21, 21);
  fill(255,150,40);
  triangle(x-7, y-15, x+7, y-15, x,y-3);
  ellipse(x+8, y+42, 15, 8);
  ellipse(x-8, y+42, 15, 8);
  fill(0);
  textSize(12)
  text("x",x-9, y-20);
  text("x",x+6, y-20);
  ellipse(x-21, y+10, 12, 40);
  ellipse(x+21, y+10, 12, 40);
  

}
// function creates the sun
function drawSun(){
  fill("gold")
  stroke("gold")
  line(0,0,60,60)
  line(0,0,-60,60)
  line(0,0,-60,-60)
  line(0,0,60,-60)
  line(0,0,35,80)
  line(0,0,-35,80)
  line(0,0,35,-80)
  line(0,0,-35,-80)
  line(0,0,80,0)
  line(0,0,-80,0)
  line(0,0,0,80)
  line(0,0,0,-80)
  line(0,0,75,35)
  line(0,0,-75,-35)
  line(0,0,75,-35)
  line(0,0,-75,35)
  circle(0,0,100)
}

//function for the countdown for a challenge
function countdown(x){
if (count >= x & count <= x+200 ){
  textSize(30)
  text("Challenge in",350,200)
}
if (count >= x+16 && count = x+70 && count <=x+140 ){
  textSize(50)
  text("2",350,300)
}
if (count >= x+140 && count <=x+200 ){
  textSize(50)
  text("1",350,300)
}
}

//functions for the creation/movement of the ice
function makeIce(iceX, iceY, size) {
  var ice = {
      fx: iceX,
      fy: iceY,
      icesize: size,
      icespeed: random(-1.5, -3),
      icemove: moveIce,
      icecolor: color(random(50, 100), random(100, 200), 255),
      icedraw: drawIce
  }
  return ice
}
function moveIce() {
  this.fx += this.icespeed
  if (this.fx <= -10) {
      this.fx += width
  }
}
function drawIce() {
  stroke(0)
  fill(this.icecolor);
  rect(this.fx, this.fy, this.icesize, 70)
}
function showIce() {
  for (i = 0; i < ice.length; i++) {
      ice[i].icemove()
      ice[i].icedraw()
  }
}

Project 11 – Moving Landscape

sketch

Trees and birds and trees and birds

var trees = [];
var birds = [];
var dx = -1;

function setup() {
    createCanvas(400, 200);

    for (var i = 0; i < 10; i++){ //populate trees
        var rx = random(width);
        trees[i] = makeTree(rx);
    }for (var i = 0; i < 3; i++){ //populate birds
        var bx = random(width);
        birds[i] = makeTree(bx);
    }
    frameRate(10);
}


function draw() {
    background('lightblue');

    //dirt
    noStroke();
    fill('darkgreen');
    rect(-10, 100, width+20, height);

    updateAndDisplayTrees();
    removeTree();
    newTree();

    updateAndDisplayBird();
    removeBird();
    newBird();

    drawRoad();
}

function drawRoad() {
    fill('grey');
    rect(-10, 130, width+20, 30);

    stroke('black');
    var dividerLines = [];
    for (var i = 0; i < 30; i++) { //make vals
        var a = i*width/30;
        dividerLines.push(a);
    } for (var i = 0; i < 30; i++) { //draw lines
        line(dividerLines[i], 145, dividerLines[i]+width/60, 145);
    } for (var i = 0; i < 30; i++) { //move lines
        dividerLines[i] += dx;
        if (dividerLines[i] <= -width/60) {
            dividerLines[i] = width;
        }
    }
}

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

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

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

function removeBird(){
    var birdsToKeep = [];
    for (var i = 0; i < birds.length; i++){
        if (birds[i].x > -50) {
            birdsToKeep.push(birds[i]);
        }
    }
    birds = birdsToKeep;
}

function newTree() {
    var newTreeLikelihood = 0.02;
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width+50));
    }
}

function newBird() {
    var newBirdLikelihood = 0.05;
    if (random(0,1) < newBirdLikelihood) {
        birds.push(makeBird(width));
    }
}


// method to update position of Tree every frame
function treeMove() {
    this.x += this.speed * this.scal/3;
}

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


function treeDisplay() {
    push();
    translate(this.x, 100);
    scale(this.scal)
    stroke('brown');
    strokeWeight(5);
    line(0, 0, 0, 20);

    stroke('green');
    fill('green');

    for (var i = 0; i < 5; i++) {
        triangle(-20+2*i, -7*i, -2, -7*i, -2, -20-7*i);
    } for (var i = 0; i < 5; i++) {
        triangle(20-2*i, -7*i, 2, -7*i, 2, -20-7*i);
    }
    pop();
}

function birdDisplay() {
    push();
    translate(this.x, this.y);
    stroke('black');
    noFill();
    strokeWeight(2);
    arc(0, 0, 20, 20, PI+PI/3, 2*PI-PI/3);
    arc(10, 0, 20, 20, PI+PI/3, 2*PI-PI/3);
    pop();
}


function makeTree(birthLocationX) {
    var tree = {x: birthLocationX,
                scal: random(0.5, 2),
                speed: dx,
                move: treeMove,
                display: treeDisplay}
    return tree;
}

function makeBird(birthLocationX) {
    var bird = {x: birthLocationX,
                y: random(0, 70),
                speed: random(-5,-2),
                move: birdMove,
                display: birdDisplay}
    return bird;
}

Window Gazing – Generative Landscape

sketch
var trunks = [];
var hills = [];
var mountains = [];
var noiseParam = 0;
var noiseStep = 0.01;
var clouds = [];
function setup() {
    createCanvas(640, 240); 

    //Trunks
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trunks[i] = makeTrunk(rx);
    }

   //Hills
    for (var i = 0; i <= width; i ++) {
        var n = noise(noiseParam);
        var value = map(n, 0, 1, 0, height*1.5);
        hills.push(value-10);
        noiseParam += noiseStep;
    }

    //Mountains
    for (var i = 0; i <=width/5+1; i++) {
        var n = noise(noiseParam);
        var value = map(n,0,1,height*1/5,height*4/5);
        mountains.push(value);
        noiseParam += noiseStep;
    }

    //Clouds
    for (var i = 0; i < 10; i ++) {
        var cloudX = random(width);
        var cloudY = random(height/2, height);
        clouds[i] = makeClouds(cloudX, cloudY);
    }

    frameRate(60);
}


function draw() {
    background(191,234,255); 

    drawMountains();

    updateAndDisplayClouds();
    removeClouds();
    addNewClouds(); 

    drawHills();

    updateAndDisplayTrunks();
    removeTrunks();
    addNewTrunks(); 

    drawWindow();
}

function drawWindow() {
    //simple code used to draw window that viewer is looking through
    var border = 40
    stroke(141,171,223);
    noFill();
    strokeWeight(border);
    rect(border/2,border/2,width-border,height-border);
    stroke(220);
    strokeWeight(border/2)
    rect((border/2)+20,(border/2)+20,(width-border)-40,(height-border)-40,20);

}

//Updating position and displaying clouds
function updateAndDisplayClouds() {
    for (var i = 0; i < clouds.length; i ++) {
        clouds[i].move();
        clouds[i].display();
    }
}

//if the clouds reach the end of the screen, remove and replace in new array
function removeClouds() {
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++){
        if (clouds[i].x > 0) {
            cloudsToKeep.push(clouds[i]);
        }
    }
    clouds = cloudsToKeep;
}

//based on set probability, add new cloud into array
function addNewClouds() {
    var newCloudLikelihood = 0.07; 
    if (random(0,1) < newCloudLikelihood) {
        var newcloudX = 640;
        var newcloudY = random(200);
        clouds.push(makeClouds(newcloudX, newcloudY));
    }
}

function makeClouds(CLOUDX, CLOUDY) {
    var cld = {x: CLOUDX,
             y: CLOUDY,
             speed: -5,
             move: cloudMove,
             display: cloudDisplay}
    return cld;
}

//moving clouds
function cloudMove() {
    this.x += this.speed;
}

//drawing of cloud
function cloudDisplay() {
    fill(255); // cream color
    noStroke();
    ellipse(this.x, this.y, 20, 30);
    ellipse(this.x, this.y, 20, 30);
    ellipse(this.x, this.y, 30, 10);
    ellipse(this.x, this.y, 10, 20);
    ellipse(this.x, this.y, 40, 20);
}

//hill drawing using Begin and End Shape
function drawHills() {
    noStroke();
    fill("green");
    
    beginShape();
    vertex(0, height);
    for (i = 0; i <= width/5 + 1; i += 1) {
        vertex(i*5, hills[i]);
        vertex((i+1)*5, hills[i+1]);
    }
    vertex(width, height);
    endShape();

    hills.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    hills.push(value);
    noiseParam += noiseStep;

}

//Mountains is variantion of hill code
function drawMountains() {
    noStroke();
    fill(161,178,158);
    
    beginShape();
    vertex(0, height);
    for (i = 0; i <= width/5 + 1; i += 1) {
        vertex(i*5, mountains[i]);
        vertex((i+1)*5, mountains[i+1]);
    }
    vertex(width, height);
    endShape();

    mountains.shift();
    var n = noise(noiseParam);
    var value = map(n, 0, 1, 0, height);
    mountains.push(value);
    noiseParam += noiseStep;

}

//trunks in front of window being moved and displayed here
function updateAndDisplayTrunks(){
    for (var i = 0; i < trunks.length; i++){
        trunks[i].move();
        trunks[i].display();
    }
}

//if trunk leaves screen, remove and replace with another
function removeTrunks(){
    var trunksToKeep = [];
    for (var i = 0; i < trunks.length; i++){
        if (trunks[i].x + trunks[i].breadth > 0) {
            trunksToKeep.push(trunks[i]);
        }
    }
    trunks = trunksToKeep; 
}

//small probability of adding new trunk
function addNewTrunks() {
    var probability = 0.08; 
    if (random(0,1) < probability) {
        trunks.push(makeTrunk(width));
    }
}


// moving trunk along window as if "passing"
function TrunkMove() {
    this.x += this.speed;
}
    

// drawing of trunks
function TrunkDisplay() {
    noStroke();
    var tHeight = 0
    fill(102,60,11);  
    push();
    translate(this.x, height);
    rect(0, 0, this.breadth, -height);
    stroke(200); 
    pop();
}

function makeTrunk(birthLocationX) {
    var trnk = {x: birthLocationX,
                breadth: 40,
                speed: -7,
                move: TrunkMove,
                display: TrunkDisplay}
    return trnk;
}

This is my project on Generative landscapes. Using what I learned from class, I created an artistic interpretation of what it feels like to look out of the window of a moving vehicle.

project-11

this project was pretty interesting. there are birds, clouds, and a landscape going across the screen.

sketch

var cloud = []
var bird = []

function setup() {
    createCanvas(480, 240)
    frameRate(10)

    for (i = 0; i < 30; i++) {
        birdX = random(width)
        birdY = random(height)
        bird[i] = makeBird(birdX, birdY)
    }
    for (i = 0; i < 15; i++) {
        cloudX = random(width)
        cloudY = random(height/1.5)
        cloud[i] = makeCloud(cloudX, cloudY)
    }
}

function draw() {
    background(140, 200, 255)
    strokeWeight(2)
    landscape()
    showCloud()
    showBird()

}

function landscape() {
    stroke(86, 125, 70)
    beginShape()
    for (var i = 0; i < width; i++) {
        var x = (i * .01) + (millis() * .0004)
        var s = map(noise(x), 0, 1, 150, 200)
        line(i, s, i, height)
        
    }
    endShape()
}


function makeBird(birdX, birdY) {
    var bird = {
        fx: birdX,
        fy: birdY,
        birdspeed: random(-3, -8),
        birdmove: moveBird,
        birdcolor: color(random(100, 200), random(100, 200), random(100, 200)),
        birddraw: drawBird
    }
    return bird
}

function moveBird() {
    this.fx += this.birdspeed
    if (this.fx <= -10) {
        this.fx += width
    }
}

function drawBird() {
    
    stroke(0)
    fill(this.birdcolor);
    ellipse(this.fx, this.fy, 10, 10)
    line(this.fx - 5, this.fy, this.fx - 10, this.fy - 2)
    line(this.fx + 5, this.fy, this.fx + 10, this.fy - 2)

}

function showBird() {
    for (i = 0; i < bird.length; i++) {
        bird[i].birdmove()
        bird[i].birddraw()
    }
}

function makeCloud(cloudX, cloudY) {
    var cloud = {
        fx: cloudX,
        fy: cloudY,
        cloudspeed: random(-1, -2),
        cloudmove: moveCloud,
        clouddraw: drawCloud
    }
    return cloud
}

function moveCloud() {
    this.fx += this.cloudspeed
    if (this.fx <= -10) {
        this.fx += width
    }
}

function drawCloud() {
    
    noStroke()
    fill(255);
    ellipse(this.fx, this.fy, 10, 10)
    ellipse(this.fx-4, this.fy-1, 10, 10)

    

}

function showCloud() {
    for (i = 0; i < cloud.length; i++) {
        cloud[i].cloudmove()
        cloud[i].clouddraw()
    }
}

Project: Generative Landscape

luca generative landscape

//lucacao
//sectionD
//Project11

var boat = [];//array to store boat number
var speed = 1;


function setup() {
    createCanvas(480, 480);
    noStroke();
    frameRate(5);

    for (var i = 0; i < 10;i++){
        bx = random(width);//boat x position
    }
}

function draw() {
    background(220);
    sea(); 
    sky();
    moon();

    for(var i = 0; i < 5; i++){
        drawBoat();
        boat++;
        print(boat);
    }
}

function sea() {
    fill(0, 64, 108);
    rect(0,240,480,240);
}

function sky(){
    fill(0, 37, 62);
    rect(0,0,480,240);

    for (var i = 0; i < 100;i++){
        var starx = random(0,480);
        var stary = random(0,240);
        fill(255,255,255);
        ellipse(starx,stary,3,3);
        starx += speed;
        
    }
    // noLoop();
}

function moon(){
    fill(252, 202, 70);
    ellipse(350,80,100,100);
}

function drawBoat(){
    var blength = random(50,100);
    var bheight = random(20,30);
    var bx = random(0,480);
    var by = random(240,480);

    this.bx += this.speed;

    fill(0);
    rect(bx,by,blength,bheight);
    rect(bx+20,by-10,blength/2,bheight/2);
    triangle(bx+blength,by+bheight,bx+blength,by,
        bx+blength+30,by-10);
    
}





For my landscape, I wanted to depict a scene with boats and stars moving at night. In my thumbnail sketch, I divided the canvas into halves, with a sky which is the top half, and the sea at the bottom half. I thought it would be more visually interesting with objects moving on all areas of the canvas. During this project, I faced difficulty trying to animate my objects, but I solved the problem by creating multiple functions which helped me clarify my code structure and tackle specific problems. The randomness in my code exists in the size and position of the boat.

Project 11: Generative Landscape

sketchDownload
// this program displays a landscape of a stone path along a stream in the woods.

// empty arrays for objects:
var bkgrndtrees = [];
var path = [];
var stream = [];
var trees = [];
var allArrays = [bkgrndtrees, path, stream, trees];

// speed of landscape shift, per frame
// adjusted for background+foreground so 'closer' objects move faster than 'far away' ones
var shift = -1;

function setup() {
    createCanvas(480, 300);
    background(80, 125, 60);
    frameRate(200);

    // create initial collections of objects:
    fillBkgrndtrees();
    fillPath();
    fillStream();
    fillTrees();

    // sort objects in arrays to be drawn properly:
    for (a=0; a<allArrays.length; a++) {
        if (allArrays[a]!=stream){          // stream should not be ordered
            orderObjects(allArrays[a]);
        }
    }
}

// fills backgroundTrees array with initial trees:
function fillBkgrndtrees() {
    for (var i = 0; i < 320; i++) {
        var rx = random(width+75);
        var ry = random(-height/25, 2*height/5);      // top of canvas = background
        bkgrndtrees[i] = makeTree(rx, ry);
    }
}

// fills foreground tree array with initial trees:
function fillTrees() {
    for (var i = 0; i < 5; i++) {
        var rx = random(width+75);
        var ry = random(4*height/5, 3*height/2);    // bottom of canvas = foreground
        trees[i] = makeTree(rx, ry);
    }
}

// fills path array with initial stones:
function fillPath() {
    for (var i = 0; i < 15; i++) {
        var size = random(width/25, width/10);
        var col = color(random(90, 120));
        var x = i*50;
        var ry = random(height/2, 3*height/5);
        path[i] = makeStone(x, ry, size, col);
    }
}

// fills stream array with objects based on stone path:
function fillStream() {
    for (var i = 0; i < path.length; i++) {
        var x = i*50;
        var y = path[i].y + path[i].size;
        stream[i] = makePoint(x, y);
    }
}

// creates a tree object
function makeTree(tx, ty) {
    // background trees:
    if (ty < height/2) {
        var tree = {x:tx,
                    y:ty,
                    age:random(2, 11),
                    trunkc: color(random(70, 90), random(55, 75), random(30, 55)),
                    leavesc: color(random(0, 75), random(65, 175), random(50)),
                    show: showTree,
                    move: moveObject,
                    speed: shift*.85 }
    }
    // foreground trees:
    else {
        var tree = {x:tx,
                    y:ty,
                    age:random(4, 7),
                    trunkc: color(random(50, 80), random(20, 50), random(10, 20)),
                    leavesc: color(random(0, 100), random(100, 200), random(30)),
                    show: showTree,
                    move: moveObject,
                    speed: shift*1.15 }
    }

    return tree;
}

// creates a stone object
function makeStone(sx, sy, ssize, scol) {
    var stone = {x:sx,
                 y:sy,
                 size:ssize,
                 c: scol,
                 show: showStone,
                 move: moveObject,
                 speed: shift}
    return stone;
}

// creates a point object (for stream curve);
function makePoint(px, py) {
    var pnt = {x:px,
               y:py,
               size:width/50,
               c: color(50, 125, 175),
               show: showStone,
               move: moveObject,
               speed: shift}
    return pnt;
}

function draw() {
    background(80, 125, 60);

    // draw all objects in all arrays:
    for (j=0; j<allArrays.length; j++) {
        thisArray = allArrays[j];
        drawObjects(thisArray);
        if (thisArray!=stream) {        // stream is updated with path
            // order and updates arrays:
            orderObjects(thisArray);
            updateArray(thisArray);
        }
    }
}

// draws and moves objects in an array
function drawObjects(array) {
    for (i=0; i<array.length; i++) {
        thisObj = array[i];
        thisObj.show();
        thisObj.move();
    }
    if (array==stream) {
        drawStream();
    }
}

// uses curve shape and array points ot draw stream
function drawStream() {
    push();
    noFill();
    stroke(50, 125, 175);
    strokeWeight(15);
    curveTightness(-.2);
    beginShape();
    curveVertex(stream[0].x, stream[0].y);
    curveVertex(stream[0].x, stream[0].y);
    for (var m=1; m<stream.length-1; m++){
        curveVertex(stream[m].x, stream[m].y);
    }
    curveVertex(stream[stream.length-1].x, stream[stream.length-1].y);
    endShape();
    pop();
}

// sorts objects in an array according to the y feild
// this ordering ensures accurate depth on canvas
function orderObjects(array) {
    for (var j=0; j<array.length-1; j++) {
        var counter = 0;
        for (var i=0; i<array.length-1; i++) {
            if (array[i].y > array[i+1].y) {
                var tmp = array[i];
                array[i] = array[i+1];
                array[i+1] = tmp;
                counter += 1;
            }
        }
        if (counter==0) {
            break;
        }
    }
}

// updates all allArrays
// adds new objects to end and deletes unused objects (off canvas)
function updateArray(array) {
    if (array==trees || array==bkgrndtrees) {
        // add new trees to array off-canvas:
        // background trees:
        var treeLikelihoodB = 320/555;
        if (random(1) < treeLikelihoodB) {
            var ry = random(-height/25, 2*height/5);    // top of canvas = background
            bkgrndtrees.push(makeTree(width+75, ry));
        }
        // foreground trees:
        var treeLikelihoodF = 5/555;
        if (random(1) < treeLikelihoodF) {
            var ry = random(3*height/4, 3*height/2);      // bottom of canvas = foreground
            trees.push(makeTree(width+75, ry));
        }
    }
    else {
        // path and stream use fixed x values:
        if (frameCount%50==0) {
            var size = random(width/25, width/10);
            var col = color(random(90, 120));
            var ry = random(height/2, 3*height/5);
            path.push(makeStone(700, ry, size, col));
            col = color(0, 50, 150);
                var y = ry + size;
            stream.push(makePoint(700, y));
        }
    }

    // remove any object no longer on canvas:
    var keep = [];
    for (var k=0; k<array.length; k++) {
        if (array[k].x > 0) {
            keep.push(array[k]);
        }
    }
    array = keep;
}

// draws tree based on age
function showTree() {
    if (this.y < height/2) {     // top of canvas = background
        var h = this.age*10;
        var w = this.age*2;
    }
    else {                      // bottom of canvas = foreground
        var h = this.age*12;
        var w = this.age*2.5;
    }
    var cx = this.x + w/2;
    var cy = this.y - h*1.5;

    if (this.age > 5) {             // older trees
        stroke(50, 40, 30);
        fill(this.trunkc);
        rect(this.x, this.y-h, w, h);
        fill(this.leavesc);
        for (var i=0; i<3; i++) {
            stroke(0, 75, 0);
            circle(cx - (this.age*4*i) + (this.age*4),
                   cy - (this.age*1.5) + (this.age*3*i),
                   this.age*5);
            circle(cx + (this.age*4*i) - (this.age*4),
                   cy - (this.age*1.5) + (this.age*3*i),
                   this.age*5);
            ellipse(cx - (this.age*6*i) + (this.age*6),
                    cy + this.age,
                    this.age*5,
                    this.age*6);
            ellipse(cx,
                    cy - (this.age*3) + (this.age*4*i),
                    this.age*7,
                    this.age*5);
        }
        noStroke();
        ellipse(cx, cy + this.age, this.age*12, this.age*9);
    }
    else {                          // younger trees
        stroke(50, 40, 30);
        fill(this.trunkc);   // tree trunk lighter brown
        rect(this.x, this.y-h, w/2, h);
        fill(this.leavesc);
        for (var i=0; i<3; i++) {
            stroke(0, 75, 0);
            circle(cx - (this.age*3*i) + (this.age*3),
                   cy - (this.age*1.5) + (this.age*2*i),
                   this.age*4);
            circle(cx + (this.age*3*i) - (this.age*3),
                   cy - (this.age*1.5) + (this.age*2*i),
                   this.age*4);
            ellipse(cx - (this.age*4*i) + (this.age*4),
                    cy + this.age,
                    this.age*4,
                    this.age*5);
            ellipse(cx,
                    cy - (this.age*4) + (this.age*4*i),
                    this.age*6,
                    this.age*4);
        }
        noStroke();
        ellipse(cx, cy + this.age/2, this.age*11, this.age*9);
    }
}

// draws stone for path
function showStone() {
    stroke(75);
    fill(this.c);
    ellipse(this.x, this.y, this.size, this.size/2);
}

// updates x values to move the landscape along
function moveObject() {
    this.x += this.speed;
}

For this project, I was inspired by a trail I used to walk a lot growing up. I struggled a bit to order the objects in a way that looks nice and is recognizable as a landscape, but I think the orderObjects() function that I created helped a lot with that. I also found it difficult to create the stream using a curve shape, but I am again really pleased with how well it came out. I wanted the path and stream to flow along together, and they do. To give more of a landscape effect, I adjusted the shift values for moving the objects so that things in the foreground move faster than things in the background.

My initial sketch of the stream in the woods.

Generative Landscape

sketchDownload
var cld = [];
var shl = [];

function setup() {
    createCanvas(480, 320);
    background(200);
    noStroke();
}

function draw() {
    //static background
    fill(57, 16, 115);
    rect(0, 0, 480, 40);
    fill(129, 21, 150);
    rect(0, 40, 480, 40);
    fill(189, 28, 119);
    rect(0, 80, 480, 40);
    fill(224, 47, 31);
    rect(0, 120, 480, 40);
    fill(230, 107, 50);
    rect(0, 160, 480, 40);
    fill(255, 185, 64);
    circle(240, 200, 60);
    fill(179, 161, 91);
    rect(0, 200, 480, 120);

    //cloud code
    if(random() > 0.95) cld.push(makeCloud((random()*120), color(random()*30+220, 220, random()*30+220))); //chance to draw new cloud
    for(let i = 0; i < cld.length; i++) { //draws and updates clouds
      cld[i].drawCloud();
      cld[i].moveCloud();
    }
    if(cld[0].x > 480) cld.shift(); //removes clouds that move too far

    //shell code
    if(random() > 0.85) shl.push(makeShell(random()*200+120, color(random()*255, random()*255, random()*255), random()*3)); //chacne to draw new drawShell
    for(let i = 0; i < shl.length; i++) { //draws and updates shells
      shl[i].drawShell();
      shl[i].moveShell();
    }
    if(shl[0].x > 480) shl.shift(); //removes shells that move too far
}

function makeCloud(ty, tc) {
    var cloud = {x: 0, y: ty, c: tc};
    return cloud;
}

function drawCloud() {
    fill(this.c);
    ellipse(this.x, this.y, 40, 20);
}

function moveCloud() {
    this.x += 10;
}

function makeShell(ty, tc, ts) {
    var shell = {x: 0, y: ty, c: tc, s: ts}
    return shell;
}

function drawShell() {
    fill(this.c);
    if(this.s < 1) circle(this.x, this.y, 20);
    else if(this.s < 2) square(this.x, this.y, 20);
    else triangle(this.x, this.y, this.x+10, this.y+20, this.x+20, this.y);
}

function moveShell() {
    this.x += 10;
}

This isn’t running correctly right now and I can’t figure out why ?-?

I made a sunset landscape because I thought I could incorporate some really cool colors into the background. First I coded the hard landscape. Since the sun is so far away, it will look like it isn’t moving. Next I created very simple clouds. To create randomness and variety in my landscape the clouds have a randomized color and height. I created a method that updated their x position so that they’d look like they were “moving” across the screen. After that I made shells. I followed a similar procedure, but I also added shape as a random variable. Having different shaped/colored shells in different locations helps make the landscape more exciting. I wish the code was displayed properly so you could see the final product 🙁

Project 10: Sonic Story

sketch

//Elise Chapman
//ejchapma
//ejchapma@andrew.cmu.edu
//Section D

// Storyline: a mouse comes out of its hole, sees some cheese,
// then goes over to nibble on it. It sees the shadow of a cat,
// then scurries back to its hole.

var xPos; //x position of the mouse
var yPos; //y position of the mouse 
var timer=0; //for animation timing purposes
var yPosCat; //y position for cat shadow

function preload() {
    squeak = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/squeak.wav");
    aha = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/aha.wav");
    nibble = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/nibble.mp3");
    scream = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/scream.wav");
}

function soundSetup() {
    squeak.setVolume(0.5);
    aha.setVolume(0.5);
    nibble.setVolume(0.5);
    scream.setVolume(0.5);
}

function setup() {
    createCanvas(600,400);
    frameRate(4); //speed of story
    xPos=(width/2)+180;
    yPos=(height/2)+78;
    yPosCat=600;
    rectMode(CENTER);
    noStroke();
    useSound();
}

function setting() {
    //wall
    background(240); //light gray
    fill(156,56,72); //red
    rect(width/2,25,width,100);

    //mouse hole
    fill(131,122,117); //lighter grayish brown for the hole wall
    rect((width/2)+90,(height/2)+50, 110,200, 80,80);
    fill(96,91,86); //grayish brown for the hole
    rect((width/2)+100,(height/2)+50, 100,200, 80,80);

    //floor
    fill(107,58,15); //brown
    rect(width/2,400,width,200);
}

function cheese() {
    fill(242,205,96); //yellow
    quad(100,350, 200,310, 200,235, 100,250);
    fill(242,232,99); //lighter yellow
    quad(100,350, 60,320, 60,240, 100,250);
    fill(228,186,62); //darker yellow
    triangle(60,240, 100,250, 200,235);

    //holes
    fill(242,205,96); //yellow
    ellipse(70,300,10,30);
    ellipse(90,280,15,40);
    ellipse(80,320,10,20);
    ellipse(75,260,10,20);
}

function mousey(x,y) {
    stroke(170); //gray
    noFill();
    strokeWeight(5);
    curve(x+35,y,x+35,y,x+70,y,x+100,y-50);
    noStroke();
    fill(170); //gray
    rect(x,y, 70,40, 0,80,80,0);
    arc(x-35,y+20, 70,80, PI,0);
    fill(150); //darker gray
    ellipse(x-40,y+20,20,12);
    ellipse(x+15,y+20,20,12);
    ellipse(x-30,y-20,40);
    fill(216,130,157); //pink
    ellipse(x-30,y-20,30);
    ellipse(x-70,y+15,10,10);
    fill(0); //black
    ellipse(x-50,y,10,10);
}

function catShadow(x,y) {
    fill(50,50,50, 80);
    ellipse(x,y,400,200);
    ellipse(x,y+200,200,400);
    triangle(x+50,y-100, x+200,y-25, x+150,y-150);
    triangle(x-50,y-100, x-200,y-25, x-150,y-150);
}

function draw() {
    setting();
    cheese();
    mousey(xPos,yPos);

    //to conceal mouse entering hole
    fill(240); //light gray
    rect((width/2)+200,(height/2)+50, 100,100);
    fill(107,58,15); //brown
    rect(width/2+225,400, 150,200);

    //mouse movement
    if (xPos>260) {
        xPos-=10;
    }

    //cat shadow
    catShadow(width/2,yPosCat);
    if (yPosCat>(height/2) & timer>23) {
        yPosCat-=20;
    }

    if (timer>32) {
        setting();
        cheese();
        push();
        translate(width,0);
        scale(-1,1);
        mousey(xPos+90,yPos);
        pop();
        fill(240); //light gray
        rect((width/2)+225,(height/2)+50, 150,100);
        fill(107,58,15); //brown
        rect(width/2+225,400, 150,200);
        catShadow(width/2, yPosCat);
        if (xPos>30) {
            xPos-=20;
        }
    }

    //sound
    if (timer==0) {
        aha.play();
    }
    if (timer==16 || timer==10) {
        aha.stop();
        squeak.play();
    }
    if (timer==19) {
        nibble.play();
    }
    if (timer==33) {
        scream.play();
    }

    timer+=1;
}

When thinking of a story I could use for this assignment, I thought back to children’s stories and cartoons. Some notable cartoons came to mind, like Tom and Jerry and Looney Tune’s Tweety Bird, and based off of these I decided to do a cat and mouse theme. The basic story I decided on using was: “a mouse comes out of its hole, sees some cheese, then goes over to nibble on it. It sees the shadow of a cat, then scurries back to its hole.” To facilitate this story, I used an aha sound (for when the mouse sees the cheese), a squeak noise (to make the mouse more mousey), a nibble noise (for when the mouse is eating the cheese), and a scream (for when the mouse sees the cat). I think the story is cute and very readable.

LO 10: Sonic Story

sketch

// sketch.js template for sound and DOM
//
// This is the 15104 Version 1 template for sound and Dom.
// This template prompts the user to click on the web page
// when it is first loaded.
// The function useSound() must be called in setup() if you
// use sound functions.
// The function soundSetup() is called when it is safe
// to call sound functions, so put sound initialization there.
// (But loadSound() should still be called in preload().)
var img;
var bx = 20;
var by = 400;
var cx = 20;
var cy = 300;
var tx = 20;
var ty = 200;
var mx = 20;
var my = 100;
var bikeTone;
var bikeDynamics;
var carTone;
var carDynamics;
var trainTone;
var trainDynamics;
var motorcycleTone;
var motorcycleDynamics;

function preload() {
    // call loadImage() and loadSound() for all media files here
}


function setup() {
    // you can change the next 2 lines:
    createCanvas(480, 480);
    createDiv("p5.dom.js library is loaded.");
    //======== call the following to use sound =========
    useSound();
}


function soundSetup() { // setup for audio generation
    // you can replace any of this with your own audio code:
    bikeTone = new p5.Oscillator();
    bikeTone.setType('sine');
    bikeTone.freq(440.0);
    bikeTone.amp(0.1);
    bikeTone.start();
    bikeDynamics = new p5.Oscillator();
    bikeDynamics.setType('sine');
    bikeDynamics.disconnect();
    bikeDynamics.start();
    carTone = new p5.Oscillator();
    carTone.setType('sine');
    carTone.freq(261.63);
    carTone.amp(0.1);
    carTone.start();
    carDynamics = new p5.Oscillator();
    carDynamics.setType('sine');
    carDynamics.disconnect();
    carDynamics.start();
    trainTone = new p5.Oscillator();
    trainTone.setType('sine');
    trainTone.freq(164.81);
    trainTone.amp(0.1);
    trainTone.start();
    trainDynamics = new p5.Oscillator();
    trainDynamics.setType('sine');
    trainDynamics.disconnect();
    trainDynamics.start();
    motorcycleTone = new p5.Oscillator();
    motorcycleTone.setType('sine');
    motorcycleTone.freq(110);
    motorcycleTone.amp(0.1);
    motorcycleTone.start();
    motorcycleDynamics = new p5.Oscillator();
    motorcycleDynamics.setType('sine');
    motorcycleDynamics.disconnect();
    motorcycleDynamics.start();
}


function draw() {
    // you can replace any of this with your own code:
    background(255);
    stroke(0);
    makeBike(bx, by);
    bx += .5;
    makeCar(cx, cy);
    cx += 1;
    makeTrain(tx, ty);
    tx += 1.5;
    makeMotorcycle(mx, my);
    mx += 2;
    bikeDynamics.amp(0.5);
    bikeDynamics.freq(.034);
    bikeTone.amp(bikeDynamics);
    carDynamics.amp(1);
    carDynamics.freq(.06);
    carTone.amp(carDynamics);
    trainDynamics.amp(2);
    trainDynamics.freq(.085);
    trainTone.amp(trainDynamics);
    motorcycleDynamics.amp(2);
    motorcycleDynamics.freq(.12);
    motorcycleTone.amp(motorcycleDynamics);
    if (millis() > 4200 + soundStart) {
       motorcycleTone.stop();
       motorcycleDynamics.stop();
    }
    if (millis() > 6000 + soundStart) {
        trainTone.stop();
        trainDynamics.stop();
    }
    if (millis() > 8400 + soundStart) {
        carTone.stop();
        carDynamics.stop();
    }
    if (millis() > 15800 + soundStart) {
        bikeTone.stop();
        bikeDynamics.stop();
    }
}

function makeBike(x, y) {
    circle(x, y, 20);
    circle(x + 40, y, 20);
    line(x, y - 10, x + 40, y - 10);
    line(x, y - 10, x, y - 20);
    line(x + 40, y - 10, x + 40, y - 30);
    line(x + 30, y - 25, x + 50, y - 35);
    line(x - 10, y - 20, x + 10, y - 20);
}

function makeCar (x, y) {
    rect(x - 20, y - 20, 40, 20);
    rect(x - 40, y, 80, 20);
    circle(x - 30, y + 30, 20);
    circle(x + 30, y + 30, 20);
}

 function makeTrain(x, y) {
    rect(x, y, 20, 20);
    rect(x, y + 20, 40, 20);
    line(x, y + 30, x - 10, y + 30);
    rect(x - 40, y + 20, 30, 20);
    line(x - 40, y + 30, x - 50, y + 30);
    rect(x - 80, y + 20, 30, 20);
    circle(x + 5, y + 45, 10);
    circle(x + 35, y + 45, 10);
    circle(x - 15, y + 45, 10);
    circle(x - 35, y + 45, 10);
    circle(x - 55, y + 45, 10);
    circle(x - 75, y + 45, 10);
} 

function makeMotorcycle(x, y) {
    rect(x, y, 40, 20);
    triangle(x, y, x + 40, y, x + 40, y - 15);
    triangle(x - 20, y, x, y + 15, x, y);
    triangle(x + 40, y, x + 60, y, x + 40, y + 15);
    circle(x - 10, y + 20, 20);
    circle(x + 50, y + 20, 20);
}