Jasmine Lee – Final Project

sing

//Jasmine Lee
//jasmine4@andrew.cmu.edu
//Section C
//Final Project

var nodes = []; //array to hold node objects
var node1c = 1; //node sound counters
var node2c = 1;
var node3c = 1;
var node4c = 1;
var node5c = 1;
var node6c = 1;
var node7c = 1;
var node8c = 1;
var node9c = 1;
var node10c = 1;
var waves; //sound variables
var windchimes;
var rain;
var campfire;
var chant;
var crickets;
var birdwhistle;
var cafe;
var church;
var stream;
var c1; //gradient colors
var c2;
var x1; //gradient controls
var inter;
var c;
var xarray = []; //arrays to hold bubble positions
var yarray = [];
var ydir = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
var r = 0; //bubble colors
var g = 0;
var b = 0;
var bubbY; //controls bubblesNC movement
var bubbY2;
var h; //time
var m;
var s;

function preload() {
    waves = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/waves.mp3")
    windchimes = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/windchimes.wav")
    rain = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/rain.wav")
    campfire = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/campfire.wav")
    chant = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/chant.mp3")
    crickets = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/crickets.wav")
    birdwhistle = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/birdwhistle.wav")
    cafe = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/cafe.m4a")
    church = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/church.wav")
    stream = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/12/stream.wav")
}

function setup() {
    createCanvas(600, 450);
    background(255);

    //creates node objects and gives them parameters
    nodes = [{x: 70, y: 70, d: 40}, //top row of nodes
             {x: 230, y: 120, d: 90},
             {x: 390, y: 75, d: 50},
             {x: 520, y: 130, d: 40},
             {x: 125, y: 235, d: 50}, //middle row of nodes
             {x: 400, y: 230, d: 80},
             {x: 550, y: 270, d: 30}, //bottom row of nodes
             {x: 80, y: 380, d: 80}, 
             {x: 250, y: 330, d: 40},
             {x: 450, y: 370, d: 50},
             ]

    //shows the nodes initially when page is refreshed
    for (var i = 0; i < nodes.length; i ++) {
        fill(200);
        noStroke();
        ellipse(nodes[i].x, nodes[i].y, nodes[i].d)
        }
}

function draw() {
    //gradient background
    c1 = color(255, 255, 255);
    c2 = color(220 + (mouseX * 0.04), 240, 255);
    setGradient(c1, c2);

    //functions that control whether the nodes are colored/white
    n1a();
    n2a();
    n3a();
    n4a();
    n5a();
    n6a();
    n7a();
    n8a();
    n9a();
    n10a();

    //bubbles that follow the mouse
    cursorP();

    //bubbles controlled by clock
    bubblesNC();

    //text
    motivationalText();
}

function mousePressed() {
    //functions that control whether the nodes play/pause sounds
    n1s();
    n2s();
    n3s();
    n4s();
    n5s();
    n6s();
    n7s();
    n8s();
    n9s();
    n10s();
}

function mouseDragged() {
    //adds mouse old coordinates into bubble arrays to create new bubbles
    xarray.push(mouseX)
    yarray.push(mouseY)
}

function setGradient(c1, c2) {
    //creates interactive background gradient
    noFill();
    for (var y = 0; y < height; y++) {
        var inter = map(mouseY, 0, height, 0, 1);
        var c = lerpColor(c1, c2, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

//node 1 appearance
function n1a() { 
    noStroke();
    if (node1c % 2 == 0) {
        fill(255);
    } else {
        fill(245, 204, 240); //periwinkle
    }
    ellipse(70, 70, 40, 40);
}

//node 1 sound
function n1s() { 
    if (mouseX > 50 & mouseX < 90 && mouseY > 50 & mouseY < 90) {
        node1c = node1c + 1;
        if (node1c % 2 == 0) {
            waves.loop();
        } else {
            waves.pause();
        }
    } 
}

//node 2 appearance
function n2a() { 
    if (node2c % 2 == 0) {
        fill(255);
    } else {
        fill(233, 255, 255); //robin's egg blue
    }
    ellipse(230, 120, 90, 90);
}

//node 2 sound
function n2s() { 
    if (mouseX > 185 & mouseX < 275 && mouseY > 75 & mouseY < 165) {
        node2c = node2c + 1;
        if (node2c % 2 == 0) {
            windchimes.loop();
        } else {
            windchimes.pause();
        }
    }
}

//node 3 appearance
function n3a() {
    if (node3c % 2 == 0) {
        fill(255);
    } else {
        fill(217, 240, 255); //light blue
    }
    ellipse(390, 75, 50, 50);
}

//node 3 sound
function n3s() {
    if (mouseX > 365 & mouseX < 415 && mouseY > 50 && mouseY < 100) {
        node3c = node3c + 1;
        if (node3c % 2 == 0) {
            rain.loop();
        } else {
            rain.pause();
        }
    }
}

//node 4 appearance
function n4a() {
    if (node4c % 2 == 0) {
        fill(255);
    } else {
        fill(246, 224, 252); //light pink-purple
    }
    ellipse(520, 130, 40, 40);
}

//node 4 sound
function n4s() {
    if (mouseX > 500 & mouseX < 540 && mouseY > 110 & mouseY < 150) {
        node4c = node4c + 1;
        if (node4c % 2 == 0) {
            campfire.loop();
        } else {
            campfire.pause();
        }
    }
}

//node 5 appearance
function n5a() {
    if (node5c % 2 == 0) {
        fill(255);
    } else {
        fill(217, 195, 242); //light purple
    }
    ellipse(125, 235, 50, 50);
}

//node 5 sound
function n5s() {
    if (mouseX > 100 & mouseX < 175 && mouseY > 210 & mouseY < 260) {
        node5c = node5c + 1;
        if (node5c % 2 == 0) {
            chant.loop();
        } else {
            chant.pause();
        }
    }
}

//node 6 appearance
function n6a() {
    if (node6c % 2 == 0) {
        fill(255);
    } else {
        fill(241, 223, 242); //pale pink
    }
    ellipse(400, 230, 80, 80);
}

//node 6 sound
function n6s() {
    if (mouseX > 360 & mouseX < 440 && mouseY > 190 & mouseY < 270) {
        node6c = node6c + 1;
        if (node6c % 2 == 0) {
            crickets.loop();
        } else {
            crickets.pause();
        }
    }
}

//node 7 appearance
function n7a() {
    if (node7c % 2 == 0) {
        fill(255);
    } else {
        fill(189, 220, 255); //baby blue
    }
    ellipse(550, 270, 30, 30);
}

//node 7 sound
function n7s() {
    if (mouseX > 535 & mouseX < 565 && mouseY > 255 & mouseY < 285) {
        node7c = node7c + 1;
        if (node7c % 2 == 0) {
            birdwhistle.loop();
        } else {
            birdwhistle.pause();
        }
    }
}

//node 8 appearance
function n8a() {
    if (node8c % 2 == 0) {
        fill(255);
    } else {
        fill(238, 210, 242); //mauve
    }
    ellipse(80, 380, 80, 80);
}

//node 8 sound
function n8s() {
    if (mouseX > 40 & mouseX < 120 && mouseY > 340 & mouseY < 420) {
        node8c = node8c + 1;
        if (node8c % 2 == 0) {
            cafe.loop();
        } else {
            cafe.pause();
        }
    }
}

//node 9 appearance
function n9a() {
    if (node9c % 2 == 0) {
        fill(255);
    } else {
        fill(235, 154, 240); //light blue-purple
    }
    ellipse(250, 330, 40, 40);
}

//node 9 sound
function n9s() {
    if (mouseX > 230 & mouseX < 270 && mouseY > 310 & mouseY < 350) {
        node9c = node9c + 1;
        if (node9c % 2 == 0) {
            church.loop();
        } else {
            church.pause();
        }
    }
}

//node 10 appearance
function n10a() {
    if (node10c % 2 == 0) {
        fill(255);
    } else {
        fill(206, 228, 237); //pale blue
    }
    ellipse(450, 370, 50, 50);
}

//node 10 sound
function n10s() {
    if (mouseX > 425 & mouseX < 475 && mouseY > 345 & mouseY < 395) {
        node10c = node10c + 1;
        if (node10c % 2 == 0) {
            stream.loop();
        } else {
            stream.pause();
        }
    }
}

//controls cursor generated bubbles and their movement
function cursorP() {
    for (var i = 0; i < xarray.length; i ++) {
        //gives floating bubbles flashing colors
        r = random(220, 255);
        g = random(220, 255);
        b = random(220, 255);
        fill(r, g, b);

        //creates bubbles when mouse is dragged
        ellipse(xarray[i], yarray[i], i, i)

        //makes bubbles bounce off bottom of canvas
        if (yarray[i] > (450 - (i / 2))) {
            ydir[i] = -(ydir[i]);
            yarray[i] = (450 - (i / 2)) - 1;
        } else {
            yarray[i] = yarray[i] + ydir[i]; 
        }

        //makes bubbles bounce off top of canvas
        if (yarray[i] < (i / 2)) {
            ydir[i] = -(ydir[i]);
            yarray[i] = (i / 2) - 1;
         } else {
            yarray[i] = yarray[i] + ydir[i];
        }

        //makes bubbles bounce off nodes
        for (var j = 0; j < nodes.length; j ++) {
            if ((dist(xarray[i], yarray[i], nodes[j].x, nodes[j].y)) < (((nodes[j].d) / 2) + (i / 2))) {
                ydir[i] = -(ydir[i]);
                if (ydir[i] > 0) {
                    //lets bubbles bounce off bottom of nodes
                    yarray[i] = yarray[i] + (i / 2) + 1; 
                } else {
                    //lets bubbles bounce off top of nodes
                    yarray[i] = yarray[i] - (i / 2) - 1; 
                }
            }
        }
    }

    //deletes bubbles if there are more than 25
    if (xarray.length > 25) {
        xarray.shift();
        yarray.shift();
    }
}

function bubblesNC() {
    h = hour();
    m = minute ();
    s = second ();

    //moves 7.5 pixels down for every second that passes
    bubbY = s * 7.5;
    bubbY2 = 450 - (s * 7.5);

    noStroke();
    //white bubbles
    fill(255, 255, 255, 100);
    ellipse(70, bubbY, 200, 200);
    ellipse(200, bubbY + 20, 80, 80);
    ellipse(450, bubbY - 40, 320, 320);
    ellipse(300, bubbY2, 80, 80);
    ellipse(30, bubbY2, 130, 130);
    ellipse(520, bubbY + 5, 100, 100);
    ellipse(370, bubbY2 - 15, 220, 220);
}

function motivationalText() {
    //adds text to center of the screen
    textAlign(CENTER, CENTER);
    textSize(30);
    textStyle(BOLDITALIC);
    fill(255, 255, 255);
    text('hello', 300, 195);
    fill(255, 255, 255);
    text('hello', 300, 225);
    fill(255, 255, 255, 200);
    text('hello', 300, 255);

}

For my final project, I intended to create a dreamlike atmosphere. The sounds that the nodes play are a mystery, with the user having to click them to discover what they are. The project acts as a sort of music sampler to allow the user to play whatever tracks they’d like to hear at the same time. Once the music is on, the node disappears into the white background, with the user having to interact with the color changing background to find the node again. When the mouse is dragged, many bubbles are created that bounce around the canvas and off the music nodes to create visual interest for the user. When all the sounds are being played and the mouse is used to make the background white, an interesting “screensaver” is created with the negative space.

Leave a Reply