top of page
  • pw2257

ICM Midterm Assignment Week 6

Trees

It starts with a blank canvas. You can plant a tree of random size and height by clicking anywhere on the canvas. The more trees you plant, the greener the background will be. You can burn the trees by pressing key b, and fire will appear on each tree. And then, you can summon rain of a random size by pressing key r, and stop the rain by pressing key r again. After raining for a while, the fire will be put out. The raindrops' size will affect how long the fire will be put out. If you stop the rain before the fire is put out, the fire will continue. Press Esc to reset to a blank canvas.


Here's a brief breakdown of the code:

Declare variables and initiate.

let trees = [];
let showTree = true;
let rain;
let raining = false;
let burnTree = false;
let currentFrame;
let duration;
function setup() {
  createCanvas(windowWidth, windowHeight);
  rain = new Rain(0, 0, 0);
}

In draw(), call draw_background() function.

function draw() {
  draw_background();

Also in draw(), show the trees that have been planted, or show the planted trees burning.

  for (let tree of trees) {
    if (showTree == true) {
      tree.plant();
    } else {
      trees.length = 0;
    }
    if (burnTree == true) {
      tree.burn();
    }
  }

Lastly in draw(), show the rain, and after raining a duration of time, stop burning the trees.

  if (raining == true) {
    rain.display();
    if ((frameCount - currentFrame) % duration == 0) {
      burnTree = false;
    }
  }
}

draw_background() function changes the background color based on how many trees have been planted (trees array length). Reduce red and blue value to make the color greener.

function draw_background() {
  let rval = constrain(250 - trees.length, 148, 230);
  let bval = constrain(250 - trees.length, 194, 230);
  background(rval, 255, bval);
}

mousePressed() function is called when mouse is pressed. When the trees are not burning, add a tree of random size to the trees array. Declare the width and height of this tree prior to adding it to maintain its proportion.

function mousePressed() {
  if (burnTree == false) {
    showTree = true;
    let treeWidth = random(20, 40);
    let treeHeight = (treeWidth / 3) * 5;
    trees.push(new Tree(mouseX, mouseY, treeWidth, treeHeight));
  }
}

keyPressed() function is called when any key is pressed. When key r (ASCII code 82) is pressed, make a new rain of random size. Press key r again to erase the rain by making a rain of size 0.

Here it stores a current frameCount, and then in draw(), will compare with the frameCount later to calculate how long it's been raining. Duration to put out the fire is decided by the size of the raindrop.

function keyPressed() {
  if (keyCode === 82) {
    if (raining == false) {
      rain = new Rain(random(8, 15), random(8, 15), random(3, 10));
      raining = true;
      //rain start time
      currentFrame = frameCount;
      //how long it takes to put out fire
      duration = int(map(rain.get_size(), 10, 3, 60, 300));
    } else {
      rain = new Rain(0, 0, 0);
      raining = false;
    }

Again in keyPressed(), when key b (ASCII code 66) is pressed, turn the burning tree on. When key ESC is pressed, erase all the trees and stop raining.

  } else if (keyCode === 66) {
    burnTree = true;
  } else if (keyCode === ESCAPE) {
    showTree = false;
    raining = false;
  }
}

keyReleased() function is called when any key is released. Here it waits for key ESC to release to stop burning trees.

function keyReleased() {
  if (keyCode === ESCAPE) {
    burnTree = false;
  }
}

Class Tree is used to make all the tree objects. In plant(), it draws trees based on input x, y location, width and height.

class Tree {
  constructor(x, y, treeW, treeH) {
    this.x = x;
    this.y = y;
    this.treeW = treeW;
    this.treeH = treeH;
  }

  plant() {
    // draw tree trunk;
    stroke(60, 20, 20);
    strokeCap(PROJECT);
    strokeWeight(this.treeW * 0.3);
    line(this.x, this.y, this.x, this.y - this.treeH * 0.2);
    // draw leaves
    noStroke();
    fill(32, 115, 17);
    triangle(
      this.x,
      this.y - this.treeH,
      this.x - this.treeW / 2,
      this.y - this.treeH * 0.2,
      this.x + this.treeW / 2,
      this.y - this.treeH * 0.2
    );
  }

Also in Class Tree, burn() draws the flames on the locations of the trees. The flames' width and height changes within a second (60 frames) and repeats. It also draws two colors of flames that flash on a different time.

  burn() {
    let fireH = map(frameCount % 60, 0, 60, 5, this.treeH / 2);
    let fireW = map(frameCount % 60, 0, 60, 5, this.treeH / 2);
    if (frameCount % 60 > 0 && frameCount % 60 <= 60) {
      fill(255, 100, 0, 200);
      ellipse(this.x, this.y, fireW, fireH);
    }
    if (frameCount % 60 > 30 && frameCount % 60 <= 60) {
      fill(255, 50, 0, 230);
      ellipse(this.x, this.y, fireW * 0.6, fireH * 0.6);
    }
  }
}


Class Rain is used to make all the rain objects. In get_size(), it returns the size of the rain stroke (raindrop). In display(), it draws a grid of blue rain strokes by looping the rows and columns of input values.

class Rain {
  constructor(rows, cols, size) {
    this.rows = rows;
    this.cols = cols;
    this.size = size;
  }

  get_size() {
    return this.size;
  }

  display() {
    strokeCap(ROUND);
    stroke(117, 188, 255);
    strokeWeight(this.size);
    let rowH = windowHeight / this.rows;
    let colW = windowWidth / this.cols;
    for (let row = 0; row < this.rows; row++) {
      for (let col = 0; col < this.cols; col++) {
        line(
          colW * col,
          rowH * row,
          colW * col + this.size * 2,
          rowH * row + this.size * 2
        );
      }
    }
  }
}


In this assignment, I practiced using class objects and arrays, nested for loops, functions, boolean logic, and adding sketch files. I learned to use frameCount to repeat events over a certian period of time. I Googled color picker to help me find the right RGB values, and I looked up ASCII key code for the key press interaction.

37 views0 comments

Recent Posts

See All

ICM Assignment Week 11 - Sound

When weather changes, suddenly, in the middle of the day... Teammate: Cat Dinh Link: https://editor.p5js.org/josephinewang/sketches/TtiY3Rkur This sound experience is dependent on our classmates in th

bottom of page