nahyunk1 & yugyeonl Final



How to open up and run the file:

  1. download and unzip the files below.
  2. nahyunk1-yugyeonl-final project
  3. songs
  4. extract “sound1”, “sound2”, and “sound3” music files from the songs folder and put them into the “assets” folder inside the final project folder.
  5. turn on terminal or node and run local server.
  6. access the sketch.js inside the final project folder.
  7. play and enjoy the songs by entering either 1, 2, 3 on your keyboard.

The project file was too large so we had to upload the songs separately in another folder along with the zip file of our code. Our project was based on the idea of generating animation with the kiwi bird and creating its walkthrough with the incorporation of music affecting the background of the landscape. There are three parts to the scenes: pressing 1 on your keyboard will affect your current scene to an urban landscape. Similarly, when either 2 or 3 is pressed, different scenes and music replace the current scene with different parts of the landscape responding to the beat, frequency, and the amplitude of the music assigned. The parts of the landscapes were drawn with the incorporation of the FFT(); function and the p5.Amplitude(); function which analyzes the frequency and the volume of the music when it is played. Some of the interesting factors that our animation consisted was the sun beam which would draw itself in an ellipse in a form of measured frequency and the stars and the moon which brightens and glistens depending on the beat of the music played at night. Throughout, we put a lot of effort learning and incorporating the p5.sound materials, creating a variety of landscapes with music chosen according to the mood of our scenes, and generally coding different functions and figuring out ways for our code to understand the switching of the scenes and the play of different music files.

**scene 2 consists of a song that is relatively louder than the other scenes that contain music files. We’ve put code for the sound of the song to be reduced, but the song still plays comparatively loud. Please be careful with the volume of your headphones.

 

sketch

var kiwi;             
var kiwiX = 200;        //kiwi locationX
var kiwiY = 310;        //kiwi locationY
var tree = [];          //array of trees
var treeAssets = [];
var shell = [];         //array of shells
var shellAssets = [];
var coin = [];          //array of coins
var coinAssets = [];
var gem = [];           //array of gems
var gemAssets = [];
var buildings = [];     //array of buildings
var ocean = [];         //array of mountain
var mountain = [];      //array of ocean
var stars = [];         //array of stars
var clouds = [];        //array of clouds
var sound1;
var sound2;
var sound3;
var amplitude; 
var volArray = [];      //array that stores volume
var timeState = "morning";    //determines initial state of time

function preload() {
    sound1 = loadSound("assets/sound1.mp3");
    sound2 = loadSound("assets/sound2.mp3");
    sound3 = loadSound("assets/sound3.mp4");
    var treeLinks = ["assets/palmtree0.png", "assets/palmtree1.png", 
                    "assets/palmtree2.png", "assets/palmtree3.png"];
    //load tree images
    for (var t = 0; t < treeLinks.length; t++) {
        treeAssets[t] = loadImage(treeLinks[t]);
    }
    //load shell images
    for (var i = 0; i < 1; i++){
        shellAssets[i] = loadImage("assets/shell.png");
    }
    //load coin images
    for (var i = 0; i < 1; i++){
        coinAssets[i] = loadImage("assets/coin.png");
    }
    //load gem images
    for (var i = 0; i < 1; i++){
        gemAssets[i] = loadImage("assets/gem.png");
    }
}

function setup() {
    createCanvas(1000, 700);
    imageMode(CENTER);
    //load amplitude
    amplitude = new p5.Amplitude();
    //load fft 
    fft = new p5.FFT();
    sound1.setVolume(1);
    sound2.setVolume(0.00000001);
    sound3.setVolume(1);
    //create initial set of trees
    for (var i = 0; i < 4; i ++) {
        var treeX = random(width);
        tree[i] = makeTrees(treeX);
    }
    //create initial set of shells
    for (var i = 0; i < 5; i ++) {
        var shellX = random(360, width);
        shell[i] = makeShells(shellX);
    }
    //create initial set of coins
    for (var i = 0; i < 5; i ++) {
        var coinX = random(360, width);
        coin[i] = makeCoins(coinX);
    }
    //create initial set of gems
    for (var i = 0; i < 5; i ++) {
        var gemX = random(360, width);
        gem[i] = makeGems(gemX);
    }
    //create initial set of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    //create initial set of clouds
    for (var i = 0; i < 10; i++) {
      var cloudX = random(width);
      var cloudY = random(height/2);
      clouds[i] = makeClouds(cloudX, cloudY);
    }
    //create kiwi animation
    createKiwi(kiwiX, kiwiY);  
    //ocean
    makeOcean(height - 220, 30, 0.00005, 0.0005, color(197, 227, 234));
    makeOcean(height - 180, 80, 0.00005, 0.001, color(225, 211, 185));  
    //mountain
    makeMountain(height - 400, 200, 0.00005, 0.0025, color(15));
    makeMountain(height - 350, 300, 0.00015, 0.006, color(0));
}

function draw() {
    if (timeState == "morning") {
        morning();
        if (sound1.isPlaying() == false){
          sound1.play();
        }  else if (sound2.isPlaying() ==  true){
          sound2.stop();
        }  else if (sound3.isPlaying() ==  true){
          sound3.stop();
        }
    } if (timeState == "afternoon") {
        afternoon();
        if (sound2.isPlaying() == false){
          sound2.play();
        }
        else if (sound1.isPlaying() ==  true){
          sound1.stop();
        } else if (sound3.isPlaying() ==  true){
          sound3.stop();
        }
    } if (timeState == "night") {
        night();
        if (sound3.isPlaying() == false){
          sound3.play();
        }  if (sound1.isPlaying() == true){
          sound1.stop();
        }  else if (sound2.isPlaying() ==  true){
          sound2.stop();
        }
    } 
}

function keyPressed() {
    if (key == '1') {
        timeState = "morning";
    } if (key == '2') {
        timeState = "afternoon";
    } else if (key == '3') {
        timeState = "night";
    }
}

function morning() {
    //gradient background color
    var from = color(125, 133, 216);
    var to = color(220, 224, 251);
    setGradient(0, from, to, 3.5 * height / 5);
    //lines in the background showing frequency
    skyFreq(0, 125);
    //sun
    makeSun(width / 4 - 100, 550, 236, 191, 113, 300);
    //ground
    noStroke();
    fill(96, 91, 103);
    rect(0, 3.5 * height / 5 - 10, width, 0.5 * height / 5);
    fill(127, 109, 123);
    rect(0, 4 * height / 5 - 10, width, height / 4);
    //clouds
    updateAndDisplayClouds();
    addClouds();
    //buildings
    updateAndDisplayBuildings();
    addBuildings();
    //kiwi
    drawKiwi();
    //coins
    updateAndDisplayCoins();
    addCoins();
}

function afternoon() {
    //gradient background color
    var from = color(20, 140, 172);
    var to = color(209, 255, 249);
    setGradient(0, from, to, 3.5 * height / 5);
    //lines in the background showing frequency
    skyFreq(100, 48);
    //ocean & sand
    noStroke();
    moveOcean();
    //sun
    makeSun(3 * width / 4, 90, 243, 229, 202, 150);  
    //sun outline based on frequency
    sunFreq();     
    //trees
    updateAndDisplayTrees();
    addTrees(); 
    //kiwi
    drawKiwi();     
    //shells
    updateAndDisplayShells();
    addShells();
}

function night() {
    //gradient background color
    var from = color(25, 0, 51);
    var to = color(51, 0, 102);
    setGradient(0, from, to, 3.5 * height / 5);
    //stars
    updateAndDisplayStars();
    removeStars();
    addStars();
    drawStars();
    //moon
    makeMoon();
    //mountain
    strokeWeight(random(0.2, 0.4));
    stroke(random(0,255), random(0,255), random(0,255));
    moveMountain();
    //ground
    noStroke();
    fill(18, 13, 17);
    rect(0, 3.5 * height / 5, width, 1.5 * height / 5);
    //kiwi
    drawKiwi();
    //gems
    updateAndDisplayGems();
    addGems();
    //sound
}

function setGradient (y, from, to, length) {
    //top to bottom gradient (background)
    for (var i = y; i <= length; i++) {
        var inter = map(i, y, width, 0, 1);
        var c = lerpColor(from, to, inter);
        stroke(c);
        strokeWeight(2);
        line(0, i, width, i);
    }
}

function makeSun(sunX, sunY, r, g, b, diam) {
    noStroke();
    //glowing gradient sunlight
    for (var i = 0; i < 30; i++) {
        var value = random(7, 8);
        var transparency = 100 - value * i;
        fill(r + 2 * i / 3, g + 7 * i / 3, b + i, transparency);
        ellipse(sunX, sunY, diam + 20 * i, diam + 20 * i);
    }
    //sun
    fill(r, g, b, 100);
    ellipse(sunX, sunY, diam, diam);
}

function sunFreq() {    //sun outline
    angleMode(DEGREES);
    //analyze level of the amplitude
    var vol = amplitude.getLevel();
    //array that pushes the volume in the array
    volArray.push(vol);
    stroke(255);
    strokeWeight(.5);
    noFill();
    push();
    translate(width - 240, 90);
    scale(2.5);
    //shape that represent the range of the frequency
    beginShape();
    for (var i = 0; i < 360; i ++){
        var r = map(volArray[i], 0, 1, 10, 100);
        var x = r * cos(i);
        var y = r * sin(i);
        vertex(x ,y);
    }
    endShape();
    pop();
    //360 because the reperesentation draws in an ellipse
    if (volArray.length > 360){
        volArray.splice(0, 1);
    }  
}

function skyFreq(offset, spacingX) {    //background lines
    var w = width / spacingX;
    //anaylze the fft
    var spectrum = fft.analyze();
    push();
    translate(0, offset);
    beginShape();
    //draws the frequency level as lines behind the ocean
    for (var i = 0; i < spectrum.length; i++){
        var angle = map(i, 0, spectrum.length, 0, 360);
        var amp = spectrum[i];
        var r = map(amp, 0, 256, 40, 200);
        var y = map(amp, 0, 256, height, 0);
        stroke(255);
        strokeWeight(0.5);
        line(i * w, height, i * w, y);
    }
    endShape();
    pop();
}

function cityFreq() {

}

function makeMoon() {
    //size of moonlight depends on the amplitude
    for (var c = 0; c < 30; c++){
        var level = amplitude.getLevel();
        noStroke();
        fill(217, 154, 100, (10 - c) * level * 50);
        ellipse(850, 150, 90 + (10 * c) + level, 90 + (10 * c) +  level);
        stroke(255, 223, 181);
        fill(255, 223, 181);
        ellipse(850, 150, 100, 100);
        fill(252, 240, 224);
        ellipse(858, 150, 85, 85);
    }
}

function drawKiwi() {  //create kiwi   
    push();
    translate(kiwiX, kiwiY);
    scale(0.6, 0.6);
    drawSprites();
    pop();
}

function createKiwi(x, y) {  //create sprite at a random position
    kiwi = createSprite(x, y);
    kiwi.addAnimation("assets/kiwi0.png","assets/kiwi1.png",
                  "assets/kiwi2.png","assets/kiwi3.png","assets/kiwi4.png","assets/kiwi5.png","assets/kiwi6.png",
                  "assets/kiwi7.png","assets/kiwi8.png","assets/kiwi9.png","assets/kiwi10.png",
                  "assets/kiwi11.png","assets/kiwi12.png","assets/kiwi13.png","assets/kiwi14.png");
}

function makeOcean(landscapeY, landscapeR, landscapeS, landscapeD, landscapeC) {
    var landscape = {ly: landscapeY,     //locationY
                range: landscapeR,      //range of how far landscape goes up
                speed: landscapeS,      //speed of the landscape
                detail: landscapeD,     //detail (how round/sharp)
                color: landscapeC,      //color of the landscape
                draw: drawLandscape}
    ocean.push(landscape);
}

function makeMountain(landscapeY, landscapeR, landscapeS, landscapeD, landscapeC) {
    var landscape = {ly: landscapeY,     //locationY
                range: landscapeR,      //range of how far landscape goes up
                speed: landscapeS,      //speed of the landscape
                detail: landscapeD,     //detail (how round/sharp)
                color: landscapeC,      //color of the landscape
                draw: drawLandscape}
    mountain.push(landscape);
}

function drawLandscape() {  //generating landscape from code provided
    fill(this.color);
    beginShape();
    vertex(0, height);
    for (var i = 0; i < width; i++) {
        var t = (i * this.detail) + (millis() * this.speed);
        var y = map(noise(t), 0, 1, this.ly - this.range / 2, this.ly + this.range / 2);
        vertex(i, y); 
    }
    vertex(width, height);
    endShape(CLOSE);
}

function moveOcean() { //move the landscape
    for (var i = 0; i < ocean.length; i++) 
        ocean[i].draw();
}

function moveMountain() { //move the landscape
    for (var i = 0; i < mountain.length; i++) 
        mountain[i].draw();
}

//palm trees
function updateAndDisplayTrees() {
    //keeps the trees moving along the x-axis
    for (var i = 0; i < tree.length; i++) {
        tree[i].moveTree();
        tree[i].drawTree();
   }
}

function drawTrees() { //draws the trees
    image(treeAssets[this.nFloor], this.x + 200, this.y - 100);
}

function moveTrees() { //move the trees
    this.x -= this.speed;
}

function addTrees() { //places in more trees into the array
    var newTreesProbability = 0.0015;
    if (random(0, 1) < newTreesProbability) {
        tree.push(makeTrees(width));
   }
}

function makeTrees(originX) {
    var palmtrees = {
        x: originX,
        y: random(400, 420),
        speed: 0.55,
        nFloor: floor(random(0, 3)),
        moveTree: moveTrees,
        drawTree: drawTrees}
    return palmtrees;
}

//shells
function updateAndDisplayShells() {
    //keeps the shells moving along the x-axis
    for (var i = 0; i < shell.length; i++) {
        shell[i].moveShell();
        shell[i].drawShell();
    }
}

function drawShells() { //draws the shells
    push();
    translate(this.x + 100, this.y);
    scale(0.25, 0.25);
    image(shellAssets[0], 0, 0);
    pop();
}

function moveShells() { //move the shells
    this.x -= this.speed;
}

function addShells() {  //places in more trees into the array
    var newTreesProbability = 0.0035; 
    if (random(0, 1) < newTreesProbability) {
        shell.push(makeShells(width));
    }
}

function makeShells(shellX) {
    var shells = {
        x: shellX,
        y: 610,
        speed: 1,
        moveShell: moveShells,
        drawShell: drawShells}
    return shells;
}

//budilings
function updateAndDisplayBuildings(){
    //keeps the buildings moving along the x-axis
    for (var i = 0; i < buildings.length; i++) {
        buildings[i].move();
        buildings[i].display();
    }
}

function addBuildings() {  //places in more buildings into the array
    var newBuilding = 0.006; 
    if (random(0,1) < newBuilding) {
        buildings.push(makeBuilding(width));
    }
}

function moveBuildings() { //move the buildings
    this.x -= this.speed;
}

function drawBuildings() { //draws the buildings
    var floorHeight = 45;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke();
    fill(this.buildingC); 
    translate(this.x, height - 180);
    rect(0, -bHeight, this.breadth, bHeight);
    for (var y = 0; y < this.nFloors; y++) {
        for (var x = 0; x < 6; x++){
            noStroke();
            fill(255, 221, random(100, 150));
            rect(x * (this.breadth / 7) + 10, -25 - (y * floorHeight), this.breadth / 12, 20);
        }
    }
    pop();
}

function makeBuilding(buildingX) {
    var building = {x: buildingX,
        breadth: random(100, 125),
        speed: 0.55,
        buildingC: color(random(150, 225), random(100, 175), random(100, 175)),
        nFloors: round(random(4, 10)),
        move: moveBuildings,
        display: drawBuildings}
    return building;
}

//coins
function updateAndDisplayCoins() {
    //keeps the coins moving along the x-axis
    for (var i = 0; i < coin.length; i++) {
        coin[i].moveCoins();
        coin[i].drawCoins();
    }
}

function drawCoins() { //draws the coins
    push();
    translate(this.x + 100, this.y);
    scale(0.3, 0.3);
    image(coinAssets[0], 0, 0);
    pop();
}

function moveCoins() { //move the coins
    this.x -= this.speed;
}

function addCoins() { //places in more coins into the array
    var newTreesProbability = 0.0035;
    if (random(0, 1) < newTreesProbability) {
        coin.push(makeCoins(width));
   }
}

function makeCoins(coinX) {
    var coins = {
        x: coinX,
        y: 610,
        speed: 1,
        moveCoins: moveCoins,
        drawCoins: drawCoins}
    return coins;
}

//gems
function updateAndDisplayGems() {
    //keeps the gems moving along the x-axis
    for (var i = 0; i < gem.length; i++) {
        gem[i].moveGems();
        gem[i].drawGems();
    }
}

function drawGems() { //draws the gems
    push();
    translate(this.x + 100, this.y);
    scale(0.3, 0.3);
    image(gemAssets[0], 0, 0);
    pop();
}

function moveGems() { //move the gems
    this.x -= this.speed;
}

function addGems() { //places in more gems into the array
    var newTreesProbability = 0.0035;
    if (random(0, 1) < newTreesProbability) {
        gem.push(makeGems(width));
   }
}

function makeGems(gemX) {
    var gems = {
        x: gemX,
        y: 610,
        speed: 1,
        moveGems: moveGems,
        drawGems: drawGems}
    return gems;
}

//stars
function updateAndDisplayStars() {
    //keeps the stars moving along the x-axis
    for (var i = 0; i < stars.length; i++){
        stars[i].move();
        stars[i].display();
    }
}

function removeStars() {  //remove stars out of canvas
    var starsKeep = [];
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x + stars[i].breadth > 0) {
            starsKeep.push(stars[i]);
            }
    }
    stars = starsKeep; //remaining stars
}

function addStars() { //places in more trees into the array
    var newTreesProbability = 0.0075;
    if (random(0,1) < newTreesProbability) {
        stars.push(makeStars(width));
    }
}

function moveStars() {  //move the stars
    this.x -= this.speed;
}

function drawStars() { //draws the coins
    strokeWeight(random(0.5, 3));
    stroke(random(0, 255), (0, 255), (0, 255));
    push();
    translate(this.x, 20);
    // the size of the stars depends on the amplitude 
    for (var i = 0; i < stars.length; i++) {
        var level = amplitude.getLevel();
        var size = map(level, 0, 1, 0, 1);
        fill(random(0, size), (0, size), (0, size));
        ellipse(random(10, 3.5 * height / 5), random(10, 3.5 * height / 5), size, size);
    }
    pop();
   }

function makeStars(birthLocationX) {
    var star = {
        x: birthLocationX,
        breadth: 50,
        speed: 1,
        move: moveStars,
        display: drawStars}
    return star;
 }

 //clouds
function updateAndDisplayClouds() {
    //update the clouds' position & draw them
    for (var i = 0; i < clouds.length; i++) {
        clouds[i].move();
        clouds[i].draw();
    }
}

function makeClouds(cloudX, cloudY) {
    var cloud = {x: cloudX,             //locationX of cloud
        y: cloudY,                      //locationY of the cloud
        offsetX: random(30, 100),
        offsetY: random(100, 175),
        breadth: random(300, 400),      //width of the cloud
        speedC: -random(1, 2),          //speed of the cloud
        nFloors: round(random(2, 8)),   //multiplier that determines the height of the cloud
        transparency: random(20, 60),   //transparency of the cloud
        move: moveClouds,
        draw: drawClouds}
    return cloud;
}

function drawClouds() {
    var multiplier = 5; //multiplier that determines the height of the cloud
    var cloudHeight = this.nFloors * multiplier;
    ellipseMode(CENTER);
    noStroke();
    fill(255, this.transparency);
    //cloud height reacts to the amplitude
    var level = amplitude.getLevel();
    push();
    translate(this.x, height / 2 - this.offsetY);
    ellipse(this.breadth/2, -cloudHeight, this.breadth, cloudHeight + 500 * level);
    pop();
    push();
    translate(this.x, height / 2 - this.offsetY - 50);
    ellipse(this.breadth/2 + this.offsetX, -cloudHeight, this.breadth, cloudHeight + 500 * level);
    pop();
}

function moveClouds() {
    //move clouds by updating its x position
    this.x += this.speedC;
}

function addClouds() {
    //new clouds from the right edge of the canvas
    var newCloudsProbability = 0.0075;
    //likliness of new clouds
    if (random(0, 1) < newCloudsProbability) {
        var cloudX = width;
        var cloudY = random(height / 2);
        clouds.push(makeClouds(cloudX, cloudY));
    } 
}

Leave a Reply