Final Project – Undertale Piano


determination

glamour

highA

highAsharp

highB

highC

highCsharp

highD

highDsharp

highE

highF

highFsharp

highG

highGsharp

lowA

lowAsharp

lowB

lowC

lowCsharp

lowD

lowDsharp

lowE

lowF

lowFsharp

lowG

lowGsharp

papyrusTalk

sansTalk

My project is an interactive piano keyboard that will play when the user presses the mouse over the individual keys. Keep in mind that because of the way the code is written, the white keys are only playable in the area below the black keys.

For a simple melody from the indie game Undertale to play, the user needs to type in a certain password that will display as the user types. That certain is… “determination.”

Screenshots to prove functionality of project:

screen-shot-2016-12-09-at-6-54-27-pmscreen-shot-2016-12-09-at-6-54-39-pmscreen-shot-2016-12-09-at-6-54-43-pm

Running a local server is required for the code template. I didn’t know how to display the project for this reason, and so I have attached my code and embedded all 28 of the .wav sound files used in the code. (If the .wav files are inaccessible somehow even when looking at the text, please let me know!) All the image URLs are direct links to the images themselves. Directions for running a local server are here.

Credits:
All copyright and materials, including the depicted characters, sound effects, quotes, and songs, of Undertale belong to its creator, Toby Fox.

The performance of the “determination” melody belongs to Kyle Landry, whose video can be found here for a direct link or embedded below.

All manual piano key notes were recorded by myself using the sound editor Audacity and the piano in Mudge residence hall in Carnegie Mellon University.

P.S., if you’ve played Undertale, try typing in the word that would please a certain fabulous robot the most when he presents his essay question… or you could just look at the code for the little treat I put in. 🙂

Rhea Nayyar’s Final Project: “A Girl Dismissed”, the angsty goth twitterbot

My good friend Kate was the inspiration for my twitter bot. No, she’s not a goth queen, but she did a hilarious text generation program that used a computer manual and a Shakespeare play to make computerized sonnets.

https://twitter.com/666sadshawty666 <—- This is the account!!!! It tweets every half hour as long as I keep the program running.

http://imgur.com/gallery/PJLdR <—- These are some of the funniest returns I got from the program. I highly recommend looking through this if you have time but the twitter feed itself should give you a good idea of what the bot has to say.

http://pastebin.com/EufB7Vcz <—- this is a pastebin link that contains
the input text (emobot_words.txt) employed by my program. I collected
these texts from various places:

  •  Twitter itself: I scoured through several tags like “#gothlife”, “#gothproblems”, “#gothculture” and so on and found some amazing content to include in my file.
  • Tumblr: Looking through similar tags on tumblr yielded the same spectacular results.
  • Facebook Groups: Lots of angst-ridden people particularly enjoy airing their grievances on social media it seems.
  • Several Goth Blogs: gothicsubculture.com, www.thebelfry.rip, whatisgoth.com, and many other sites had loads of information about
    the gothic subculture, the stereotypes, history, and the backlash from mainstream society. They were actually pretty educational but all boiled down to the same message. Goths are drawn to darkness and macabre, but are generally happy people.
  • Song Lyrics: All from the popular early 2000s band called Evanescence. Tracks include “My Immortal” and “Wake Me Up”.
  • My Own “Creativity”: It’d be inappropriate, in my opinion at least, to use so many other sources for text generation so I absolutely had to include some of my own angsty poetry and thoughts from years past. I only hope it adds to the authenticity of this bot.

***I appreciate being able to locate and use all this content and this work isn’t intended to be offensive but to merely poke fun at the multi-faceted subculture. I was interested in gothic culture throughout middle school and high school and I’d like to consider this as an homage to my former self.***

There was an issue with creating the Twitter bot with .js file, so I had to switch to Processing entirely. There were some differences in syntax, but
it was relatively easy to adjust the code properly. I had learned some new
functions, too. And what a boolean is. That was very cool. Boolean is good.

ANYWAYS, down to the important stuff: RiTa library. The RiTa library contains about 40K words that are classified and grouped appropriately.
Self-described as a “software-toolkit for computational literature”, RiTa library is very simple to use but has incredibly intricate and complex results. I don’t want to go on forever about it, so I’ll link you to the RiTa
homepage: https://rednoise.org/rita/index.php

To create the text generator, I had to use the Markov chain function. The Markov chain is frequently used in natural text generation through programming. Essentially, the Markov chain takes input text and analyzes the words and which other words follow them and so on. Through this analysis, the Markov chain function allows the program to randomly generate grammatically correct sentences from the input text (in this case, the emobot_words.txt file). This is achieved by calling a function known as markov.generateSentences(); .

captura-de-pantalla-2016-12-09-a-las-5-36-48-pm

captura-de-pantalla-2016-12-09-a-las-5-36-36-pm

RiTa’s reference page provided me with the accurate syntax/template codes to complete this program.


As for actually creating the bot, Temboo was my go-to source for the implementation. It provided me with many outlets to create a bot with, but Twitter was my final choice. I had to go through some hoops (well, not really… I just needed to apply for the OAuth keys and tokens and connect them with the account) to get it up and running but it works and I’m quite happy about that!
captura-de-pantalla-2016-12-09-a-las-5-36-16-pm

In the end, sometimes the bot really has a hard time making sense. They may not always be syntactically correct or have and contextual information but they’re humorous, relatable (1 out of every 5 times I suppose), and poetic. It’s as if the person who would be behind this is too overwhelmed with their thoughts to make coherent sentences sometimes. We’ve all been there.

Stay spooky, my dark, damaged friends!

-Rhea

Final Project Windy Day Gardening – Simin Li

It is a windy day. Let’s plant some things! Add water and fertilizer to make the plant grow. Fertilizer makes the plant grow faster!

screen-shot-2016-12-09-at-5-48-16-pm

Harvest when you are finished growing. screen-shot-2016-12-09-at-5-41-09-pm

finalproject

// Simin Li
// Section C
// siminl@andrew.cmu.edu
// Final Project 

var tree = [];
var woodlength;
var branchStemX = 340;
//x pos of plant branch stem
var branchStemY = 600;
//y pos of plant branch stem
var fruitAmount = 1;
var fruitSize = 19;
var harvested = 0;
var harvestButton;
var picking = false;
var waterButton;
var watering = false;
var fertilizeButton;
var fertilizing = false;
var wateringCan;
var hand;
var plum;
var leaf;
var compost;
var seedling; 
//image names
var count;
//keep track of times a button is clicked
var branchDirection = 1;
//the direction of the recursion tree
var matureness = 9;
//levels of recursion tree

function preload(){
    wateringCan = loadImage("http://i.imgur.com/JNvlZzy.png");
    hand = loadImage("http://i.imgur.com/7r9pIdV.png");
    plum = loadImage("http://i.imgur.com/JEh9AIh.png");
    leaf = loadImage("http://i.imgur.com/MDoduCh.png");
    compost = loadImage("http://i.imgur.com/Rut3lp4.png");
    seedling = loadImage("http://i.imgur.com/BG0X2wj.png");
    //preload self drawn images
}

function setup() {
    createCanvas(680, 680);
    frameRate(7);

    harvestButton = createButton('harvest');
    harvestButton.position(65, 65);
    harvestButton.mousePressed(pick);
    //create a button that allows you to harvest fruit

    waterButton = createButton('water');
    waterButton.position(65, 85);
    waterButton.mousePressed(water);
    //create a button that allows you to water the plant

    fertilizeButton = createButton('fertilize');
    fertilizeButton.position(65, 105);
    fertilizeButton.mousePressed(fertilize);
    //create a button that allows you to fertilize the plant

    background(240);
}

function draw() {

    noStroke();
    fill("SkyBlue");
    rect(0,0,680,600);
    //render sky
    dirt();
    //render soil
    fill(247,197,51);
    ellipse(width - 90, 90, 160,160);
    //render sun
    push();
        translate(width / 4, height - 80);
        recursionBranch(matureness, 60, 9);
    pop();
    push();
        translate(width * 3 / 4, height - 80);
        recursionBranch(matureness, 60, 9);
    pop();
    //render background recursion trees
    var outcome = "The number of fruit harvested is " + harvested + ".";
    textAlign(CENTER);
    fill(255);
    textSize(16);
    text(outcome,width * 4 / 5 , height - 15);
    //display the number of fruit harvested 
    for(var i = 0; i < tree.length; i ++){
        tree[i].draw();
        stroke(42,27,21);
        strokeWeight(6);
        line(340, 600, 340,tree[i].branchY);

    }
    //render whole plant
    image(seedling, 265, 550, seedling.width * 0.15, seedling.height * 0.15);
    if(picking){
    //if the harvest button is pressed change cursor to hand
        noCursor();
        image(hand, mouseX - 71, mouseY - 15, hand.width * 0.2, hand.height * 0.2);
        //shift the new cursor a bit so the finger tip and arrow can align
        }
    else if(watering){
    //if the harvest button is pressed change cursor to watering can
        noCursor();
        image(wateringCan, mouseX - 50, mouseY - 90, wateringCan.width * 0.3, wateringCan.height * 0.3);
    }
    else if(fertilizing){
    //if the harvest button is pressed change cursor to manure
        noCursor();
        image(compost, mouseX , mouseY , compost.width * 0.3, compost.height * 0.3);
    }
    else{
        cursor();
    }
}
function drawBranch(){
    stroke(42,27,21);
    strokeWeight(4);
    var tipX = this.branchX + this.brachDirection * this.branchLength * cos(this.angle);
    var tipY = this.branchY - this.branchLength * sin(this.angle);
    line(this.branchX,this.branchY,tipX,tipY);
    if(this.fruit){
        //if there is fruit, render fruit
        ellipseMode(RADIUS);
        ellipseMode(CENTER);
        fill(124,23,22);
        noStroke();
        image(plum, this.fruitX - plum.height / 6, this.fruitY - plum.height / 12, plum.width / 3,plum.height / 3);
    }
    for(var n = 0; n < this.leafNumber; n ++){
        push();
            translate(this.leaves[n][0],this.leaves[n][1]);
            rotate(this.leaves[n][2]);
            noStroke();
            fill(92,190,66);
            image(leaf, 0, 0, leaf.width / 2,leaf.height / 2);
        pop();
    }
    //render leaves
}
function makeBranch(length,x,y){
    if ((y / 30) % 2 === 0){
        var direction = - 1;
    } 
    else{
        direction = 1;
    }
    //alternate branch directions
    var branchAngle = random(0, PI / 3);
    //randomize the angle of branch
    var leafNumber = Math.floor(random(2, 6));
    //randomize the number of leaves on each branch
    var leaves = [];
    for(var m = 0; m < leafNumber; m ++){
        var leafPosition = random(0,length);
        leafX = x + direction * leafPosition * cos(branchAngle);
        leafY = y - leafPosition * sin(branchAngle);
        leafRotation = direction * random(-TWO_PI, TWO_PI);
        leaves[m] = [leafX, leafY, leafRotation];
    }
    //store leaf information in an array
    var branches = [];
    var s = {
        brachDirection: direction,
        branchX: x,
        branchY: y,
        angle: branchAngle,
        branchLength: length,
        fruit: true,
        fruitX: x + direction * length * cos(branchAngle),
        fruitY: y - length * sin(branchAngle),
        leafNumber: leafNumber,
        leaves: leaves,
        branches: branches,
        draw: drawBranch
    }
    return s;
}

function mousePressed() {
    // fruitAmount = floor(random(0,3));
    count += 1;
    if(branchStemY > 100){
        if(watering & (count > 1)){
            branchStemY -= 30;
            //grow by 30
            woodlength = random(70,130);
            //randomize length of branch 
            tree.push(makeBranch(woodlength,branchStemX,branchStemY));
            //push branches on to the array tree
        }
        if(fertilizing & (count > 1)){
            branchStemY -= 30;
            woodlength = random(100,150);
            //randomize length of branch (fertilizer causes more length)
            tree.push(makeBranch(woodlength,branchStemX,branchStemY));
            //push branches on to the array tree
        }
    }
    if(picking){
        for(var j = 0; j < tree.length; j++){
            if(tree[j].fruit){
                if(dist(mouseX,mouseY,tree[j].fruitX,tree[j].fruitY) <= fruitSize){
                    tree[j].fruit = false;
                    //do not display picked fruit
                    harvested += 1;
                    //update the amount of fruit harvested
                }
            }
        }
    }
}
function recursionBranch(depth, len, thickness) {
//creates recursive tree with complexity of depth, size of len and boldness of thickness
    strokeWeight(thickness);
    stroke(50,45,39);
    line(0, 0, 0, -len);
    //render trunk
    push();
        translate(0, -len);
        if (depth > 0) {
            if (depth > 5 ) {
            //when complexity is low, thickness decreases faster
                rotate(radians(-25));
                recursionBranch(depth - 1, len * random ((6 / 7), (8 / 9)),thickness * (3/ 4));
                rotate(radians(50));
                recursionBranch(depth - 1, len * random ((6 / 7), (8 / 9)),thickness * (3/ 4));
            }
            else {
            //when complexity is low, thickness decreases slower
                if(random(1) < 0.75){
                //most of the time create one branch
                    if(branchDirection === -1){
                        rotate(radians(random(-10,-20)));
                        recursionBranch(depth - 1, len * random ((6 / 7), (3 / 4)),thickness * (6 / 7));
                        branchDirection *= -1;
                        //alternate branch direction
                    }
                    else{
                        rotate(radians(random(10,20)));
                        recursionBranch(depth - 1, len * random ((6 / 7), (3 / 4)),thickness * (6 / 7));
                        branchDirection *= -1;
                        //alternate branch direction
                    }
                }
        else{
        //occasionally create two branches
            rotate(radians(-14));
            recursionBranch(depth - 1, len * random ((6 / 7), (3 / 4)),thickness * (6/ 7));
            rotate(radians(28));
            recursionBranch(depth - 1, len * random ((6 / 7), (3 / 4)),thickness * (6/ 7));
            }
        }
    }
    pop();
}
function dirt(){
    //render dirt
    noStroke();
    fill(90,80,60);
    rect(0,600,680,80);
    image(seedling, 290, 570, seedling.width * 0.1, seedling.height * 0.1);
}
function pick(){
//set to picking mode
    picking = true;
    watering = false;
    fertilizing = false;
}

function water(){
//set to watering mode
    watering = true;
    picking = false;
    fertilizing = false;
    count = 0;
    
}

function fertilize(){
//set to fertilizing mode
    fertilizing = true;
    watering = false;
    picking = false;
    count = 0;
}

For the final project, I wanted to make an interactive plant. I have always loved gardening games because of the joy of harvesting decided to make one myself. The number and distribution of leaves and fruit are generated randomly . The extent to which the plant grows will depend on how many times it is watered and fertilized . After you have decided to stop watering, it is harvesting season. The player clicks on a button called “Harvest” and  can harvest the fruit by clicking on the fruit and the number of fruit harvested will be displayed on the screen. I also incorporated hand drawn elements in the project to make it more visually pleasing. I scanned the images and uploaded them to imgur to use them in my project.

Final Project – Naomi Shimada

For my final project I wanted to incorporate my writing. I took a short story that I wrote and then broke it down into 15 different scenes. I looked at each scene and then decided on a strong image on each one like a picture book. From there I coded each scene as a separate function with helper functions to create each individual aspect. In some of the scenes I decided that I wanted there to be an interactive aspect so I coded other functions that were dependent on the mouse position. I thought that by making the writing more visual and because often times you have to read the story to know what’s animated in the scene the writing itself would become more enjoyable to non-readers.

Credit for the images and the song, none of which are my own:

I wanted to code the photo of the man in the door, but creating an accurate image that captured the emotion in the actor’s face was too difficult. Here is the link.

The next image is the high chair in the kitchen. Here is the link to the original image.

The third image is another that I wanted to code but found that using an image conveyed the emotion better. Here is the link.

The final image link.

The song is Styx’s Sail Away.

Screenshots from the project:

screen-shot-2016-12-09-at-10-05-44-amscreen-shot-2016-12-09-at-10-05-56-amscreen-shot-2016-12-09-at-10-06-06-am

Final Project

The Adventures of Peewie

For my project, I created a short video adventure / educational game which revolves around bringing Peewie home to safety. In the game, using the up arrow button, you jump to avoid the cacti and spiky platforms. I would recommend to constantly stay jumping. If you hit a spiky platform or cacti, the game ends and you see this screen.

screen-shot-2016-12-09-at-2-30-06-pm

If you survive through the whole game, you will see all 4 levels and receive fun facts about koalas at every level. If you make it to the end, you are brought home to safety.screen-shot-2016-12-09-at-2-42-19-pm

In this picture, Peewie is covering Obama’s face. In my proposal I said that the game would involve the koala climbing a tree but it evolved more into creating a visual experience/story more so than a game. Have fun!

sketch

//Mairead Dambruch
//Section C
//Project 12
var platforms = [];//platform array
var koalaY = 0;
var koalaDy = 0; //vertical velocity
var offset = 0;
var barNum = 300;//number of platforms
//picture names
var lostlife;
var congrats;
var cactus;
var spike;
var angel;
var GameOver;
var reload;
var redX;
var spikeExample;
var cactiExample;
var heaven;
var dad;


function preload(){
    lostlife = loadImage("http://i.imgur.com/eCYmH15.jpg");
    congrats = loadImage("http://i.imgur.com/EQxzwtc.jpg");
    cactus = loadImage("http://i.imgur.com/Hp9LFpZ.png");
    spike = loadImage("http://i.imgur.com/nRBS4fx.png");
    angel = loadImage("http://i.imgur.com/8kZpNEO.jpg");
    GameOver = loadImage("http://i.imgur.com/LzK1lnJ.jpg");
    reload = loadImage("http://i.imgur.com/tIlOzm8.png");
    redX = loadImage("http://i.imgur.com/ENZweGy.png");
    spikeExample = loadImage("http://i.imgur.com/GZCztt6.png");
    cactiExample = loadImage("http://i.imgur.com/2kTQhSR.png");
    heaven = loadImage("http://i.imgur.com/fEk6K32.jpg");
    dad = loadImage("http://i.imgur.com/EQxzwtc.jpg");
    }

function newPlatform(px, py, pw) {
    return {x: px, y: py, w: pw};
    }

function setup() {
    createCanvas(600, 300);
    platforms.push(newPlatform(10, 10, 10));
    }

function platRight(p) {
    return p.x + p.w;
    }

function platLast() {
    return platforms[platforms.length - 1];
    }

function draw() {
    var c = color(123, 234, 223);
    var cactusheight = 225;
    var cactiO = 200;
    var groundO = 35;
    var spikeOx = 143;
    var spikeOy = 124;
    var platformW = 30;
    var py = 150;
    background(c);
    stroke(0);
    fill(0);

    // the ground
    fill(255, 217, 102);
    rect(0, height - groundO, width, groundO);

    //draw obstacles
    fill(255);
    stroke(255);

    for (var i = 0; i < platforms.length; i++) {
          var p = platforms[i];
          rect(p.x- offset, p.y , platformW, platformW);
          //draws cacti
          image(cactus, (p.x - offset) - cactiO, cactusheight ,(cactus.width / 2), (cactus.height / 2));
          //draws spikes
          image(spike, ((p.x - spikeOx) - offset), p.y - spikeOy, (spike.width * 1.5), (spike.height * 1.5));
          }

    //time tracker
    fill(100);
    noStroke();
    var timeX = 130;
    var timeY = 55;
    var ttextX = 5;
    var ttextY = 17;
    var millisecond =  millis();
    rect(0, 0, timeX, timeY);
    stroke(0);
    fill(255);
    textSize(10);
    text("Milliseconds \nrunning: \n" + millisecond, ttextX, ttextY);

     //screen 1
    if(millis() > 1 & millis() < 3000){
        var s1textX = 230;
        var s2textY = 200;
        offset = 0;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(12);
        text("BRING PEEWIE HOME!!", s1textX, s2textY);
        }

    //instructional screen
    if(millis() > 3000 & millis() < 7000){
        var itextX = 235;
        var itextY = 200;
        var itextO = 220;
        var imageO = 100;
        offset = 0;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(12);
        text("HIT THE UP ARROW", itextX, itextY);
        text("TO AVOID CACTI & SPIKES", itextO, itextO);
        image(spikeExample, imageO, imageO, (spikeExample.width/2), (spikeExample.height/2));
        image(cactiExample, imageO*4 , imageO, (cactiExample.width/2), (cactiExample.height/2));
        }

    //Level 1
    if(millis() > 7000 & millis() < 9000){
        var l1text = 200;
        var l1O = 30;
        offset = 0;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(18);
        text("LEVEL 1", l1text, l1text);
        text("START JUMPIN'!", l1text, l1O + l1text);
        }

    //Level 2
    if(millis() > 18000 & millis() < 23000){
        l2os = 20;
        l2textY = 270;
        offset = 0;
        var l2text = 200;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(18);
        text("LEVEL 2 FUN FACT", l2text, l2text);
        textSize(13);
        text("In Aborigine language, the word ‘koala’ means ‘no water’, because the only water", l2os, l2textY);
        text("they drink is through eucalyptus leaves.", l2os, l2textY + l2os);
        }

    //Level 3
    if(millis() > 30000 & millis() < 35000){
        var l3text = 200;
        offset = 0;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(18);
        text("LEVEL 3 FUN FACT", l3text, l3text);
        textSize(15);
        text("Koalas have the smallest brain to body size ratio of any mammal - Sorry Peewie!", l2os, l2textY + l2os);
        }

    //Level 4
    if(millis() > 45000 & millis() < 50000){
        var l4text = 200;
        offset = 0;
        p.y = 150;
        background(255);
        stroke(0);
        fill(0);
        textSize(18);
        text("LEVEL 4 FUN FACT", l4text, l4text);
        textSize(15);
        text("51% of koalas have chlamydia - Let's hope Peewie is in the 49%!", l2os, l2textY + l2os);
        }

    //Level 5, End of Game
    if(millis() > 55000 & millis() < 1000000){
        var l5text = 200;
        var l5x = 150;
        var l5y = 285;
        offset = 0;
        barNum = 0;
        background(255);
        image(heaven, 0, 0, (heaven.width/2), (heaven.height/2));
        image(dad, l5text, 70, (dad.width/3), (dad.height/3));
        stroke(0);
        fill(0);
        textSize(30);
        text("YOU MADE IT HOME!!", l5x, l5y);
        }

    // if first platform is offscreen to left, remove it
    if (platforms.length > 0 & platRight(platforms[0]) < offset) {
        platforms.shift();
        }

    // if last platform is totally within canvas, make a new one
    if (platRight(platLast()) - offset < width) {
        var p = newPlatform(platRight(platLast()), // start location
                            random(150, 250), // height of new platform
                            barNum); // all platforms have width 200 for now
        platforms.push(p); // add to our array of platforms
        }

    // move the "landscape"
    offset += 1;

    //koala is moving
    var pindex = 0;
    var koalaX = 300;

    //if platform is behind koala, increase index
     if (platRight(platforms[pindex]) - offset < koalaX){
         pindex += 1;
         }

     var py = platforms[pindex].y;

     //if koala is above platform, land on base
     if (koalaY <= py){
         koalaY = min(py - 20, koalaY + koalaDy);
         } else {
     if (koalaDy < 0){
         koalaDy = 0;
         }
         koalaY = min (height, koalaY + koalaDy)
         }

    //if koala is past platform base, game over
    if (koalaY >= p.y){
         offset = 0;
         background(0);

         //aligns koala to be in angel;
         koalaY = 170;
         koalaX = 310;

         //angel
         image(angel, 245, 90, (angel.width/1.8), (angel.height/1.8));

         //game over checkerboard
        image(GameOver, 110 , 20, (GameOver.width/4), (GameOver.height/4));
        image(GameOver, 360 , 20, (GameOver.width/4), (GameOver.height/4));
        image(GameOver, 110 , 220, (GameOver.width/4), (GameOver.height/4));
        image(GameOver, 360 , 220, (GameOver.width/4), (GameOver.height/4));

        //sad koala checkerboard
        image(lostlife, 250 , 0, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 500 , 0, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 0 , 0, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 250 , 200, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 500 , 200, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 0 , 200, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 125 , 100, (lostlife.width/2), (lostlife.height/2));
        image(lostlife, 375 , 100, (lostlife.width/2), (lostlife.height/2));

        //Reload suggester
        textSize(10);
        stroke(255);
        fill(255);
        text("TRY TO SAVE PEEWIE", 10, 150);
        image(reload, 50, 160, (reload.width/15), (reload.height/15));
        textSize(9);
        text("GIVE UP ON PEEWIE", 505, 150);
        image(redX, 535, 160, (redX.width/10), (redX.height/10));
        }

    //accelerate koala with gravity
    koalaDy = koalaDy + .8;

    //draw koala
    //face
    fill(0);
    ellipse(koalaX, koalaY - 20, 20, 20);

    //legs
    noStroke();
    fill(157, 165, 178);
    ellipse(koalaX - 7, koalaY + 4, 15, 30);
    ellipse(koalaX + 7, koalaY + 4, 15, 30);

    //arms
    fill(142, 139, 142);
    ellipse(koalaX - 14, koalaY, 10, 20);
    ellipse(koalaX + 14, koalaY, 10, 20);

    //koala head
    noStroke();
    fill(157, 165, 178);
    ellipse(koalaX, koalaY - 20, 55, 50);

    //ears
    fill(157, 165, 178);
    ellipse(koalaX - 20, koalaY - 40, 25, 25);
    ellipse(koalaX + 20, koalaY - 40, 25, 25);

    //eyes
    fill(255);
    ellipse(koalaX - 15, koalaY - 20, 15, 15);
    ellipse(koalaX + 15, koalaY - 20, 15, 15);

    //pupils
    fill(0);
    ellipse(koalaX - 15, koalaY - 19, 8, 8);
    ellipse(koalaX + 15, koalaY - 19, 8, 8);

    //eye lids
    stroke(0);
    fill(206, 159, 204);
    arc(koalaX - 15, koalaY - 20, 15, 15, PI, 0, CHORD);
    arc(koalaX + 15, koalaY - 20, 15, 15, PI, 0, CHORD);

    //nose
    fill(0);
    arc(koalaX, koalaY - 10, 10, 25, PI, 0);

    //mouth
    fill(206, 159, 204);
    arc(koalaX, koalaY - 7, 7, 7, 0, PI, CHORD);

    //ear pink
    fill(206, 159, 204);
    noStroke();
    ellipse(koalaX - 20, koalaY - 40, 15, 15);
    ellipse(koalaX + 20, koalaY - 40, 15, 15);
    }


function keyPressed() {
    if (keyCode == UP_ARROW){
    koalaDy = -10;
    }
return false;
    }

Image Citations

sad koala image http://s95.photobucket.com/user/lilo19951995/media/34533.gif.html

obama holding koala http://www.vox.com/xpress/2014/11/15/7226815/barack-obama-koala

cacti – from Steve the Jumping Dinosaur Chrome loading game

Game Over image is from Pac Man

angel wings – http://www.shutterstock.com/pic-205797616/stock-vector-angel-wings-with-golden-halo-hovering-in-the-dark-wings-and-golden-halo.html

heaven background -http://weknowyourdreams.com/heaven.html

 

Sarita Chen – Final Project

For my project I made an interactive character that responds to 3 prompts. Because my major interest in animation is 2D animation, I really enjoyed the walking assignment we did with the walking frames and getting the character to walk and follow the mouse. I wanted to base my project on that assignment so I drew the image frames and animated them using code. The character is Lance from Voltron: Legendary Defender which is a Netflix only series that I watched over the summer and really enjoyed :).

sketch

var waveFrames = [];
var laughFrames = [];
var complimentFrames = [];
var currentwaveFrame = 0;
var currentlaughFrame = 0;
var currentcomplimentFrame = 0;
var startIMG;
var waveImages;
var laughImages;
var complimentImages;


function preload(){

	startIMG = loadImage("http://i.imgur.com/mALMPDf.jpg");


	waveImages = [];
	waveImages[0] = ('http://i.imgur.com/oQGI281.jpg');
	waveImages[1] = ('http://i.imgur.com/1NBmtWx.jpg');
	waveImages[2] = ('http://i.imgur.com/EZx2syw.jpg');
	waveImages[3] = ('http://i.imgur.com/nA7ZuKG.jpg');

	for(var i = 0; i<4; i++) {
		waveFrames[i] = loadImage(waveImages[i]);
	}			
	

	laughImages = [];
	laughImages[0] = ('http://i.imgur.com/CWnkxF8.jpg');
	laughImages[1] = ('http://i.imgur.com/0i6DQam.jpg');
	laughImages[2] = ('http://i.imgur.com/CWnkxF8.jpg');

	for (var l = 0; l<3; l++){
		laughFrames[l] = loadImage(laughImages[l]);
	}

	complimentImages = [];
	complimentImages[0] = ('http://i.imgur.com/odBxDz4.jpg');
	complimentImages[1] = ('http://i.imgur.com/9zZDtl2.jpg');
	complimentImages[2] = ('http://i.imgur.com/odBxDz4.jpg');

	for (var h = 0; h<3; h++){
		complimentFrames[h] = loadImage(complimentImages[h]);
	}

}

function setup() {
    createCanvas(600, 600);
    frameRate(8);

    
   
}   

function draw() {

	image(startIMG,0,0,600,600);

	currentwaveFrame = currentwaveFrame + 1;
	if (currentwaveFrame > 3) {
		currentwaveFrame = currentwaveFrame - 3;
	}

	if (keyIsPressed) {
		if ((key == 'h') || (key == "H")) {
			
			image(waveFrames[currentwaveFrame],0,0,600,600);
			
			
		}

	}
	
	currentlaughFrame = currentlaughFrame + 1;
	if (currentlaughFrame > 2) {
		currentlaughFrame = currentlaughFrame - 2;
	}

	if (keyIsPressed) {
		if ((key == 'l') || (key == "L")) {
			
			image(laughFrames[currentlaughFrame],0,0,600,600);
			
			
		}
	}

	currentcomplimentFrame = currentcomplimentFrame + 1;
	if (currentcomplimentFrame > 2) {
		currentcomplimentFrame = currentcomplimentFrame - 2;
	}

	if (keyIsPressed) {
		if ((key == 'c') || (key == "C")) {
			
			image(complimentFrames[currentlaughFrame],0,0,600,600);
			
			
		}
	}


}

Grace Cha – Final Project

For my final project, I created a looping coral reef animation that shows different colors and suttle delights of underwater imagination.  I focused on the use of simple shapes , use of fun, moving recursion seweed trees, different opacities, and similar color pallete.

There are many things moving: 4 moving recusion trees, fish, and bubbles.

 

sketch

//Grace Cha
//section C
//heajinc@andrew.cmu.edu
//FINAL PROJECT

var swordFish = [];
var Bubbless = [];
var SCALE = 0.01;

function setup() {
    createCanvas(600, 600);
    for (var i=0; i<5; i++) {                        //initial placement of swordFishs
        var swordFishX = random(width);
        var swordFishY = random(100, 500);
        swordFish[i] = makeswordFish(swordFishX, swordFishY);
    }

    for (var i=0; i<3; i++) {                      //initial placement of Bubbless
        var BubblesX = random(width);
        var BubblesY = random(height);
        Bubbless[i] = makeBubbless(BubblesX, BubblesY);
    }
    //frameRate(10)    
}

function draw() {
    
    angle = 10 * (noise(millis() / 2000) - 0.5);
    angle1 = 20 * (noise(millis() / 3000) - 0.5);
    angle2 = 30 * (noise(millis() / 5000) - 0.5);
    angle3 = 10 * (noise(millis() / 7000) - 0.5);

    background("#CAE0F4");
    push();
    fill("#E34E54")
    rect(0, 0, width, height/3);
    pop();

    Sky(0, 0, width, height);

    showBubbless();
    deleteBubbless();
    makeNewBubbless();


    push();
    translate(400,height + 170,100); 
    drawBranch3(0, 80);
    pop();

    beginShape();
    fill("#5FAEB6");
    curveVertex(240, 521);
    curveVertex(240, 521);
    curveVertex(305, 450);
    curveVertex(400, 416);
    curveVertex(502, 559);
    curveVertex(468, 620);
    curveVertex(263, 620);
    curveVertex(240, 521);
    curveVertex(240, 521);
    endShape();


    push();
    translate(130,height + 50); 
    drawBranch2(0, 50);
    pop();

    beginShape();
    noStroke();
    fill("#51A0AA");
    curveVertex(0,359);
    curveVertex(0,359);
    curveVertex(143,452);
    curveVertex(552,614);
    curveVertex(0, height);
    curveVertex(0, height);
    endShape();

    beginShape();
    fill("#368692");
    curveVertex(0, 390);
    curveVertex(0,390);
    curveVertex(119,488);
    curveVertex(346, 604);
    curveVertex(0, height);
    curveVertex(0, height);
    endShape();

    showswordFish();
    deleteswordFish();
    makeNewswordFish();

    

    push();
    translate(200, height + 50); 
    rotate(radians(300));
    drawBranch(0, 20,90);
    pop();

    

    


    
    beginShape();
    fill("#0D5D6D");
    curveVertex(0,600);
    curveVertex(0,600);
    curveVertex(0, 219);
    curveVertex(34,238);
    curveVertex(96, 188);
    curveVertex(109, 201);
    curveVertex(54, 289);
    curveVertex(66, 368);
    curveVertex(127, 501);
    curveVertex(114, 536);
    curveVertex(121, 564);
    curveVertex(148, 527);
    curveVertex( 166, 600);
    curveVertex(0,600);
    curveVertex(0,600);
    endShape();


    push();
    translate(470,height -35,100); 
    rotate(radians(300));
    drawBranch1(0, 10,100);
    pop();

    beginShape();
    fill("#0D5D6D");
    curveVertex(397 +68,0);
    curveVertex(397+68,0);
    curveVertex(388+68,14);
    curveVertex(403+68, 47);
    curveVertex(383+68, 79);
    curveVertex(403+68, 147);
    curveVertex(443+68, 131);
    curveVertex(474+68, 176);
    curveVertex(449+68, 190);
    curveVertex(513+68, 318);
    curveVertex(481+68, 411);
    curveVertex(502+68, 620);
    curveVertex(551+68, 620);
    curveVertex(535+68, -9);
    curveVertex(397+68,0);
    curveVertex(397+68,0);
    endShape();
    
}


function drawBranch(depth, len, color) {
	stroke(75, 194, color % 255);
	
	strokeWeight(1);
	fill("#11153D");
	ellipse(70, 70,-len/4, -len/3);
    
    push();
    translate(0, -len);
    drawTree(depth + 1, len, color);
    pop();
}

function drawBranch1(depth, len, color) {
	stroke(0, 81, color % 255, 60);
	fill(227,78,84, 40);
    ellipse(0, 50,-len , -len * 2);
    ellipse(50, 50,-len , -len * 2);
    push();
    translate(0, -len);
    drawTree1(depth + 1, len, color);
    pop();
}

function drawBranch2(depth, len) {
    
    stroke(76,90,39, 60);
    fill(207,243,90,50);
    ellipse(50, 0,-len/5, -len)
    push();
    translate(0, -len);
    drawTree2(depth + 1, len);
    pop();
}

function drawBranch3(depth, len, color) {
    stroke(13, 93, 109, 80);
    strokeWeight(1);
    fill(13, 93, 109, 80);
    ellipse(100, 100,-len/12, -len/12)
    line(30, 0, 30, -len);
    push();
    translate(0, -len);
    drawTree3(depth + 1, len, color);
    pop();
}




function drawTree(depth, len, color) {
    if (depth < 8) {
        rotate(radians(-10 + angle));
        drawBranch(depth, len, color  + 50);
        rotate(radians(20));
        drawBranch(depth, len, color + 50);
    }
}

function drawTree1(depth, len, color) {
    if (depth < 8) {
        rotate(radians(-10 + angle1));
        drawBranch1(depth, len, color  + 50);
        rotate(radians(20));
        drawBranch1(depth, len, color + 50);
    }
}

function drawTree2(depth, len) {
    if (depth < 8) {
        rotate(radians(-10 + angle2));
        drawBranch2(depth, len);
        rotate(radians(20));
        drawBranch2(depth, len);
    }
}

function drawTree3(depth, len) {
    if (depth < 8) {
        rotate(radians(-10 + angle3));
        drawBranch3(depth, len);
        rotate(radians(20));
        drawBranch3(depth, len);
    }
}



function Sky(x, y, w, h) {
    //Draws the gradient sky
    var c1, c2;
    // c1 = color("#8443FE");
    // c2 = color("#03FCCA");
    c1 = color("#4BE1C0");
    c2 = color("#237B8E");
    for (var i = y; i <= y + h; i++) {
        var inter = map(i, y, y + h, 0, 1);
        var c = lerpColor(c1, c2, inter);
        stroke(c);
        line(x, i, x + w, i);
    }
}

function showswordFish() {                                      //this makes the swordFish move left
    for(var i=0; i<swordFish.length; i++) {
        swordFish[i].fly();
        swordFish[i].display();
    }
}

function deleteswordFish() {                                    //deletes swordFish that disappear from sight
    var swordFishToKeep = [];
    for (var i=0; i< swordFish.length; i++) {
        if(swordFish[i].x <0) {
            swordFishToKeep.push(swordFish[i]);
        }
    }
}

function makeNewswordFish() {                                   //creates more swordFish coming from left
    var newswordFishLiklihood =0.03
    if (random(0,1) < newswordFishLiklihood) {
        swordFish.push(makeswordFish(650, random(100, 500)));
    }
}
function swordFishFly() {
    this.x += this.speed;
}

function swordFishDisplay() {                       //makes graphic elements of the swordFish
    
    push();
    translate(this.x, this.y);
    stroke(243, 239, 244);
    // strokeWeight(1);
    // fill(255, 220, 98);
    
    strokeWeight(3); 
    fill("#F9F7CB");
    stroke("#F9F7CB");  //makes swordswordFish nose
    line(12,25,29,25);


    fill("#83CFC8");
    stroke("#83CFC8");
    
    triangle(80,26,86,12,86,38);
    fill("#83CFC8");
    stroke("#83CFC8");
    triangle(63,31,72,27,73,35);

    beginShape();
    curveVertex(41,20);
    curveVertex(41,20);
    curveVertex(41,11);
    curveVertex(48,9);
    curveVertex(54,10);
    curveVertex(54, 14);
    curveVertex(58, 12);
    curveVertex(59, 17);
    curveVertex(64, 14);
    curveVertex(64, 22);
    curveVertex(41,20);
    curveVertex(41,20);
    endShape();

    
    beginShape();
    fill("#D3CD24");
    stroke("#D3CD24");
    curveVertex(29,25);
    curveVertex(29,25);
    curveVertex(46,17);
    curveVertex(83,26);
    curveVertex(45,36);
    curveVertex(29,25);
    curveVertex(29,25);
    
    endShape();

    beginShape();
    fill("#F9F7CB");
    stroke("#F9F7CB");
    curveVertex(46,17);
    curveVertex(46,17);
    curveVertex(46,25);
    curveVertex(83,26);
    curveVertex(46,17);
    curveVertex(46,17);
    endShape();

    fill(0);
    noStroke();
    stroke(0);
    ellipse(41,25,5,5);           //makes eyes
    pop();
}

function makeswordFish(birthLocationX, birthLocationY) {
    var swordFish = {x : birthLocationX,
                y : birthLocationY,
                speed : -random(2, 4),
                fly : swordFishFly,
                display : swordFishDisplay}
    return swordFish;
}


function showBubbless() {                                      //this makes the Bubbless move up
    for(var i=0; i<Bubbless.length; i++) {
        Bubbless[i].move();
        Bubbless[i].display();
    }
}

function deleteBubbless() {                                    //deletes Bubbless that disappear from sight
    var BubblessToKeep = [];
    for (var i=0; i< Bubbless.length; i++) {
        if(Bubbless[i].y >600) {
            BubblessToKeep.push(Bubbless[i]);
        }
    }
}

function makeNewBubbless() {                                   //creates more Bubbless coming down
    var newBubblesLiklihood =0.05
    if (random(0,1) < newBubblesLiklihood) {
        Bubbless.push(makeBubbless(random(width), 600));
    }
}

function BubblesMove() {                                      //sets the move property of Ballons
    this.y += this.speed;
}

function BubblesDisplay() {
    push();
    translate(this.x, this.y);
    fill(255,50);
    ellipse(0, 0, 10, 10);
    pop();


}

function makeBubbless(birthLocationX, birthLocationY) {
    var Bubbles = {x : birthLocationX,
                   y : birthLocationY,
                   speed : -random(1, 6),
                   move : BubblesMove,
                   display : BubblesDisplay}
    return Bubbles;
}





Final Project -sehenry

For my final project I decided to create a two player game. I like anime so I wanted to have Goku from Dragonball Z fight Naruto from Naruto. After I tested out different types of game play, I decided to make the game a battle of who can tap the fastest. The player on the left (Naruto) needs to press the “a” key as fast as they can while the person on the right needs to press the “l” key as fast as they can. As each person presses their respective buttons, each character’s “Battle Bar” should increase. The objective of the game is to have the largest bar by the end of the time limit. If your character wins, the character shall initiate their ultimate move. Unfortunately, I was unable to upload the sketch successfully for some reason even after I changed the .mp3 location to WordPress but I still wanted everyone to be able to see how my code looks as well as the result. I included some screenshots to show a clearer view of how my project looks. The video links are found under them. The first link leads to a video that shows Goku winning, and the second link shows a video of Naruto winning. I tried doing a screen record to make it clearer, but it just slowed my computer down so I am sorry for the bad quality.

GOKU WINS SCREENSHOTS
screen-shot-2016-12-09-at-3-10-04-pm

screen-shot-2016-12-09-at-3-10-12-pm

NARUTO WINS SCREENSHOTS

screen-shot-2016-12-09-at-3-10-32-pm

screen-shot-2016-12-09-at-3-10-34-pm

screen-shot-2016-12-09-at-3-10-38-pm

screen-shot-2016-12-09-at-3-10-41-pm

screen-shot-2016-12-09-at-3-10-48-pm
VIDEO LINKS

Goku Wins

Naruto Wins

jmmedenb-final project

jmmedenb-final

//Jessica Medenbach
//jmmedenb@andrew.cmu.edu
//Tuesdays @ 1:30pm
//Final Project 

var myCaptureDevice;
var img;
var Point;
var r, g, b;
var change;

function setup() {
    createCanvas(640, 550);
    myCaptureDevice = createCapture(VIDEO);
    myCaptureDevice.size(640, 550); 
    myCaptureDevice.hide(); 
    var y = 20;
    change = .25;
    size1 = 200;
    size2= width/4;
    size3=height/2;
    
    
}


//--------------------------------------------------------------------
function draw() {
    background(b,r,g);
    myCaptureDevice.loadPixels(); 
    image(myCaptureDevice, 0, 0); 
    
   
    strokeWeight(3);
    noFill();
    ellipse(width/2,height/2,size2,height/4);
    ellipse(width/2,height/2,width-10,size3);
    ellipse(width/2, height/2,200,size1); 
    
    
    var turtle = makeTurtle(width/2, height/2);
   turtle.penDown();
    
    for (var i = 0; i < 250; i++) {
        turtle.forward(5);
        turtle.right(45)
        turtle.forward(5);
        turtle.right(45);
        turtle.forward(5);
        turtle.right(45);
        turtle.forward(5);
        turtle.right(45)
        turtle.forward(5);
        turtle.right(45);
        turtle.forward(5);
        turtle.right(45);
        turtle.forward(5);
        turtle.right(45);
        turtle.forward(5);


            turtle.penUp();
           
            
            turtle.right(137.507764/2.0);
            turtle.forward(i/change);
            turtle.right(137.507764/10);
            

          

            

            turtle.penDown();
            
    
          }


     change++;

          


         
  
}

function mousePressed() {
  
  var d = dist(mouseX, mouseY, 360, 200);
  if (d < 100) {
    
    r = random(255,0);
    g = random(255,120);
    b = random(255);
    change = random(.25,.5,2,4,6,8);
    move = random(2,10);
    size1 = random(200,400,600);
    size2=random(width/2,width,width/6);
    size3=random(height/2,height/4,height-50);

 

    


  }


}




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;}

For my final project, coming from the performance and media design program, I wanted to create something that could be used in performance. Therefore, I decided I would want the ability to use live camera since that is something we use quite a bit in my department and an interactive element that the performer or controller could trigger during the performance. I chose to make a spiraling pupil on top of the live camera image as an opportunity to play with turtles and the mouse click manipulating the objects and imagery over the live camera. This was a good exercise for me because it got me to think more about the combination of all these elements that I’ve learned in this class and how I could apply these new skills to other classes and projects I will work on.

The idea would be that during the performance the camera would be on the performer and then the controller would click to play with the turtles spinning and the shape of the eye changing.

 

Final Project

C-major Palette

/*Emma Shi
eyshi@andrew.cmu.edu
Section B
Final Project
*/

var midC;
var D;
var E;
var F;
var G;
var A;
var B;
var hiC;
var pad = 38;
var space = 75;
var col = 0;
var thickness = 1;
var rD = 7;
var gD = 80;
var bD = 6;
var rE = 243;
var gE = 170;
var bE = 0;
var rF = 83;
var gF = 38;
var bF = 0;
var rA = 256;
var gA = 246;
var bA = 227;
var rB = 46;
var gB = 39;
var bB = 118;
var eraser;

function preload(){
  A = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/A.mp3');
  B = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/B.mp3');
  midC = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/middleC.mp3');
  hiC = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/highC.mp3');
  D = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/D.mp3');
  E = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/E.mp3');
  F = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/F.mp3');
  G = loadSound('https://courses.ideate.cmu.edu/15-104/f2016/wp-content/uploads/2016/12/G.mp3');
}
function setup(){
  createCanvas(800, 300);
  background(0);
}

function draw(){
  noStroke();
  middleC();
  noteD();
  noteE();
  noteF();
  noteG();
  noteA();
  noteB();
  highC();
  paint();
  eraser = createEraser();

if (mouseIsPressed) {
  if ((10 <= mouseX) & (mouseX <= 70) && (8 <= mouseY) && (mouseY <= 70)){
  col = "red";//if user presses mouse within the upper right red circle, the stroke is red
  midC.play();
} else if ((10 <= mouseX) & (mouseX <= 70) && (80 <= mouseY) && (mouseY <= 142)){
  col = color(rE, gE, bE);//if user presses mouse within the mid right yellow circle, the stroke is yellow
  E.play();
} else if ((10 <= mouseX) & (mouseX <= 70) && (155 <= mouseY) && (mouseY <= 220)){
  col = "white";//if user presses mouse within the mid right white circle, the stroke is white 
  G.play();
} else if((10 <= mouseX) & (mouseX <= 70) && (230 <= mouseY) && (mouseY <= height-8)){
  col = color(rB, gB, bB);//if user presses mouse within the bottom right blue circle, the stroke is blue
  B.play();
} else if ((80 <= mouseX) & (mouseX <= 140) && (8 <= mouseY) && (mouseY <= 70)){
  col = color(rD, gD, bD);//if user presses mouse within the upper left green circle, the stroke is green
  D.play();
} else if ((80 <= mouseX) & (mouseX <= 140) && (80 <= mouseY) && (mouseY <= 142)){
  col = color(rF, gF, bF);//if user presses mouse within the mid left brown circle, the stroke is brown
  F.play();
} else if ((80 <= mouseX) & (mouseX <= 140) && (155 <= mouseY) && (mouseY <= 220)){
  col = color(rA, gA, bA);//if user presses mouse within the mid left beige circle, the stroke is beige
  A.play();
} else if ((80 <= mouseX) & (mouseX <= 140) && (230 <= mouseY) && (mouseY <= height-8)){
  col = "red";//if user presses mouse within the bottom left red circle, the stroke is red
  hiC.play();
} else if ((120 <= mouseX) & (mouseX >= 160) && (50 <= mouseY) && (mouseY <= 70)){
  col = 0;
}
  push();
  stroke(col);
  strokeWeight(thickness);
  line(pmouseX, pmouseY, mouseX, mouseY);
  pop();
}

  fill("white");
  textStyle(NORMAL);
  text('Click on a circle and drag your cursor to draw', 160, 20);
  text('Press A to increase brush size', 160, 32);
  text('Press B to decrease brush size', 160, 44);
}

function middleC(){
  fill("red");
  ellipse(40, pad, 60, 60);//upper right red circle
}

function noteD(){
  fill(rD, gD, bD);
  ellipse(110, pad, 60, 60);//upper left green circle
}

function noteE(){
  fill(rE, gE, bE);
  ellipse(40, pad + space, 60, 60);//mid right yellow circle
}

function noteF(){
  fill(rF, gF, bF);
  ellipse(110, pad + space, 60, 60);//mid left brown circle
}

function noteG(){
  fill("white");
  ellipse(40, pad + 2*space, 60, 60);//mid right white circle
}

function noteA(){
  fill(rA, gA, bA);
  ellipse(110, pad + 2*space, 60, 60);//mid left off-white circle
}

function noteB(){
  fill(rB, gB, bB);
  ellipse(40, height-pad, 60, 60);//bottom right blue-violet circle
}

function highC(){
  fill("red")
  ellipse(110, height-pad, 60, 60);//bottom left red circle
}

function paint(){
  line(pmouseX, pmouseY, mouseX, mouseY);//allows user to draw
}

function createEraser() {
  noFill();
  stroke("white");
  rect(160, 50, 40, 20);

  noFill();
  text('Erase', 165, 65);//creates Erase button
}

function keyTyped(){
  if (key == 'a'){
    thickness += 0.5;//strokeweight increases by 0.5 if user presses a
  } else if (key == 'b'){
    thickness -= 0.5;//strokeweight decreases by 0.5 is user presses b
  }
}

I originally wanted to create a program that would essentially create a “music video” for a song, and have notes in the song represented through colors that I associate with specific notes (I have perfect pitch, and perhaps as a result, synesthesia with music notes and color). However, I ended up making a different project in the end, but still wanted to incorporate audiovisual elements that reflect my own experiences in having synesthesia and perfect pitch.

In essence, this project is a simple drawing tool where there is a given color palette; specifically, one that represents the C-major scale for me. Each color in the palette references a different note — D is represented by dark green, E is represented by mustard yellow, F is represented by brown, G is represented by white, A is represented by off-white, B is represented by blue-violet, and you may notice that middle C and high C are represented by the same red color (I don’t make a distinction in color between the same note in different octaves). Every time the user draws, the corresponding note is played.

Although these aren’t the prettiest of colors, these are pretty much the exact shades that I refer to in my mind when I think of these music notes, and I believe there is some natural logic to them. For example, if you take a C-major chord (C, E, G), it translates to red, yellow, and white. These are all warm colors. However, if you take a G-major chord (G, B, D), it translate to white, blue-violet, and green. These are all cool colors. Additionally, the notes G, A, and F are all “neutral” colors (white, off-white, brown), because they can be matched up with more chords, and thus more color combinations. I didn’t take music theory back in the day, so I am probably using the wrong terms, but hopefully you get the idea.

Through this project, I hope that viewers can get some perspective of what it is like to have synesthesia for music and color.