Jdbrown – Final Project – iRony

To begin typing, begin typing.

My final project is a Braille typing interface. Since hardly anyone who can see can read Braille, and hardly anyone who can read Braille can see, It’s meant to be used as a venting system – like writing a letter you’ll never send. The program allows typing of all letters and some punctuation (i.e. question mark, space, enter keys). Once one has typed enough, the program will reset the canvas and repeatedly erase what the user has written. “Delete” will reset the canvas / program.

irony

// Joshua Brown
// Jdbrown@andrew.cmu.edu
// Final Project: Braille Writing: "Irony"
// Section C

var dotSize = 8;        // size of Braille dots
var dotX = 10;          // x co-ordinate of each dot
var dotY = 10;          // y co-ordinate of each dot
var dotDis = 10;        // distance between dots;
var t1;                 // turtle object
var counter = 0;        // counter for "transition" function
var back = 0;           // background variable
var col = 0;            // color variable
var spd = 0.5;          // speed variable

function setup () {

    createCanvas (480, 500);
    background (255);

}

function draw () {

    transition(); // function erases the canvas, erases typed input periodically
    
}

function transition() {

    if (counter < 20) {                 // if the user has entered fewer
        col = 0;                        // than 20 letters, dot color is black
    } 

    if (counter > 20 & col < 240) {    // if the user has entered more than
        col += 0.5;                     // 20 letters, dot color lightens
    }

    if (counter > 20) {                 // if the user has entered more than
        col += 1;                       // 20 letters, dot color lightens
    } 

    if (col > 200) {                    // if the dot color is whitish,
        background(back += 1);          // de-draw the background, lighter
        col = 255;                      // dot color is black.
    } 

    if (back >= 255) {                  // if the background is white,
        col = 1;                        // dot color is black
        back -= 0.25;                   // background darkens
    }

    if (counter >= 150) {
        background (255);
        col = 0;
        noLoop();
    }
}

function keyPressed() {

    var t1 = makeTurtle (dotX, dotY);
    print (keyCode);

    if (keyIsPressed) {     // when a key is pressed, increase the counter;
        counter += 1;       // move the Turtle over to mimic space between letters.
        print (counter);
        dotX += 26;
    }

    if (keyCode == 8) {     // when the delete key is pressed, 
        background (255);   // clear the canvas and reset the turtle position.
        dotX = 10;          // clear the counter back to 0;
        dotY = 10;
        counter = 0;
        draw();
    }

    if (dotX > (width - 5)) {   // when the dotX goes beyond the canvas, reset it to keep it on
        dotY += 45;
        dotX = 10;
    }
    if (dotY > (height - 5)) {  // if tying goes beyond the canvas, fix it.
        dotY = 10;
        dotX = 10;
        background(255);
    }
    if (keyCode == 32) {    // creating a space w/ spacebar;
        makeSpace(t1);
    }
    if (keyCode == 65) {
        makeA(t1);
    }
    if (keyCode == 66) {
        makeB(t1);
    }
    if (keyCode == 67) {
        makeC(t1);
    }
    if (keyCode == 68) {
        makeD(t1);
    }
    if (keyCode == 69) {
        makeE(t1);
    }
    if (keyCode == 70) {
        makeF(t1);
    }
    if (keyCode == 71) {
        makeG(t1);
    }
    if (keyCode == 72) {
        makeH(t1);
    }
    if (keyCode == 73) {
        makeI(t1);
    }
    if (keyCode == 74) {
        makeJ(t1);
    }
    if (keyCode == 75) {
        makeK(t1);
    }
    if (keyCode == 76) {
        makeL(t1);
    }
    if (keyCode == 77) {
        makeM(t1);
    }
    if (keyCode == 78) {
        makeN(t1);
    }
    if (keyCode == 79) {
        makeO(t1);
    }
    if (keyCode == 80) {
        makeP(t1);
    }
    if (keyCode == 81) {
        makeQ(t1);
    }
    if (keyCode == 82) {
        makeR(t1);
    }
    if (keyCode == 83) {
        makeS(t1);
    }
    if (keyCode == 84) {
        makeT(t1);
    }
    if (keyCode == 85) {
        makeU(t1);
    }
    if (keyCode == 86) {
        makeV(t1);
    }
    if (keyCode == 87) {
        makeW(t1);
    }
    if (keyCode == 88) {
        makeX(t1);
    }
    if (keyCode == 89) {
        makeY(t1);
    }
    if (keyCode == 90) {
        makeZ(t1);
    }
    if (keyCode == 191) {
        makeQuestion(t1);
    }
    if (keyCode == 13) {
        dotY += 45;
        dotX = 10;
    }
}

function makeA (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeB (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
    t1.penUp();
}

function makeC (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

}

function makeD (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeE (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

}

function makeF (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeG (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeH (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeI (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeJ (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeK (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeL (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeM (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeN (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeO (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeP (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeQ (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeR (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeS (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeT (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeU (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeV (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeW (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeX (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeY (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);
}

function makeZ (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeSpace (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

function makeQuestion (t1) {

    t1.setColor(col);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.forward(dotDis / 20);
}

// makeTurtle(x, y) -- make a turtle at x, y, facing right, pen down
// left(d) -- turn left by d degrees
// right(d) -- turn right by d degrees
// forward(p) -- move forward by p pixels
// back(p) -- move back by p pixels
// penDown() -- pen down
// penUp() -- pen up
// goto(x, y) -- go straight to this location
// setColor(color) -- set the drawing color
// setWeight(w) -- set line width to w
// face(d) -- turn to this absolute direction in degrees
// angleTo(x, y) -- what is the angle from my heading to location x, y?
// turnToward(x, y, d) -- turn by d degrees toward location x, y
// distanceTo(x, y) -- how far is it to location x, y?

function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;


/*function TEMPLATE (t1) {

    t1.setColor(0);                 // defining the top left
    t1.setWeight(dotSize);
    t1.penUp();
    t1.forward(dotDis);
    t1.right(90);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the mid left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining the bottom left;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining "turn into second column"
    t1.left(90);                    // and bottom right
    t1.forward(dotDis);
    t1.penDown();
    t1.left(90);
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining mid right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

    t1.penUp();                     // defining top right;
    t1.forward(dotDis);
    t1.penDown();
    t1.forward(dotDis / 20);

}

    Keycodes for letters:
    a = 65, b = 66, c = 67, d = 68
    e = 69, f = 70, g = 71, h = 72,
    i = 73, j = 74, k = 75, l = 76,
    m = 77, n = 78, o = 79, p = 80,
    q = 81, r = 82, s = 83, t = 84,
    u = 85, v = 86, w = 87, x = 88,
    y = 89, z = 90;
    */
    
    /*noStroke();
    fill (0);

    ellipse (dotX, dotY, dotSize, dotSize);         // top left;
    ellipse (dotX * 2, dotY, dotSize, dotSize);     // top right;
    ellipse (dotX, dotY * 2, dotSize, dotSize);     // mid left;
    ellipse (dotX * 2, dotY * 2, dotSize, dotSize); // mid right;
    ellipse (dotX, dotY * 3, dotSize, dotSize);     // bottom left;
    ellipse (dotX * 2, dotY * 3, daotSize, dotSize); // bottom right;

    //ellipse (10, 10, 10, 10); // defining the top left;
    //ellipse (20, 10, 10, 10); // defining the top right;
    //ellipse (10, 20, 10, 10); // defining the mid left;
    //ellipse (20, 20, 10, 10); // defining the mid right;
    //ellipse (10, 30, 10, 10); // defining the bottom left;
    //ellipse (10, 30, 10, 10); // defining the bottom right;
*/
}

mjeong1-Final Project-Section A

To play, use the array keys to move the player(waiter) to left,right,up and down. And you may use space bar to create bullets(hamburger). If the waiter collides with the burger, the game is over.

sketch

//Min Young Jeong
//mjeong1@andrew.cmu.edu
//section A
//Final Project

var screenwidth = 500;
var screenheight = 300;
//setting up three functions each for the player,bullets,and targets
//waiter(player)

var waiter = {
    x : 280,
    width : 60,
    y : 240,
    height: 60,
    draw : function(){
        image(img_waiter, this.x, this.y, this.width, this.height);
    }
}

//burger
var burger  = [];
function Burger(I){
    I.active = true;
    I.x =random(500);
    I.y = 0;
    I.width = 50;
    I.height = 50;
    I.speed = 2;
    I.inBounds = function(){
        return I.x >= 0 & I.y >= 0 && I.x < screenwidth - I.width && I.y < screenheight - I.height;
    }
    I.draw = function(){
        image(img_Burger, I.x, I.y, I.width, I.height);
    }
    I.update= function(){
        I.active = I.active & I.inBounds();
        I.y += I.speed;
    }
    return I;
}

//Coke(bullets)

var coke = [];
function Coke(I){
    I.active = true;
    I.x = waiter.x;//use the same x and y for the initial origin point
    I.y = waiter.y;
    I.width = 30;
    I.height = 30;
    I.speed = 20;
    I.inBounds = function(){
        return I.x >= 0 & I.y >= 0 && I.x < screenwidth - I.width && I.y < screenheight -  I.height;
    }
    I.update = function(){
        I.active  = I.active & I.inBounds();
        I.y -= I.speed;
    }
    I.draw = function(){
        image(img_Coke, I.x, I.y, I.width, I.height);
    }
    return I;
}

//shooting function

function shooting(Burger, Coke){
    return Coke.x + Coke.width >= Burger.x & Coke.x < Burger.x + Burger.width &&
            Coke.y + Coke.height >= Burger.y && Coke.y < Burger.y + Burger.height;
}
//canvas functions 
var img_Burger, img_waiter, img_Coke,img_background;
var score = 0;

function preload(){
    img_Burger = loadImage("https://i.imgur.com/4qXtEIR.png");
    img_waiter = loadImage("https://i.imgur.com/7IGyR4c.png");
    img_Coke = loadImage("https://i.imgur.com/ugtVBKn.png");
    img_background = loadImage("https://i.imgur.com/eHRSSik.jpg");
}//preloading images for each characters

function setup(){
    createCanvas(screenwidth, screenheight);
    noCursor();
}

function draw(){
    clear();
    image(img_background,0,0);
    fill(0);
    text("score : " + score, 10, 10);
    if(keyIsDown(LEFT_ARROW)){
        if(waiter.x-5 >= 0)
            waiter.x -= 5;
        else
            waiter.x = 0;
    }//left key to move the player to the left 
    if(keyIsDown(RIGHT_ARROW)){
        if(waiter.x + 5 <= screenwidth-waiter.width)
            waiter.x += 5;
        else
            waiter.x = screenwidth - waiter.width;
    }//right key to move the player to the right
    if(keyIsDown(UP_ARROW)){
        if(waiter.y-5 >= 0)
            waiter.y -= 5;
        else
            waiter.y = 0;
    }//upward key to move the player upward
    if(keyIsDown(DOWN_ARROW)){
        if(waiter.y + 5 <= screenheight-waiter.height)
            waiter.y += 5;
        else
            waiter.y = screenheight - waiter.height;
    }//downward key to move the player downward 
    if(keyIsDown(32)){
        coke.push(Coke({}));
    }//space to make bullets moving upward
    waiter.draw();//draw waiter

    coke.forEach(function(Coke){
        Coke.update();
        Coke.draw();
    });

    if(Math.random()<0.05){
        burger.push(Burger({}));
    }
    burger = burger.filter(function(Burger){
        return Burger.active;
    });
    burger.forEach(function(Burger){
        Burger.update();
        Burger.draw();
    });

    coke.forEach(function(Coke){
        burger.forEach(function(Burger){
            if(shooting(Burger, Coke)){
                Burger.active = false;
                Coke.active = false;
                score++;
            }
        });
    });

    burger.forEach(function(Burger){
        if(shooting(Burger, waiter)){
            Burger.active = false;
            noLoop();
            textSize(100);
            fill(0);
            text("TOO FULL", 10, 150);
        }
    });
}

For this assignment, I explored the forEach function for the array of bullets and targets and how they collide each other in order to disappear. I also played with the inserting image files into the js file.

jiheek1 – dnoh – SectionD – Final Project

sketch

//Jihee Kim, Daniel Noh
//15-104 MWF 9:30
//jiheek1@andrew.cmu.edu, dnoh@andrew.cmu.edu
//Final Project
//Section D

var snowmanX = 200;
var easing = 0.1;
var limit; //constrain the snowman and the carrot
var targetX; //target location of snowman and carrot (mouseX)
var dx;
var carrotFrame = 0; //initialize the carrot image
var heartFrame = 0; //initialize the heart image
var carrots = []; //an array of carrot images
var hearts = []; // an array of heart images
var balls = []; //an array of ellipses falling from the top of canvas
var clouds = []; //an array of clouds


var speedCounter = 0;
var carrotCounter = 0;
var scoreCounter = 0;
var carrotStoptime = 0;
var score = 0;

var yVelocity = 1;
var nBalls = 26; //numbrt of snowballs

function preload() {
    //these URLs preload the loading carrot
    var filenamesC = [];
    filenamesC[0] = "https://i.imgur.com/qepItjw.png";
    filenamesC[1] = "https://i.imgur.com/WrRwOgn.png";
    filenamesC[2] = "https://i.imgur.com/IaGv051.png";
    filenamesC[3] = "https://i.imgur.com/788iMwW.png";
    filenamesC[4] = "https://i.imgur.com/L46EZ7S.png";

    //loads the images into the carrots[] array
    for (var i = 0; i < filenamesC.length; i++) {
        carrots[i]= loadImage(filenamesC[i]); //load each frame...
    }

    //loads the images into the hearts[] array
    var filenamesH = [];
    filenamesH[0] = "https://i.imgur.com/awWteaR.png"
    filenamesH[1] = "https://i.imgur.com/vw1d2oU.png"
    filenamesH[2] = "https://i.imgur.com/aBUC5GV.png"
    filenamesH[3] = "https://i.imgur.com/zBHIG8D.png"

    for (var j = 0; j < filenamesH.length; j++) {
        hearts[j]= loadImage(filenamesH[j]); //load each frame...
    }
}

function setup() {
    createCanvas(480,640);
    //create new balls according to locationBalls function
    for (i = 0; i < nBalls; i++) {
        var newBalls = new locationBalls();
        balls.push(newBalls);
    }
}

function draw() {
    //background gradient
    var a = color(160, 232, 229);
    var b = color(238, 252, 251);
    backGradient(0, width, a, b);


    updateCloud();
    removeCloud();
    addCloud();

    updateBalls();
    levelUp();

    //draw carrot nose
    drawCarrot();

    //draw snowman
    drawSnowman();

    //draw score
    drawScore();

    //menu bar on the left side of canvas
    fill(255);
    stroke(130, 232, 229);
    strokeWeight(4);
    rect(20, 75, 70, 350, 35, 35, 35, 35);

    //draw ice
    drawIce();

    //draw carrot icon
    imageMode(CENTER);
    image(carrots[carrotFrame], 55, 350, 80, 80);
    //every fifteen points, a quarter of the carrot icon is filled
    if (score >= 15 & score < 30) {
        carrotFrame = 1;
    }
    if (score >= 30 & score < 45) {
        carrotFrame = 2;
    }
    if (score >= 45 & score < 60) {
        carrotFrame = 3;
    }
    if (score >= 60) {
        carrotFrame = 4;
    }

    //draw heart icons
    image(hearts[heartFrame], 55, 170, 120, 240);

    //draw score
    drawScore();

    //intro popup
    if (speedCounter < 280) {
        fill(255);
        stroke(130, 232, 229);
        strokeWeight(4);
        rect(20, 75, width-40, 350, 35, 35, 35, 35);
        strokeWeight(2);
        fill(130, 232, 229);
        textSize(40);
        text("HOW TO PLAY", width/2, 170);
        noStroke();
        textSize(20);
        text("move the snowman with your mouse", width/2, 250);
        text("and help it dodge the snowballs!", width/2, 280);
        text("you have three lives", width/2, 330);
        text("GOOD LUCK!", width/2, 380);
    }

    //if hit by snowball, lose a heart
    for (i = 0; i < balls.length; i++) {
        if (speedCounter > 300) {
            if ((balls[i].x > (snowmanX - 10)) & (balls[i].x < (snowmanX + 10))
            && (balls[i].y > (height - 150)) && (balls[i].y < (height - 130))) {
                heartFrame += 1;
                balls[i].y = 0;
            }
        }
    }
    //end game
    if (heartFrame >= 3) {
        gameOver();
    }
}

function keyPressed() { //reset game when pressing R
    if (keyCode == 82 & heartFrame == 3) {
        heartFrame = 0;
        carrotFrame = 0;
        snowmanX = 200;
        easing = 0.1;
        speedCounter = 0;
        carrotCounter = 0;
        scoreCounter = 0;
        carrotStoptime = 0;
        score = 0;
        yVelocity = 1;
    }
}

function gameOver() {
    yVelocity = 0;
    snowmanX = width/2;
    easing = 0;
    //game over popup
    fill(255);
    stroke(130, 232, 229);
    strokeWeight(4);
    rect(20, 75, width-40, 350, 35, 35, 35, 35);

    //game over text
    fill(130, 232, 229);
    textSize(50);
    strokeWeight(2);
    text("GAME OVER", width/2, 170);
    textSize(30);
    noStroke();
    strokeWeight(1);
    fill(130, 232, 229);
    text("your score: " + score, width/2, 220);
    textSize(25);
    text("PRESS R TO RESTART", width/2, 350);
    image(carrots[carrotFrame], width/2, 270, 80, 80);
    noLoop;
}

function levelUp() {
    speedCounter += 1;
    if (speedCounter > 600) {
        yVelocity = 2;
    }
    //level 1 speed
    if (speedCounter > 1200) {
        yVelocity = 4;
    }
    //level 2 speed
    if (speedCounter > 1800) {
        yVelocity = 6;
    }
    //level 3 speed
    if (speedCounter > 2400) {
        yVelocity = 8;
    }
    //level 4 speed
    if (speedCounter > 3000) {
        yVelocity = 10;
    }
    //god level speed -- impossible mode.
    if (speedCounter > 3600) {
        yVelocity = 12;
    }
}

function backGradient(y, x, a, b) { //background gradient color
    for (var i = y; i <= height; i++) {
      var mid = map(i, y, y+x, 0, 1);
      var c = lerpColor(a, b, mid);
      stroke(c);
      strokeWeight(2);
      line(y, i, y+x, i);
	}
}

function drawScore() {
    //score keeping system
    scoreCounter += 1;
    if (scoreCounter % 120 == 0 & heartFrame != 3 && speedCounter > 300) {
        score += 1
    }
    fill(130, 232, 229);
    noStroke();
    textAlign(CENTER);
    textSize(25);
    text(score, 55, 290);
}

function drawSnowman() {
    limit = constrain(mouseX, 125, 450); //limits within the canvas
    targetX = limit; //easing the snowman to mouse
    dx = targetX - snowmanX;
    snowmanX += dx * easing;

    fill(255);
    strokeWeight(3);
    stroke(230);
    //body
    ellipse(snowmanX, height-80, 40, 40);
    //head
    ellipse(snowmanX, height-110, 30, 30);
}

function drawCarrot() {
    //limits within the canvas
    limit = constrain(mouseX, 125, 450);
    //easing the carrot to mouse
    targetX = limit;
    dx = targetX - snowmanX;
    snowmanX += dx * easing;

    fill(255, 181, 51);
    strokeWeight(2);
    stroke(255, 110, 51);
    triangle(snowmanX-5, height-125, snowmanX+5, height-125,
             snowmanX, height-145);
}

function drawIce() {
    fill(215, 255, 255);
    strokeWeight(5);
    stroke(175, 250, 250);
    rect(-5, height-55, width+10, 60);
    //the lines on the ice
    for(var i = 0; i < 16; i++) {
        strokeWeight(4);
        line(0 + (i*30), height-55, 20 + (i*30), height-45);
        line(15 + (i*30), height-55, 50 + (i*30), height-35);
    }
}

//updates the clouds so they move and show
function updateCloud() {
    for (var i = 0; i < clouds.length; i++){
      clouds[i].move();
      clouds[i].display();
    }
}

//gets rid of clouds that pass the screen
function removeCloud() {
    var cloudsKeep = [];
    for (var i = 0; i < clouds.length; i++){
      if (clouds[i].x + clouds[i].breadth > 0){
        cloudsKeep.push(clouds[i]);
      }
    }
    clouds = cloudsKeep;
}

//adds clouds at a random interval, replacing the ones that are removed
function addCloud() {
    var newCloudPercent = 0.1;
    if (random(0,1) < newCloudPercent){
        var cloudX = width;
        var cloudY = random(height/1.2);
        clouds.push(makeClouds(width));
    }
}

//adds velocity to the clouds, making them move
function cloudMove() {
    this.x += this.speed;
}

//this is the things that make the cloud
function displayCloud() {
    var cloudHeight = 5;
    var cHeight = this.nCloud*cloudHeight;

    noStroke();
    fill(255, this.opaque);
    push();
    translate(this.x, height/1.15);
    ellipse(0, -cHeight, this.breadth, cHeight/1.5);
    pop();
    push();
    translate(this.x, height/1.15+40);
    ellipse(30, -cHeight, this.breadth, cHeight);
    pop();
}

//these are the parameters for the clouds
function makeClouds(cloudX, cloudY) {
    var cloud = {x: cloudX,
				y: cloudY,
				breadth: random(50, 100),
				speed: -random(1, 3),
				nCloud: round(random(10,23)),
				opaque: random(80, 90),
				move: cloudMove,
				display: displayCloud}
    return cloud;
}

//updates the balls so they move and show
function updateBalls() {
    for (var i = 0; i < balls.length; i++) {
        balls[i].draw();
        balls[i].move();
    }
}

//sets up the movement and display of balls
function locationBalls() {
    this.x = random(125, width);
    this.y = random(0, height);

    this.draw = function() {
        fill(0);
        if (this.y < height + 5) {
            stroke(222, 236, 249);
            strokeWeight(2);
            fill(255);
            ellipse(this.x, this.y, 20, 20);
        } else {
            this.x = random(125, width);
            this.y = -5;
        }
    }

    this.move = function() {
        this.y += yVelocity;
    }
}

For this project, we created a vertical dodging game, inspired by the holiday season. The plot of the game is a snowman who does not want to die and tries to avoid the snow which will gradually kill it.

The player can move the snowman with their mouse to dodge the falling snowballs. As time passes, the snow’s falling speed and the score increases. A carrot icon on the left of the canvas also fills up every 15 points, as well. Whenever the snowballs hit the snowman, the snowman loses a life, which is represented by the three heart icons on the left. Clouds are also in the background to provide a more interesting scenery. At the end of the game, the player is shown their score through points and the carrot icon, and instructed how to restart the game. Below is a zip file and some screenshots of the game. ENJOY and HAPPY HOLIDAYS!

jiheek1_dnoh_finalproject

intro
playing
game over

atraylor – Final Project

For my final project I made a boredom simulator. Please, enjoy the fun that awaits you in this blandly furnished room with plenty of fun and exciting activities to entertain yourself with. If you become bored, that’s okay! Just click again and find another riveting thing to do to take your mind off the boredom! Along with engaging visuals, treat your weary mind with the wondrous sounds that accompany the many fascinating capabilities of this program. You won’t be disappointed…

atraylor final project

To open this project, I suggest using a local server because it contains several sound files.

To use the simulator, click on an object to entertain yourself, once you are done, click “i’m bored” to return to the room.

ablackbu-Final Project

For my final project I made a game called Meteor Flyer. You can play a version below but some effects are missing. For the best performance, download the game in the “PLAY” link below.

To play, the user:

  1. Navigates a UFO with their mouse through a meteor field.
  2. When the mouse is close to the meteors, they grow.
  3. UFO can shoot a meteor and break it by the user clicking the mouse.
  4. If the UFO makes it to the bottom of the canvas, the player wins
  5. if the UFO hits a meteor, the player loses.
  6. the colors can be changed with the “ENTER” key.
  7. The instructions can be shown by holding down the “SHIFT” key.

Please download the file and use the local file to access the html file to play!!

***********

PLAY ******

***********

 

Here are some snapshots of a winning game and a losing game.

Winning Game:

____________________________________________

Losing Game:

 

Like I said before, this version on WordPress is scaled and some effects don’t work. For the best performance, download the game in the “PLAY” link above.

sketch

var bubbles = [];
var colCount = 0;
var loseF = false;
var rocketX = 300;
var rocketY = 80;
var ropeX = 300;
var ropeY = 80;
var len = 150; //length of array
var on = false;
var gettime;

//pop sound
var sound1;

//background colors
var a = ("#292b29");
var b = ("#fbf49c");
var c = ("#f69b9c");
var d = ("#a3bfe4");
var e = ("#a9dbcf");
var f = ("#9a97ca");
var back = [a, b, c, d, e, f];

//bubble colors
var ba = ("#a5a5a5");
var bb = ("#918c60");
var bc = ("#7a3f42");
var bd = ("#4f5863");
var be = ("#67827b");
var bf = ("#474769");
var bub = [ba, bb, bc, bd, be, bf];

//text colors
var ta = ("#292b29");
var tb = ("#a5a5a5");
var tex = [ta, tb]


function preload() {
    // load sound and image files
    //sound1 = loadSound('sounds/pop.wav');
    mouse1 = loadImage("https://i.imgur.com/vWALILY.png")
}

function setup() {
    createCanvas(600, 600);
    textFont("Courier")
    //set up bubbles object
    for (var i = 0; i < len; i++){
        bubbles[i] = {
            
            x:random(0, width) , 
            y:random(80, height) , 
            diam:random(10, 55) , 
            pointx : 0,
            pointy : 0,
            //make the bubbles
            display : function(){
                stroke(back[colCount]);
                fill(bub[colCount]);
                ellipse(this.x, this.y, this.diam);
            }
        }
    }
}

function draw() {
    background(back[colCount]);
    if(frameCount > 400){
            on = true
    }
    
    for (var i = 0; i < len; i++){
        //display bubbles
        bubbles[i].display();
        //move bubbles to make them shake
        
        if(on == true){
            bubbles[i].x += random(-1,1);
            bubbles[i].y += random(-1,1);
        }
        if(on == false){
            bubbles[i].x += 0
            bubbles[i].y += 0
        }  

        strokeWeight(.5);
        stroke(bub[colCount]);
        //create a line from the mouse to the bubbles if they are 100 pix away
        if(dist(bubbles[i].x, bubbles[i].y, mouseX,mouseY) < 100){
            line(bubbles[i].x, bubbles[i].y, mouseX,mouseY);
            
            //increase bubbles size if the line connects them
            //stop increasing at 150 pix
            if(frameCount > 400){
                if (bubbles[i].diam <= 150){
                    bubbles[i].diam += .3;
                }
            }   
        }
        //test if the rocket is touching a bubble
        var roc = dist(mouseX, mouseY-50, bubbles[i].x, bubbles[i].y);
        if(frameCount > 400){
            if(roc <= 15 + bubbles[i].diam/2){
                loseF = true      
            }
        }

        //if shift is held down, pause the game
        if (keyIsDown(SHIFT)){
            on = false
        }
    }
    
    //if shift is held down the instructions pop up
    if (keyIsDown(SHIFT)){
        on = false
        instructions();
    }

    //put instructions up for a few seconds when page reloads
    if(frameCount > 30 & frameCount < 400){
        //show where to put mouse flashing
        if(frameCount % 10){
            fill("green");
            strokeWeight(0);
            ellipse(ropeX, ropeY, 40, 40, 20)
            //mouse image
            push();
            scale(.08);
            image(mouse1, ropeX * 12.3, ropeY * 12);
            pop();
        }
        instructions();
    }

    //make rocket
    rocket();
    
    //winning message if rocket makes it accross
    if(rocketY >= height + 35){
        end();
    }
    
    //losing message if rocket hits a bubble
    if(loseF == true){
        noLoop();
        lose();
    }

    //countdown
    if(frameCount < 400){
        ticker();
    }

    if(mouseIsPressed){
        var gettime = frameCount
    }
    
    //make beam lasers when pressing on a bubble
    if(frameCount >= gettime & frameCount < gettime + 3){
        strokeWeight(3)
        stroke("red");
        line(ropeX - 5, ropeY, rocketX - 5, rocketY - 50); 
        line(ropeX + 5, ropeY, rocketX + 5, rocketY - 50); 
    }
}

function mousePressed(){   
    for (var i = 0; i < len; i++){
        var g = dist(mouseX, mouseY, bubbles[i].x, bubbles[i].y);
        //if you click on an bubble it pops
        if(g <= bubbles[i].diam/2){
            bubbles[i] = bubbles[len - 1];
            len -= 1;

            //pop sound plays
            //sound1.play();
        }
    }
}

function keyPressed(){
    //if the enter key is pressed, the color of the porgram changes
    //so that the colors cycle through from the array
    if (keyCode == ENTER)  {
        colCount ++;
        if(colCount == 6){
            colCount = 0;
        }
    }
}

function instructions(){
    rectMode(CENTER);
    textAlign(CENTER);
    
    //instrucitons text
    fill(255);
    rect(width/2, height/2 + 5, 420, 150, 20);
    fill(tex[5*frameCount%2]);
    
    textSize(10);
    text("Place Mouse Here --->", ropeX - 90, ropeY + 6);

    textSize(18);
    text("LEAD THE UFO THROUGH THE METEORS", width/2, height/2 - 30);
    text("REACH THE BOTTOM WITHOUT CRASHING", width/2, height/2 - 10);
    
    fill("#292b29");
    textSize(14);
    text("Click to destroy meteors", width/2, height/2 + 20);
    
    textSize(10);
    text("Press 'ENTER' to change colors", width/2-100, height/2 + 55);
    fill("#a3bfe4")
    textSize(10);
    text("Hold 'SHIFT' to pause", width/2+100, height/2 + 55);  
}

//make UFO
function rocket(){
    if(frameCount > 400){
        rocketX = mouseX
        rocketY = mouseY
        ropeX = mouseX
        ropeY = mouseY
    }
    strokeWeight(.5)
    stroke("black");
    line(ropeX, ropeY, rocketX, rocketY-50); 
    stroke(255);
    fill(200);
    ellipse(rocketX, rocketY-50, 30, 30);
    fill(180);
    ellipse(rocketX, rocketY-50, 15, 15);
}

//winning message
function end(){
    background("green");
    noLoop()
    fill("white");
    textSize(20);
    text("YOU WON!", width/2, height/2);
}

//losing message
function lose(){
    background("red");
    textSize(20);
    fill("white");
    text("YOU lOSE!", width/2, height/2);
    textSize(15);
    text("ctrl + R to restart game", width/2, height/2 + 25);
}

//countdown to the start
function ticker(){ 
    fill(255);
    textSize(40)
    text(floor(6 - (frameCount / 80)), 300, 150);
}

yuchienc-haewanp-Final

Overview

Hae Wan and my project in it’s original state cannot be displayed on wordpress because it uses the p5.gui library that isn’t included. We’ve made a modified version with p5 sliders that doesn’t include the full capabilities. Please scroll down to see that, but we would like the attached file to be what is graded. As per instruction of TA’s, we’ve included screenshots of how it works as well as a link to the video. Please download the packaged file below:

yuchienc-sectionC-haewanp-secionA-final

and run the index.html file. There’s no need to setup any servers; the p5.gui library is included. Simply type in any message you want in the “message” box and play around with the parameters to customize your text!

Here is a video of how it works:

https://vimeo.com/246549917

Running the index.html file in a browser with the gui created by p5.js library

Showing how text can be resized

Showing different color palettes

Type of letter randomly changes when parameters are adjusted

Size of type can be resized

The vertical height of the canvas adapts to amount of text and can be used to create a pattern.

Demo

To interact with this demo, please type a few letters (don’t use spaces or backspace or punctuation) and play with the sliders!

sketch

var aSlider;
var bSlider;
var unit;
var padding;
var message = [];
var fontA = {'A': a_a, 'B': a_b, 'C': a_c, 'D': a_d, 'E': a_e, 'F': a_f,
 			 'G': a_g, 'H': a_h, 'I': a_I, 'J': a_j, 'K': a_k, 'L': a_l, 
 			 'M': a_m, 'N': a_n, 'O': a_o, 'P': a_p, 'Q': a_q, 'R': a_r,
 			 'S': a_s, 'T': a_t, 'U': a_u, 'V': a_v, 'W': a_w, 'X': a_x,
 			 'Y': a_y, 'Z': a_z
 			}; //storing all functions of the haewan's font into an object];

function setup() {
    createCanvas(480, 480);
    noStroke();
    aSlider = createSlider(0, 100, 50);
    aSlider.position(330, 405);
    bSlider = createSlider(0, 100, 0);
    bSlider.position(330, 455);
}

function draw() {
    background(250);
    
    fill('#ef4131');
    text('SIZE', 325, 390);
    text('PADDING', 325, 440);
    
    unit = aSlider.value();
    padding = bSlider.value();
    for (i = 0; i < message.length; i++) {
        var cur = message[i];
        typeletter(cur, i);
    }
}

function typeletter(ltr, i) {
    fontA[ltr](unit * i + padding*i, 0);        
};


function keyPressed() {
    message.push(key);
    print(key);
}

////////////////////////////////////////////////////
/////////////////////TYPEFACE///////////////////////
////////////////////////////////////////////////////


function a_a(x, y) {
    trngl(x + unit / 2, y, unit, 3)
    trngl(x + unit / 2, y, unit, 4);
    crcl(x + unit / 2, y + 2 * unit / 3, unit / 3);
}

function a_b(x, y) {
    hlf_crcl(x, y + 3 * unit / 10, 3 * unit / 5, -HALF_PI);
    hlf_crcl(x, y + 7 * unit / 10, 3 * unit / 5, -HALF_PI);
    rctngl(x + unit / 6, y, unit, 'v');
}

function a_c(x, y) {
    hlf_crcl(x, y + unit / 2, unit, HALF_PI);
    crcl(x + unit / 2, y + unit / 2, unit / 3);
}

function a_d(x, y) {
    rctngl(x, y, unit, 'v');
    hlf_crcl(x - unit / 6, y + unit / 2, unit, -HALF_PI);
}

function a_e(x, y) {
    rctngl(x + unit * 0.15, y, unit, 'v');
    crcl(x + unit * 0.7, y + unit * 0.15, unit * 0.3);
    crcl(x + unit * 0.7, y + unit * 0.5, unit * 0.3);
    crcl(x + unit * 0.7, y + unit * 0.85, unit * 0.3);
}

function a_f(x, y) {
    rctngl(x + unit * 0.15, y, unit, 'v');
    crcl(x + unit * 0.7, y + unit * 0.15, unit * 0.3);
    crcl(x + unit * 0.7, y + unit * 0.5, unit * 0.3);
}

function a_g(x, y) {
    hlf_crcl(x, y + unit / 2, unit, 0);
    hlf_crcl(x, y + unit / 2, unit, HALF_PI + QUARTER_PI);
}

function a_h(x, y) {
    rctngl(x, y, unit, 'v');
    crcl(x + unit * 0.5, y + unit * 0.5, unit * 0.3);
    rctngl(x + 2 * unit / 3, y, unit, 'v');
}

function a_I(x, y) {
    rctngl(x + unit / 3, y, unit, 'v');
}

function a_j(x, y) {
    rctngl(x + unit / 2, y, 2 * unit / 3, 'v');
    hlf_crcl(x, y + 2 * unit / 3, 2 * unit / 3, 0);
}

function a_k(x, y) {
    trngl(x + unit / 3, y, unit, 2);
    trngl(x + unit / 3, y, unit, 4);
    rctngl(x, y, unit, 'v');
}

function a_l(x, y) {
    rctngl(x, y, unit, 'v');
    crcl(x + unit * 0.55, y + unit * 0.85, unit * 0.3);
}

function a_m(x, y) {
    trngl(x, y, unit, 4);
    trngl(x + unit / 2, y, unit, 4);
}

function a_n(x, y) {
    trngl(x, y, unit, 4);
    rctngl(x + unit / 2, y, unit, 'v');
}

function a_o(x, y) {
    crcl(x + unit / 2, y + unit / 2, unit);
}

function a_p(x, y) {
    hlf_crcl(x - unit / 6, y + 3 * unit / 10, 3 * unit / 5, -HALF_PI);
    rctngl(x, y, unit, 'v');
}

function a_q(x, y) {
    crcl(x + unit / 2, y + unit / 2, unit);
    trngl(x + unit / 2, y + unit / 2, unit / 2, 4);
}

function a_r(x, y) {
    trngl(x + unit / 3, y + unit / 2, unit / 2, 4);
    hlf_crcl(x - unit / 6, y + 3 * unit / 10, 3 * unit / 5, -HALF_PI);
    rctngl(x, y, unit, 'v');
}

function a_s(x, y) {
    hlf_crcl(x + unit * 0.11, y + unit * 0.4, 3 * unit / 4, HALF_PI + QUARTER_PI);
    hlf_crcl(x - unit * 0.11, y + unit * 0.6, 3 * unit / 4, TWO_PI - QUARTER_PI);
}

function a_t(x, y) {
    rctngl(x + unit / 3, y, unit, 'v');
    crcl(x + unit * 0.15, y + unit * 0.15, unit * 0.3);
    crcl(x + unit * 0.85, y + unit * 0.15, unit * 0.3);
}

function a_u(x, y) {
    rctngl(x, y, unit / 2, 'v');
    rctngl(x + 2 * unit / 3, y, unit / 2, 'v');
    hlf_crcl(x, y + unit / 2, unit, 0);
}

function a_v(x, y) {
    trngl(x + unit / 2, y, unit, 1)
    trngl(x + unit / 2, y, unit, 2);
    crcl(x + unit / 2, y + unit / 3, unit / 3);
}

function a_w(x, y) {
    trngl(x, y, unit, 2);
    trngl(x + unit / 2, y, unit, 2);
}

function a_x(x, y) {
    trngl(x + unit / 2, y, unit, 1);
    trngl(x + unit / 2, y, unit, 2);
    trngl(x + unit / 2, y, unit, 3);
    trngl(x + unit / 2, y, unit, 4);
}

function a_y(x, y) {
    rctngl(x + unit / 3, y + unit / 3, 2 * unit / 3, 'v');
    hlf_crcl(x, y, unit, 0);
}

function a_z(x, y) {
    push();
    translate(x + unit / 2, y + unit / 2);
    rotate(HALF_PI);
    trngl(unit/6, - unit / 2, unit, 1);
    pop();
    rctngl(x, y, unit, 'h');
    rctngl(x, y + 2 * unit / 3, unit, 'h');
}

/////////SHAPES TO DRAW///////////
 
function trngl(x, y, h, d) {
    fill(239, 65, 49);
    beginShape();
    vertex(x, y);
    vertex(x, y + h);
    if (d % 2 == 0) {
        vertex(x + h / 2, y + h * (2 % d) / 2);   
    } else {
        vertex(x - h / 2, y + h * (2 % d) / 2);
    }
    endShape();    
}

function crcl(x, y, r) {
    fill(255, 230, 0);
    ellipse(x, y, r, r);
}

function rctngl(x, y, h, d) {
    fill(46, 49, 150);
    if (d == 'v') {
        rect(x, y, unit / 3, h);
    } else {
        rect(x, y, h, unit / 3);
    }

}

function hlf_crcl(x, y, r, d) {
    fill(236, 0, 140);
    arc(x + unit / 2, y, r, r, d, d + PI);   
    
}

Reflection

We split up the work by each of us designing our own typeface (denoted in comments). Rules and patterns are common in design of typefaces– you’ll notice that there is symmetry between lowercase “d”s, “p”s, “b”s and “q”s, so it was fun applying that idea of repetition to something computational. Bettina focused on writing the code for the GUI and how to compute the spacing for moving letters to new lines, have the canvas height grow with the type, etc. (the draw() and typeletter() functions, the fontB{} functions) And then Haewan focused on the fontA{} functions, and the revised version with p5 sliders so that something can be displayed on WordPress.

NatalieKS-Final-Project

While this project was stressful, it was really fun to be able to put something together using things I had learned this semester. One of my goals was to be able to create a small, fun game, and I’m proud to say that I have accomplished that goal. I wanted to create something clean, almost child-like in terms of visuals, and I wanted to employ a variety of instruments for the various sounds. One thing I wish I knew how to do was adjust the volume of each sound; some of them are louder than others, and I would’ve liked them all to be the same volume. Even so, it was cool to be able to create something a bit more advanced (as opposed to a still image) and to create an actual game from scratch. I hope you have as much fun playing the game and discovering the different sounds as I had putting them all together!

~

My project is a sound-based game, so please make sure your sound is on!

How to Play:

Press any key to begin, and continue pressing keys (the ones with letters on them) to play the game. You have 15 seconds to create a musical composition, and then judges will judge you. Have fun!

nksFinal

//Natalie Schmidt
//nkschmid@andrew.cmu.edu
//Section D
//Final Project

//indicate when the game starts
var startGame;
//keep track of how many seconds have passed since
//the game started
var secondsPassed;
//keep track of how many times the key is pressed
var count = 0;
//indicate whether the game has started or not
var isGamePlayed = false;
//indicate whether to display the end message
var isEndMessage = false;
//use for probability of the faces
var r;
//x position of the faces
var x;
//y position of the faces
var y;
//position of the note
var noteX;
//x position of the notes
var noteXPos = [];
//y position of the notes
var noteYPos = [];

//I tried to avoid having too many
//characters on one line,
//but I didn't want to break the link into
//two separate lines
function preload() {
    boomcrash = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/boomcrash.wav");
    snare = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/snare.wav");
    acousticKick = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/acousticKick.wav");
    drumstick = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/drumstick.wav");
    rattleDrum2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/rattleDrum2.wav");
    smallHighHat = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/small-highhat.wav");
    smallCymbal = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/smallCymbal.wav");
    deepCymbal = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/deepCymbal.wav");
    highStrings = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/highStrings.wav");
    lowStrings = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/lowString2.wav");
    synth1 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/synth1.wav");
    synth2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/synth2.wav");
    synth3 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/synth3.wav");
    bassStrings = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/bassStrings.wav");
    highStrings2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/highStrings2.wav");
    pianoDo = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoDo.wav");
    pianoRe = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoRe.wav");
    pianoMi = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoMi.wav");
    pianoFa = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoFa.wav");
    pianoSo = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoSo.wav");
    pianoLa = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoLa.wav");
    pianoTi = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoTi.wav");
    pianoOctave = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pianoHighDo.wav");
    frenchhorn1 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/frenchhorn1.wav");
    frenchhorn2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/frenchhorn2.wav");
    frenchhorn3 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/frenchhorn3.wav");
}

function setup() {
    createCanvas(480, 480);
    startGame = second();
    r = floor(random(1, 10));
    frameRate(10);
//set the starting position of the note
    noteX = 640;
}

function draw() {
    background(236, 101, 114);
    scale(0.75, 0.75);
    noStroke();
//leftmost judge
    judge1();
//center judge
    judge2();
//rightmost judge
    judge3();
//display the staff and moving notes
    musicNotes();
//if the game has started, keep track of how
//many seconds have passed!
    if (isGamePlayed == true) {
    //Time when the game ends
        e = new Date();
        print(e.getTime());
        secondsPassed = e/1000 - d/1000;
    //display the seconds passed as a timer
        textSize(50);
        text(nf(secondsPassed, 2, 1), 260, 50);
    }
//if 15 seconds have passed since the game started,
//display end message
    if (secondsPassed >= 15.0) {
        isGamePlayed = false;
        isEndMessage = true;
        endMessage();
    }
//draw the notes
    for(var i = 0; i < noteXPos.length; i++) {
        noFill();
        stroke(0);
        strokeWeight(4);
        if (isGamePlayed == true) {
            ellipse(noteXPos[i], noteYPos[i], 15, 10);
        //make them move across the screen
            noteXPos[i] -= 8;
        }
    }
//if the game hasn't started, display the start message
    if (isGamePlayed == false & isEndMessage == false) {
        startMessage();
    }
}

//message before the game starts
function startMessage() {
    noStroke();
    fill(236, 198, 21);
    rect(65, 30, 500, 170, 20);
    fill(255);
    rect(75, 30, 500, 160, 20);
    textSize(30);
    fill(236, 198, 21);
    text("Welcome!", 240, 60);
    fill(0);
    textSize(15);
    text("Here's how to play:", 245, 85);
    text("Each key corresponds to a different sound." + " "
        + "Once you press the first key,", 85, 105);
    text("the timer will start." + " "
        + "You have 15 seconds to create your own", 125, 125);
    text("musical masterpiece. When you're done," + " "
        + "the three judges will judge you!", 85, 145);
    textSize(25);
    fill(236, 198, 21);
    text("Have fun, and good luck!", 185, 175);
}

//message when the game is over
function endMessage() {
    noStroke();
    fill(236, 198, 21);
    rect(65, 30, 500, 160, 20);
    fill(255);
    rect(75, 30, 500, 150, 20);
    fill(0);
    textSize(40);
    fill(236, 198, 21);
    text("The End!", 225, 75);
    textSize(20);
    fill(0);
    text("Look at the judges to see" + " "
        + "how you did!", 150, 110);
    text("Thanks for playing!", 230, 135);
    textSize(15);
    text("Refresh the page if you'd" + " "
        + "like to play again!", 170, 165);
}

//create the leftmost judge: the happy judge
function judge1() {
    x = 80;
    y = 355;
//light gray shadow
    fill(220);
    ellipse(90, 575, 100, 350);
//white body
    fill(255);
    ellipse(100, 575, 100, 350);
//head shadow
    fill(220);
    ellipse(90, 370, 125, 125);
//white head
    fill(255);
    ellipse(100, 370, 125, 125);

//determine expressions
    if (isGamePlayed == true) {
        thinkingFace();
    }
    if (secondsPassed >= 15.0) {
        if (r <= 6) {
            happyFace();
        }
        else if (r >= 7 & r <= 9) {
            surprisedFace();
        }
        else {
            mehFace();
        }
    }
}

//create the center judge: the equal judge
function judge2() {
    x = 280;
    y = 355;
    noStroke();
//light gray shadow
    fill(220);
    ellipse(290, 575, 100, 350);
//white body
    fill(255);
    ellipse(300, 575, 100, 350);
//head shadow
    fill(220);
    ellipse(290, 370, 125, 125);
//white head
    fill(255);
    ellipse(300, 370, 125, 125);

//determine expressions
    if (isGamePlayed == true) {
        thinkingFace();
    }
    if (secondsPassed >= 15) {
        if (r <= 4) {
            happyFace();
        }
        else if (r >= 5 & r <= 7) {
           surprisedFace();
        }
        else {
            mehFace();
        }
    }
}

//create the rightmost judge:
//the hard to impress judge
function judge3() {
    x = 480;
    y = 355;
    noStroke();
//light gray shadow for body
    fill(220);
    ellipse(490, 575, 100, 350);
//white body
    fill(255);
    ellipse(500, 575, 100, 350);
//light gray shadow for head
    fill(220);
    ellipse(490, 370, 125, 125);
//white head
    fill(255);
    ellipse(500, 370, 125, 125);

//determine expressions for game
    if (isGamePlayed == true) {
        thinkingFace();
    }
    if (secondsPassed >= 15) {
        if (r <= 4) {
            surprisedFace();
        }
        else {
            mehFace();
        }
    }
}

//create surprised expression
function surprisedFace() {
    stroke(0);
    strokeWeight(1);
//eyelashes left eye
    stroke(1);
    line(x - 1, y - 15, x - 1, y - 25);
    line(x - 5, y - 15, x - 7, y - 25);
    line(x + 3, y - 15, x + 5, y - 25);
//eyelashes right eye
    line(x + 39, y - 15, x + 39, y - 25);
    line(x + 35, y - 15, x + 33, y - 25);
    line(x + 43, y - 15, x + 45, y - 25);
//eyes
    fill(255);
    ellipse(x, y, 25, 30);
    ellipse(x + 40, y, 25, 30);
//pupils
    fill(0);
    ellipse(x, y, 15, 15);
    ellipse(x + 40, y, 15, 15);
//mouth
    ellipse(x + 20, y + 45, 20, 30);

//display message
    noStroke();
    fill(236, 198, 21);
    rect(x + 40, y - 145, 90, 85, 20);
    triangle(x + 43, y - 70, x + 70, y - 60,
        x + 33, y - 55);
    fill(255);
    rect(x + 50, y - 145, 90, 80, 20);
    triangle(x + 53, y - 75, x + 80, y - 65,
        x + 43, y - 60);
    fill(0);
    textSize(30);
    text("Wow!", x + 60, y - 95);
}

//create unimpressed "meh" expression
function mehFace() {
    fill(0);
    noStroke();
//pupils
    ellipse(x + 5, y, 15, 15);
    ellipse(x + 45, y, 15, 15);
//eyelids (the curves)
    noFill();
    stroke(0);
    strokeWeight(1);
    arc(x + 1, y - 1, 20, 20, PI, 0);
    arc(x + 41, y - 1, 20, 20, PI, 0);
//mouth
    line(x + 10, y + 35, x + 40, y + 35);
    arc(x, y + 35, 20, 20, 3*PI/2, HALF_PI);

//display message
    noStroke();
    fill(236, 198, 21);
    rect(x + 40, y - 145, 90, 85, 20);
    triangle(x + 43, y - 70, x + 70, y - 60,
        x + 33, y - 55);
    fill(255);
    rect(x + 50, y - 145, 90, 80, 20);
    triangle(x + 53, y - 75, x + 80, y - 65,
        x + 43, y - 60);
    fill(0);
    textSize(30);
    text("meh", x + 64, y - 95);
}

//create happy expression
function happyFace() {
//eyes
    stroke(0);
    strokeWeight(1);
//eyelashes left eye
    line(x - 1, y - 10, x - 1, y - 20);
    line(x - 5, y - 10, x - 7, y - 20);
    line(x + 3, y - 10, x + 5, y - 20);
//eyelashes right eye
    line(x + 39, y - 10, x + 39, y - 20);
    line(x + 35, y - 10, x + 33, y - 20);
    line(x + 43, y - 10, x + 45, y - 20);
//eyes
    arc(x, y, 25, 25, PI, 0);
    arc(x + 40, y, 25, 25, PI, 0);
//mouth
    arc(x + 20, y + 30, 50, 50, 0, PI);
//blush marks left
    stroke(236, 101, 114, 100);
    line(x - 35, y + 17, x - 25, y + 12);
    line(x - 25, y + 17, x - 15, y + 12);
    line(x - 15, y + 17, x - 5, y + 12);
//blush marks right
    line(x + 40, y + 17, x + 50, y + 12);
    line(x + 50, y + 17, x + 60, y + 12);
    line(x + 60, y + 17, x + 70, y + 12);

//display message
    noStroke();
    fill(236, 198, 21);
    rect(x + 40, y - 145, 90, 85, 20);
    triangle(x + 43, y - 70, x + 70, y - 60,
        x + 33, y - 55);
    fill(255);
    rect(x + 50, y - 145, 90, 80, 20);
    triangle(x + 53, y - 75, x + 80, y - 65,
        x + 43, y - 60);
    fill(0);
    textSize(28);
    text("Pretty!", x + 55, y - 95);
}

//create thinking face displayed
//during the game
function thinkingFace() {
    stroke(0);
    strokeWeight(1);
    fill(255);
//left eyelid
    arc(x, y + 10, 25, 25, PI, 0);
//right eyelid
    arc(x + 40, y + 10, 25, 25, PI, 0);
//mouth
    fill(255);
    arc(x +5, y + 35, 15, 15, 3*PI/2, HALF_PI);
    arc(x + 22, y + 28, 25, 25, PI/4, 3*PI/4);
}

function musicNotes() {
//music staff (lines)
    for (var i = 3; i < 8; i++) {
        stroke(0, 0, 0, 80);
        strokeWeight(3);
        line(0, i*20, 640, i*20);
//push the y position into the array
        noteYPos.push(i*20);
    }
}

function keyPressed() {
//keep track of how many times
//the keys are pressed
    count++;
//if a key is pressed, start the game
    if (count == 1) {
        isGamePlayed = true;
     // startGame = second();
     //Time when the key was pressed
        d = new Date();
    }
//push the current x position into the noteX array
    noteXPos.push(640);

//assign sounds to each letter
//and only play them if the game is being played
    if(isGamePlayed == true) {
        //letter a
        if (keyCode == 65) {
            boomcrash.play();
        }
        //letter s
        if (keyCode == 83) {
            snare.play();
        }
        //letter d
        if (keyCode == 68) {
            acousticKick.play();
        }
        //letter e
        if (keyCode == 69) {
            drumstick.play();
        }
        //letter w
        if (keyCode == 87) {
            rattleDrum2.play();
        }
        //letter x
        if (keyCode == 88) {
            smallHighHat.play();
        }
        //letter z
        if (keyCode == 90) {
            smallCymbal.play();
        }
        //letter q
        if (keyCode == 81) {
            deepCymbal.play();
        }
        //letter j
        if (keyCode == 74) {
            synth1.play();
        }
        //letter k
        if (keyCode == 75) {
            synth2.play();
        }
        //letter l
        if (keyCode == 76) {
            synth3.play();
        }
        //letter r
        if (keyCode == 82) {
            bassStrings.play();
        }
        //letter t
        if (keyCode == 84) {
            lowStrings.play();
        }
        //letter y
        if (keyCode == 89) {
            highStrings.play();
        }
        //letter u
        if (keyCode == 85) {
            highStrings2.play();
        }
        //letter f
        if (keyCode == 70) {
            pianoDo.play();
        }
        //letter g
        if (keyCode == 71) {
            pianoRe.play();
        }
        //letter h
        if (keyCode == 72) {
            pianoMi.play();
        }
        //letter c
        if (keyCode == 67) {
            pianoFa.play();
        }
        //letter v
        if (keyCode == 86) {
            pianoSo.play();
        }
        //letter b
        if (keyCode == 66) {
            pianoLa.play();
        }
        //letter n
        if (keyCode == 78) {
            pianoTi.play();
        }
        //letter m
        if (keyCode == 77) {
            pianoOctave.play();
        }
        //letter i
        if (keyCode == 73) {
            frenchhorn1.play();
        }
        //letter o
        if (keyCode == 79) {
            frenchhorn2.play();
        }
        //letter p
        if (keyCode == 80) {
            frenchhorn3.play();
        }
    }
}

jamieh-final-project

*Move mouse around canvas to move particles

*Click and/or drag to add more particles

sketch

/*
Jamie Ho
jamieh@andrew.cmu.edu
10:30
Project 12
*/

var particles = [];		//array to store circle particles
var d;					//distance between two particles
var md;					//distance between particle and 
var r = 255;
var g = 255;
var b = 255;

function setup(){
	createCanvas(480, 480);
}

function draw(){
	background(0);
	//create particles and push into array
	p = new Particle();
	particles.push(p);
	//if mouse is pressed, then add more particles & invert background colour
	if(mouseIsPressed){
		particles.push(p);
		background(255);
	}
	//first for loop counting backwards of the array
	for(var i = particles.length-1; i > 0; i--){		
		particles[i].show();
		particles[i].update();
		//second for loop counting forwards of the array. two for loops needed to draw lines between all particles
		for(var j = 0; j < particles.length; j++){		
			//distance between two particles
			d = dist(particles[i].x, particles[i].y, particles[j].x, particles[j].y);
			//distance between particle and mouse
			md = dist(particles[i].x, particles[i].y, mouseX, mouseY);
			//if distance between two particles is less than 45 then lines will be blue and thicker
			if(d < 45){
				if(d < 25){
					stroke(102, 204, 255);
					strokeWeight(0.35);
				} else if(d < 45 & d > 25){
					//if mouse is pressed, inverse colours
					if(mouseIsPressed){
						stroke(0);
						strokeWeight(0.1);
					} else{
						stroke(255);
						strokeWeight(0.1);
					}
				}
				line(particles[i].x, particles[i].y, particles[j].x, particles[j].y);
			}
			//if the distance between particle and mouse is between range to determine whether or not to push particles away
			if(md < 50 & mouseIsPressed == false){
				if(particles[i].x > mouseX){
					particles[i].x += random(md/4, md/2);
				} else if(particles[i].x < mouseX){
					particles[i].x -= random(md/4, md/2);
				} else if(particles[i].y > mouseY){
					particles[i].y += random(md/4, md/2);
				} else if(particles[i].y < mouseY){
					particles[i].y -= random(md/4, md/2);
				}
			}
			//if the alpha is less than 0 and returns true
			//then that particle is "killed off" or removed from array
			if(particles[i].finished()){
				particles.splice(i, 1);
			}
		}
	}
}

class Particle{
	//defines locations of particles and velocities and alphas
	constructor(){
		//if mouse is pressed then particle shows up where mouse is clicked
		if(mouseIsPressed){
			this.x = mouseX;
			this.y = mouseY;
		} else {
		//otherwise anywhere on canvas
			this.x = random(width);
			this.y = random(height);
		}
		//size of particles
		this.cSize = random(2, 8);
		//velocities
		this.vx = random(-0.5, 0.5);
		this.vy = random(-0.5, 0.5);
		//brightness of circles
		this.alpha = 255;
	}
	//creates the particles
	show(){
		noStroke();
		if(mouseIsPressed){
			fill(r, g, b, this.alpha);
		} else {
			fill(255, this.alpha);
		}
		ellipse(this.x, this.y, this.cSize);
	}
	//to move the particles
	update(){
		//make particles move
		this.x += this.vx;
		this.y += this.vy;
		//conditions where if particles hit the four edges, bounce
		if(this.x > width-this.cSize/2){
			this.vx -= random(0.5, 1.5);
		} else if(this.x < 0+this.cSize/2){
			this.vx += random(0.5, 1.5);
		} else if(this.y > height-this.cSize/2){
			this.vy -= random(0.5, 1.5);
		} else if(this.y < 0+this.cSize/2){
			this.vy += random(0.5, 1.5);
		}
		//to decrease the brightness of particles
		this.alpha -= 1.25;
	}
	//to "kill off" particles
	finished(){
		return this.alpha < 0; 	//either true or false
	}
}

function mouseDragged(){
	if(particles.push(p) & mouseIsPressed){
		r = map(mouseY, 0, height, 100, 255);
		g -= random(2, 3);	
		b = map(mouseX, 0, width, 150, 255);
	}
}

For my final project, I wanted to work with objects again to become more familiar with it. I chose to use particles and linking those particles based on different conditions. The particles are also interactive so that they’re not just floating circles that move by itself randomly. And while the mouse is clicked, the colours invert to show something more geometrical based on the lines drawn between particles.

svitoora – Evolution

For best viewing experience, please open in full screen here, and let it run for a while in the background. Check on your simulation occasionally to see how they’re evolving.

You can click to add producers, but this is highly unrecommended as it will alter the carrying capacity of the system. I recommend simply letting the software simulation run in the background.

Evolution

// 
// Supawat Vitoorapakorn
// Svitoora@andrew.cmu.edu
// Section E


// EVOLUTION: An overview of genetic algorithms
// 
// Evoltuion is a software that simulates evolution over time
// of a specie of consumers. The three main conceps are:

// VARIABILITY
// At setup, a diverse pool of genetic material is randomly created.

// HERERDITY
// Every time two producers mate, it's geneteics are combined and passed down.

// SELECTION
// The consumer's speed is determine by its darkness.
// Over time natural selection will probabilistically occur.



// CHARACTERS
// 
// PRODUCERS:
// A certain amount of producers is randomly created every time interval.
// The producers gathers sunlight, grows, and if it exceeds a certain amount
// of calories it splits into two. Producers' calories can be consumed
// by consumers, and if producers' calories is negative it dies.

// CONSUMERS:
// A certain amount of consumers is randomly generated at setup.
// Consumers move around randomly searching for food (prdoucers).
// Each movement of a consumer consumes a certain amount of calories, and
// If a consumer's calorie is below zero, it dies. If a consumer's calorie
// reaches a certain threshold, it will stop searching for food and begin
// searching for a potential mate nearby to reproduce with.
// 
// Reproduction consumes energy, and the the consumer may die shortly after.


var time = 1; // Time variable
var w = 480; // width
var h = 480; // height

var turtles_AI = []; // array of consumers

var INDEX = 0; // ID for each turtle
var debug_mode = false; // true to see calorie transfer.


//------------------------------------------
// Creates Turtle
// Each turtle has fitness level based on its color's darkness
// The darker it is the faster it moves to food.
// Each turtle also has a certain amount of energy (calorie).
// Input: x,y,energy, color
// Output: Object turtle
function makeTurtle(tx, ty, energy = random(25, 300),
	c = color(random(0, 255), random(0, 255), random(0, 255))) {
	var turtle = {
		x: tx,
		y: ty,
		life_index: random(-1, 1), //random seed for perlin bheavior
		life_index2: random(-1, 1), //random seed for perlin bheavior
		x_dir: 1,
		y_dir: 1,
		c: c,
		energy: energy,
		index: INDEX,
		mating: false
	};
	turtle.fitness = fitness(turtle); //0 to 100
	turtle.diameter = map(turtle.energy, 0, 100, 1, 20);
	INDEX += 1;
	return turtle;
}

// Determines fitness of Turtle from 0 to 100%
// The darker the color the faster it is.
// Input: Color
// Out: fitness
function fitness(turtle) {
	R = red(turtle.c);
	G = green(turtle.c);
	B = blue(turtle.c);
	avg = (R + G + B) / 3 // 0-255
	return map(avg, 0, 255, 100, 0); //Darker the fitter
}

// Moves Turtle with noise
function turtle_move_AI() {
	speed = .045;
	for (i in turtles_AI) {
		life = turtles_AI[i].life_index;
		life2 = turtles_AI[i].life_index2;
		x_dir = turtles_AI[i].x_dir;
		y_dir = turtles_AI[i].y_dir;

		// Moves turtle with Perlin Noise
		SIZE = 10; //Radius of displacement
		turtles_AI[i].x += x_dir * (noise(time * life) - .5) * SIZE;
		turtles_AI[i].y += y_dir * (noise(time * life2) - .5) * SIZE;
		turtles_AI[i].energy -= .01; //Caloric Cost of movement


	}
}

// Contains any group of objects within the screen
// If object touch boundary of screen reverse direction
// Input: group
function contain(group) {
	for (i in group) {
		// Min
		if (group[i].x < 0) {
			group[i].x = 0
			group[i].x_dir *= -1;
			group[i].dx *= -1;
		}
		if (group[i].y < 0) {
			group[i].y = 0
			group[i].y_dir *= -1;
			group[i].dy *= -1;
		}
		// Max
		if (group[i].x > w) {
			group[i].x = w
			group[i].x_dir *= -1;
			group[i].dx *= -1;
		}
		if (group[i].y > h) {
			group[i].y = h
			group[i].y_dir *= -1;
			group[i].dy *= -1;
		}
	}
}

// Draws Turtle
function drawTurtle() {
	for (var i = 0; i < turtles_AI.length; i++) {
		d = map(turtles_AI[i].energy, 0, 100, 1, 20);
		fill(turtles_AI[i].c);
		ellipse(turtles_AI[i].x, turtles_AI[i].y, d, d)
		fill(255);
		textSize(10);
		if (debug_mode == true) {
			text(floor(turtles_AI[i].energy), turtles_AI[i].x, turtles_AI[i].y)
		}
	}
}

// Removes dead turtles
// If turtle has less than zero energy left it dies.
function turtle_update() {
	for (var i = 0; i < turtles_AI.length; i++) {
		if (turtles_AI[i].energy > 250) {
			turtles_AI[i].mating = true;
		}
		if (turtles_AI[i].energy < 0) {

			turtles_AI.splice(i, 1);
			return
		}
	}
}


//------------------------------------------
// Hunt Food
// Input: individuall turtle
// Output: individiual turtle's target
function hunt(turtle) {
	x = turtle.x;
	y = turtle.y;
	// If no food return false
	if (Object.keys(PRODUCERS) == 0) {
		return false
	} else {
		// Else target is the closest food
		target = {
			x: null,
			y: null,
			d: null
		};
		// Search all food
		for (j in PRODUCERS) {
			// Distance to food
			d_food = dist(x, y, PRODUCERS[j].x, PRODUCERS[j].y);
			// If target is null or closer than previous
			// Reassign target to closest producers
			if (target.d == null || d_food < target.d) {
				target.x = PRODUCERS[j].x;
				target.y = PRODUCERS[j].y;
				target.d = d_food;
				target.i = j
			}
		}
		return PRODUCERS[target.i];
	}
}

// Make all turtle hunt for Food
function HUNT() {
	for (var i = 0; i < turtles_AI.length; i++) {
		target = hunt(turtles_AI[i]);
		if (target != false & turtles_AI[i].mating == false) {
			moveToward(turtles_AI[i], target, turtles_AI[i].fitness);
			eat(turtles_AI[i], target)
		}
	}
}

// Makes Object X moves towards Object Y with V velocity
function moveToward(X, Y, V) {
	v = map(V, 0, 100, 0, .1);
	X.x = lerp(X.x, Y.x, v / 2);
	X.y = lerp(X.y, Y.y, v / 2);
}


// Eat food if food is inisde circle
// Input: individual food, FOOD array
function eat(turtle, target) {
	d = dist(turtle.x, turtle.y, target.x, target.y)
		// If food is inside turtle
	if (d < (turtle.diameter / 2)) {
		target.energy -= .2;
		turtle.energy += 1;
	}
}


//------------------------------------------
// Mating function of turtles
// Turtle becomes mature at 200 calories and seeks to reproduce
// Input: individual turtle
// Ouput: closest mateable target
function mate(turtle) {
	x = turtle.x;
	y = turtle.y;
	target = {
		x: null,
		y: null,
		d: null
	};
	// Search all potential mate
	mate_count = 0;
	for (var j = 0; j < turtles_AI.length; j++) {
		// If Mate-able and not self
		if (turtles_AI[j].mating == true & turtles_AI[j] != turtle) {
			mate_count += 1;
			d = dist(turtles_AI[j].x, turtles_AI[j].y, turtle.x, turtle.y)
			if (target.d == null || d < target.d) {
				target.x = turtles_AI[j].x;
				target.y = turtles_AI[j].y;
				target.d = d;
				target.i = j
			}
		}
	}
	// If there is no mate return false.
	if (mate_count == 0) {
		return false
	}
	// If there is mate return target.
	else {;
		return turtles_AI[target.i];
	}
}

// Makes turtles have sex.
// If mateable turtles touch one another they both lose 100 calorie
// and creates 1 baby. Turtle bcomes mateable at 200 calories.
function sex(turtle, target) {
	d = dist(turtle.x, turtle.y, target.x, target.y)
	if (d < turtle.diameter / 2) {
		turtle.energy -= 100;
		target.energy -= 100;
		// Genetic Averaging and Mutation
		c = lerpColor(turtle.c, target.c, random(.3, .7));
		x = (turtle.x + target.x) / 2;
		y = (turtle.y + target.y) / 2;
		turtles_AI.push(makeTurtle(x, y, 66, c))
	}
}


// Loop through turtles to and make them mate
function MATE() {
	for (var i = 0; i < turtles_AI.length; i++) {
		target = mate(turtles_AI[i]);
		if (target != false & turtles_AI[i].mating == true) {
			moveToward(turtles_AI[i], target, turtles_AI[i].fitness);
			sex(turtles_AI[i], target);
		}
	}
}


//------------------------------------------
// Control

// Adds producers where mouse is clicked
function mouseClicked() {
	// FOOD.push(new makeFood(mouseX, mouseY));
	producer = (new makeProducer(mouseX, mouseY, 30));
	PRODUCERS[time] = producer;
	print(PRODUCERS);
}

// Adds producers where mouse is dragged
function mouseDragged() {
	if (millisecond % 2 == 0) {
		producer = (new makeProducer(mouseX, mouseY, 30));
		PRODUCERS[time] = producer;
	}
}


//------------------------------------------
// Producers
// Make food from sunlight
// Grows overtime and increase cell amount
var PRODUCERS = {};

// Creates prodcuers that grows from light
// Producers are eaten by turtles
// Input: x,y, energy, dx, dy
function makeProducer(x, y, energy = 10, dx = 0, dy = 0) {
	this.x = x;
	this.y = y;
	this.life_index = random(-1, 1); //random seem for perlin beheavior
	this.life_index2 = random(-1, 1); //random seem for perlin beheavior
	this.energy = energy;
	this.c = color(0, 255 / 2, 0, 255 * random(.5, 1));
	this.mitosis = false;

	this.dx = dx;
	this.dy = dy;
}


// Draws producers
function drawProducer() {
	for (key in PRODUCERS) {
		x = PRODUCERS[key].x;
		y = PRODUCERS[key].y;
		c = PRODUCERS[key].c;
		energy = PRODUCERS[key].energy;
		fill(c);
		strokeWeight(1)

		// Perlin noise to size to give it life
		base_vivacity = 5;
		speed = 1
		life = base_vivacity * (sin(time / 5 * speed))

		// Make rectangles rotate randomly
		push();
		rectMode(CENTER);
		translate(x, y);
		rotate((noise(PRODUCERS[key].life_index) * 360));
		rect(0, 0, energy + life, energy + life);
		pop();

		// Debug mode
		if (debug_mode == true) {
			fill(255);
			textAlign(CENTER);
			text(round(PRODUCERS[key].energy), x, y);
		}
	}
}


// Makes producer grow and reproduce if it has enough energy
function growProducer() {
	for (key in PRODUCERS) {
		// Grow Producer
		life_index = PRODUCERS[key].life_index;
		PRODUCERS[key].energy += noise(time * life_index) / 4;
		// Reproduce
		if (PRODUCERS[key].energy > 50) {
			PRODUCERS[key].mitosis = true
		}
	}
}


// Producers preform mitosis by using it's energy to reproduce
function mitosisProducer() {
	for (key in PRODUCERS) {
		if (PRODUCERS[key].mitosis == true) {
			energy = PRODUCERS[key].energy
				// Create 2 new cells
			for (i = 0; i < 2; i++) {
				producer = (new makeProducer(
					PRODUCERS[key].x,
					PRODUCERS[key].y,
					5,
					random(-energy / 4, energy / 4),
					random(-energy / 4, energy / 4)));
				PRODUCERS[time] = producer;
				PRODUCERS[key].energy -= 25;
			}
		}
	}
}

// Basic Physics for producer while splittig
function mitosisPhysic() {
	for (key in PRODUCERS) {
		PRODUCERS[key].x += PRODUCERS[key].dx;
		PRODUCERS[key].y += PRODUCERS[key].dy;
		PRODUCERS[key].dx = lerp(PRODUCERS[key].dx, 0, .1);
		PRODUCERS[key].dy = lerp(PRODUCERS[key].dy, 0, .1);
	}

}


// Kills Producer if its energy is below 0.
function dieProducer() {
	for (key in PRODUCERS) {
		if (PRODUCERS[key].energy < 0) {
			delete PRODUCERS[key]
		}
	}
}

// Give Producer Perlin noise to make it look alive
function lifeProducer() {
	for (key in PRODUCERS) {
		SIZE = .5;
		lifeX = (noise(time * PRODUCERS[key].life_index) - .5) * SIZE;
		lifeY = (noise(time * PRODUCERS[key].life_index2) - .5) * SIZE;
		PRODUCERS[key].x += lifeX;
		PRODUCERS[key].y += lifeY;

	}
}


var producer_timer = 1;
// Adds new producer into the system every producer timer interval
function add_food(interval) {
	producer_timer += 1;
	print(producer_timer)
	if (producer_timer % 500 == 0) {
		for (var i = 0; i < random(0, 6); i++) {
			PRODUCERS[time] = (new makeProducer(random(0, w), random(0, h), 1));
			time += .1;
		}
	}
}


//------------------------------------------
// SETUP
function preload() {
	w = windowWidth;
	h = windowHeight;
}

// Creates petri dish
function setup() {
	createCanvas(w, h);
	background(255);
	num_node = 100;
	// Create a diverse genetic pool of consumers
	for (i = 0; i < num_node; i++) {
		t = makeTurtle(random(0, w), random(0, h));
		turtles_AI.push(t);
	}
	// Initial set of producers
	for (i = 0; i < num_node / 10; i++) {
		PRODUCERS[i] = (new makeProducer(random(0, w), random(0, h)));
	}
}

//------------------------------------------

function draw() {
	background(255, 255, 255, 255 * .33);
	millisecond = floor(millis()) % 2000;
	// Model
	time += .1;
	turtle_move_AI();
	contain(turtles_AI);
	contain(PRODUCERS);
	HUNT();
	MATE()
	turtle_update();

	// Producers 
	growProducer();
	dieProducer();
	mitosisProducer();
	mitosisPhysic();
	lifeProducer();
	add_food(1000);

	// Draw
	noStroke();
	drawTurtle();
	drawProducer();
}

Producer splits into two after growing big enough:

Producers splitting.

Consumers mate after it exceeds a certain caloric threshold and combines their genes with some amount of mutation:

Consumers mating.

At first, the simulation begins with a lot genetic diversity:

The simulation begins with a lot gentic diversity.

But over time due to natural selection for faster (darker) consumers, the genetic diversity is significantly decreased:

Over time natural selection reduces genetic diversity.

Interestingly, membrane-like structures also start to emerge from how food is being consumed. Here, the producers form a membrane around a dense cluster of producers that is rapidly splitting.

Membrane-like structures emerged although it wasn’t explicity programmed.

These membrane-like and clusters macrostructures were not explicitly programmed, they emerge probabilistically out of the specification and rules of this simulation. Here, a wall of producer is protecting a rapidly splitting colony of producers.

Wall of producers protecting a rapidly growing colony.

Group behavior also emerged out of the algorithm. Here, the producers began to form almost cell like clusters where food is rapidly consumed and reproduction distance is significantly decreased thereby creating a cell-like unit.

Individual cell-like clusters of rapidly reproducing and consuming begin to emerge.
Here, one cell-like cluster separately moves towards another group of producers.
Last colony of producers consumed.

As the system reaches its carrying capacity, the producer begins to starve and die.

No more food left.
Consumers begin to starve and die.
As food emerge, the cycle of population repeats.

And as this cycle of extreme population swing for both the producers and consumers restarts, the genetic diversity of population doesn’t. Over time, despite natural mutation rate, the consumer population becomes abosolutely homogenous without any genetic diversity. In real life, this means that the population is extremely susceptible to a disease that can complete wipe its whole population out. 

No more genetic diversity is left.

Conclusion:

  1. Features can be created implicitly through explicitly programming beheaviors. Alhtough certain feaures of this simulation wasn’t explicity programmed, it emerge through the algorithms of the character’s beheavior.
  2. A system of genetic evolution will never reach its ultimate form. Although the black ones were the fastest, they needed to reproduced with inferior consumers thereby creating sub par offpsrings. Over time, this means that humans as a geneticically evolving organsims will never reach our ultimate form, if such form exist.
  3. What happens when there is no genetic diversity? If life on earth continued to evolve due to natural selection and converge towards an ideal form and homogenity what would happen?

 

SaveSave

SaveSave

SaveSave

mjanco – Final Project – Section B

sketch

//Michelle Janco
//mjanco@andrew.cmu.edu
//Final Project - Section B

var fish = [];
var tree = .05;
var treeSpeed = .0009;
var lX = 300;
var song;

//yellow sky color
var yellowSkyR = 240;
var yellowSkyG = 215;
var yellowSkyB = 87;

//new sky color
var skyR = 217;
var skyG = 98;
var skyB = 88;

function setup() {
    createCanvas(640, 240);
    // create fish
    for (var i = 0; i < 5; i++){
        var rx = random(width);
        fish[i] = makefish(rx);
    }
  frameRate(30);
}

function draw() {
    background(yellowSkyR, yellowSkyG, yellowSkyB);
    displayHorizon();
    makeTree();
    updateAndDisplayfish();
    removefishThatAreOutOfView();
    addNewfishWithSomeRandomProbability();

    //change background color as mouse
    //moves across canvas
    if ((mouseX >= 640) & (mouseX <=640)){
      mouseX = 640;
  }
    if ((mouseX > 0) & (mouseX < 640)){
        yellowSkyR = mouseX*((217-240)/640) + 240;
        yellowSkyG = mouseX*((98-215)/640) + 215;
        yellowSkyB = mouseX*((88-87)/640) + 87;
    }

    //big cloud
    fill(255);
    ellipse(mouseX + 5, 55, 20);
    ellipse(mouseX + 25, 50, 35);
    ellipse(mouseX + 40, 60, 25);
    ellipse(mouseX + 55, 50, 40);
    ellipse(mouseX + 80, 50, 25);
    ellipse(mouseX + 95, 55, 15);

    //smaller cloud
    fill(255);
    ellipse(mouseX + 68, 10, 10);
    ellipse(mouseX + 80, 10, 20);
    ellipse(mouseX + 95, 10, 25);
    ellipse(mouseX + 110, 10, 30);
    ellipse(mouseX + 125, 8, 30);
    ellipse(mouseX + 140, 10, 15);
    ellipse(mouseX + 145, 10, 10);

    //smallest cloud
    fill(255);
    ellipse(mouseX + 268, 40, 10);
    ellipse(mouseX + 280, 40, 20);
    ellipse(mouseX + 295, 40, 25);
    ellipse(mouseX + 310, 40, 40);
    ellipse(mouseX + 325, 38, 30);
    ellipse(mouseX + 340, 40, 15);
    ellipse(mouseX + 345, 40, 10);
}

function mouseClicked() {
  //if mouse is inside sun, draw text
    var d = dist(mouseX, mouseY, 550, 50);
    if (d < 100) {
    showText(true);
    }
}

function showText(mouse) {
    if (mouse==true) {
      textSize(32);
      fill(0);
      text("Salmon Skies", 20, 50);
    }
}

//make trees
function makeTree() {
    noStroke();
    fill(22, 60, 28);
    beginShape();
    for (var i = 0; i < width; i++) {
        var x = (i * tree) + (millis() * treeSpeed);
        var y = map(noise(x), 0, 1, height/2, height/3);
        vertex(i, y);
    }
    vertex(width, height-height/2);
    vertex(0, height-height/2);
    endShape();
}

function displayHorizon() {
    noStroke();
    line(0,height-height/2, width, height-height/2);
    //pond
    fill(44, 80, 108);
    rect(0, height-height/2, width, height-height/2);
    //sun
    fill(240);
    noStroke();
    ellipse(550, 50, 50, 50);
}

function updateAndDisplayfish(){
    // update fish positions, display them
    for (var i = 0; i < fish.length; i++){
        fish[i].move();
        fish[i].display();
    }
}

function removefishThatAreOutOfView(){
    //if entirety of the fish are off canvas
    //then remove them
    var fishToKeep = [];
    for (var i = 0; i < fish.length; i++){
        if (fish[i].x + fish[i].breadth > 0) {
            fishToKeep.push(fish[i]);
    }
        }
  fish = fishToKeep;
}

function addNewfishWithSomeRandomProbability() {
    //small probability, add a new fish to the end
    var newfishLikelihood = 0.005;
    if (random(0,1) < newfishLikelihood) {
        fish.push(makefish(width));
    }
}

//update position of fish
function fishMove() {
    this.x += this.speed;
}

//draw the fish
function fishDisplay() {
    var fishHeight = random(10, 15);
    var fHeight = (20);
    fill(219, 97, 87, 150);
    noStroke();
    push();
    translate(this.x, height - 60);
    //fish body
    ellipse(0, -fHeight, this.breadth, fishHeight);
    fill(255);
    //fish eyes
    ellipse(-13, -fHeight, 4, 6);
    fill(0);
    ellipse(-13, -fHeight, 2, 3);
    //fish fins
    fill(219, 97, 87, 150);
    ellipse(0, -fHeight+7, 4, 8);
    fill(219, 97, 87, 150);
    ellipse(-2, -fHeight-7, 6, 8);
    fill(219, 97, 87, 150);
    arc(23, -fHeight, 30, 30, 0, HALF_PI);

    //fish reflection
    fill(219, 97, 87, 30);
    ellipse(0, fHeight, this.breadth, fishHeight);
    //reflection fish eyes
    fill(255, 30);
    ellipse(-13, fHeight, 4, 6);
    fill(0, 30);
    ellipse(-13, fHeight, 2, 3);
    //reflection fish fins
    fill(219, 97, 87, 30);
    ellipse(0, fHeight+7, 4, 8);
    fill(219, 97, 87, 30);
    ellipse(-2, fHeight-7, 6, 8);
    fill(219, 97, 87, 30);
    arc(23, fHeight, 30, 30, 0, HALF_PI)
    pop();
}

function makefish(birthLocationX) {
    var fis = {x: birthLocationX,
                breadth: 50,
                speed: -2.0,
                nlil: round(random(2,40)),
                move: fishMove,
                display: fishDisplay}
    return fis;
}

For this project, I wanted to go back to a concept that I struggled with. During the generative landscape project, I ran into quite a few problems and was not able to make an image that I found aesthetically pleasing. I wanted to return to this, and have more time to work through the concepts to be able to make something calming to watch. I am drawn to imagery that relaxes the viewer, and I imagine this is the type of image that could be watched to slow down a person’s heart rate, as the fish move at a calming pace. I love going to the lake back home with my Dad and watching the fish go by, which was always a therapeutic activity. This image in my head was what I wanted to emulate. Considering the amount of difficulty and trouble I have faced in this class, I’m glad I had extra time to really focus, take my time, and make something that feels fairly complete. I learned a lot more skills from being able to slow down and focus on these concepts.