yushano_Final Project

yushano-12
sketch

//Isabella Ouyang
//Section A
//yushano@andrew.cmu.edu
//Assignment-12

var choice = [];
var trees = [];
var snowmen = [];
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var thespeed = 1;
var songs=[];
var textX = 0;
var playMusic = false;

function preload() {
   var song1 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/all-i-want-for-christmas-is-you.mp3");
   var song2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/ChristmasIsntChristmas.mp3");
   var song3 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/jingle-bell.mp3");
   var song4 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/silent-night.mp3");
   songs.push(song1);
   songs.push(song2);
   songs.push(song3);
   songs.push(song4);
   imgplus = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/plus.jpg");
   imgmusic = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/music.jpg");
   imgminus = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/minus.jpg");
}

function setup() {
    createCanvas(480, 240); 
    frameRate(5);
}

function draw() {
    background(205,233,233); 

    // display the background
    stroke(0);
    strokeWeight(1);
    drawMountain();
    displayHorizon();

    // draw objects
    // Ferris Wheel
    // update the rotation
    drawFerrisWheel();
    thespeed += 0.5;
    
    // Trees
    updateAndDisplayTrees();
    addNewTreesWithSomeRandomProbability();

    // Snowmen
    updateAndDisplaySM();
    addNewSMWithSomeRandomProbability();

    // snow
    drawSnow();

    // window frame
    strokeWeight(40);
    stroke(230);
    line(0,0,0,height);
    line(width,0,width,height);

    // load buttons
    image(imgplus,width-20,10);
    image(imgmusic,0,10);
    image(imgminus, width-20, 40);

}

function drawFerrisWheel(){
    strokeWeight(2);
    noFill();
    
    // draw the structure
    noStroke();
    fill(200);
    rect(width/2-2,height/2,4,85);
    fill(150);
    ellipse(width/2,height/2,10);
    rect(width/2-20,height/2+80,40,5);

    // draw the curve
    push();
    noFill();
    translate(width / 2, height / 2);
    rotate(thespeed);
    // the curve inside
    for (var i = 0; i < 8; i++) {
        // calculate the gradient of color
        var r = 207 - (207 - 152) / 6 * i;
        var g = 171 - (171 - 92) / 6 * i;
        var b = 177 - (177 - 103) / 6 * i;
        stroke(r, g, b);
        drawTetracuspidCurve();    
        rotate(PI / 14);
    }
    pop();   
    
}

function drawTetracuspidCurve(){
    var nPoints = 400;
    var x;
    var y;
    var a = 75;
    var ph = 0;
    noFill();
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        x = a / 4 * (3*cos(t) -  cos(ph + 3 * t));
        y = a / 4 * (3*sin(t) +  sin(ph + 3 * t));
        vertex(x, y);
        push();
        // draw the cart at each peak
        if (x == 0 || y == 0) {
            for (var i = 0; i < 4; i++) {
                fill(204, 229, 255);
                rect(x + 35, y + 3, 10, 10);
                rotate(TWO_PI / 4);
            
            }    
        }
        pop();
    }
    endShape(CLOSE);    
}

function drawMountain() {
    fill(255); 
    noStroke();
    beginShape(); 
    vertex(0, 200);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 30, 200);
        vertex(x, y);    
    }
    vertex(width, 200);   
    endShape();
}

function drawSnow() {
    var xS = 10;
    var yS;
    for (var i = 0; i < 50; i++) {
        yS = 0;
        for (var j = 0; j < 25; j++){
            stroke(255);
            strokeWeight(0.5);
            //noStroke();
            ellipse(xS, yS, 2);
            line(xS - 3, yS - 3, xS + 3, yS + 3);
            line(xS + 3, yS - 3, xS - 3, yS + 3);
            line(xS, yS - 3, xS, yS + 3);
            yS += random(10, 20);
        }
        xS += random(8, 25);    
    }
}

    
// DRAW THE CHRISTMAS TREE
function updateAndDisplayTrees() {
    // Update the tree's positions, and display them.
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function addNewTreesWithSomeRandomProbability() {
    // With a very tiny probability, add a new tree to the end.
    var newTreeLikelihood = 0.1; 
    if (random(0,1) < newTreeLikelihood) {
        var theX = random(20, width-20);
        trees.push( makeTree(theX,0) );
    }
}


// method to update position of tree every frame
function treeMove() {
    this.y += this.speed;
}
    

// draw the tree and some ornaments
function treeDisplay() { 
    stroke(0); 
    push();
    translate(this.x, this.y);
    // tree
    strokeWeight(0.5);
    fill(0, 102, 51);
    triangle(0, this.y + 30, this.breadth / 2, this.y, this.breadth, this.y + 30); 
    fill(108,22,22)
    rect(this.breadth / 2 - 5, this.y + 30, 10, this.treeH / 3);
    // ornaments
    var x0 = this.breadth / 6;
    for (var i = 0; i < 5; i++){
        fill(255, 0, 0);
        ellipse(x0, this.y + 25, 5);
        x0 += this.breadth / 6;
    }
    pop();
}


function makeTree(birthLocationX, birthLocationY) {
    var tree = {x: birthLocationX, 
                y: birthLocationY,
                breadth: 30,
                speed: 2.0,
                treeH: 10,
                move: treeMove,
                display: treeDisplay}

    return tree;
}

// DRAW THE SNOWMAN
function updateAndDisplaySM() {
    // Update the tree's positions, and display them.
    for (var i = 0; i < snowmen.length; i++){
        snowmen[i].move();
        snowmen[i].display();
    }
}

function addNewSMWithSomeRandomProbability() {
    // With a very tiny probability, add a new tree to the end.
    var newSMLikelihood = 0.1; 
    if (random(0, 1) < newSMLikelihood) {
        var theX = random(20, width - 20);
        snowmen.push(makeSnowman(theX,0));
    }
}


// method to update position of sm every frame
function smMove() {
    this.y += this.speed;
}
    

// draw the snowman 
function smDisplay() { 
    stroke(0); 
    push();
    translate(this.x, this.y);
    // tree
    fill(245);
    strokeWeight(0.8);
    ellipse(this.x, this.y + 8, 13);
    ellipse(this.x, this.y, 8);
    // ornaments
    fill(255, 0, 0); // the hat
    triangle(this.x - 2, this.y - 4, this.x, this.y - 7, this.x + 2, this.y - 4);
    fill(0); // eyes
    ellipse(this.x - 2, this.y, 1);
    ellipse(this.x + 2, this.y, 1);
    fill(255, 128, 0);
    triangle(this.x - 1, this.y + 2, this.x + 1, this.y + 2, this.x, this.y + 6);
    pop();
}


function makeSnowman(birthLocationX, birthLocationY) {
    var snowman = {x: birthLocationX, 
                y: birthLocationY,
                speed: 2.0,
                move: smMove, 
                display: smDisplay}

    return snowman;
}

// Draw the soil 
function displayHorizon(){
    stroke(0);
    fill(0, 51, 102);
    rect (0, height - 40, width, 40);
}

// Interaction with user
function mousePressed() {
    // button to play the music
    if (mouseX < 20 & mouseY < 30 && mouseY > 10) {
        playMusic = !playMusic;
    }
    if ( playMusic == false ) {
        for (var i = 0; i < songs.length; i++ ){
            if (songs[i].isPlaying()) {
                songs[i].stop();
            }
        }
    } else {
        songs[floor(random(1,5))].play();
    }
 

    // button to add more Christmas trees or snowmen
    if (mouseX > width-20 & mouseX < width && mouseY < 30 && mouseY > 10) {
        var choice = ceil(random(0,2));
        if (choice == 1) {
            trees.push(makeTree(random(20, width - 20),0));
        } else {
            snowmen.push(makeSnowman(random(20, width - 20),0));
        }
    }
    // button to get rid of some Christmas trees or snowmen
    if (mouseX > width-20 & mouseX < width && mouseY < 60 && mouseY > 40) {
        var choice = ceil(random(0,2));
        if (choice == 1) {
            trees.pop(makeTree(random(20,width-20),0));
        } else {
            snowmen.pop(makeSnowman(random(20,width-20),0));
        }

    }
}

My final project is an interactive animation which I try to mimic the Christmas scene. I integrate the use of curve (string art), music and images into this project. The center is a ferris wheel that is coded by curves. The Christmas trees, snowmen and snow are also coded instead of using images. The mountain behind are winter snow mountain.

Instruction:

If you press the music button on the left, it will play a random music. If you click it again, it stops. If you click it again then, it plays next random song. If you press the plus or minus button on the right, there will be more or less Christmas trees or snowmen that are falling from the sky.

hschung-Final-Project

sketch

//Heidi Chung
//hschung
//Section A
//Final-Project

var clouds = [];
var bobaY = 0; // height of boba
var bobaDy = 0; // the vertical velocity of boba
var offset = 0;
var themeSong; //variable for song to be played
var blush = 200; //variable to make boba change color and "blush"

function preload() {
  themeSong = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/bobasong.mp3");
  //preloading the song Boba Beach by Grynperet
}

function newcloud(px, py, pw) { //object for clouds
    return {x: px, y: py, w: pw};
}

function setup() {
    createCanvas(450, 400);
    clouds.push(newcloud(600, 200, 200));//adding a new cloud
    themeSong.play(); //play the song
    amplitude = new p5.Amplitude(); //capturing the volume of the song
}

// compute the location of the right end of a cloud
function cloudRight(p) {
    return p.x + p.w;
}

// return the last cloud object
function cloudLast() {
    return clouds[clouds.length - 1];
}

function draw() {
    background(253, 225, 200);
    var bobaX = width / 2;
    drawGreeting(); //calling the greeting and its "shadow" to be drawn
    drawBoba(); //calling the boba to be drawn
      push();
      noStroke(); //multiple layers to achieve pleasant transparency
      fill(255, 99);//white sea foam
      rect(0, height - 70, width, 70);
      fill(177, 156, 217, 90);//lilac sea foam 2
      rect(0, height - 80, width, 80);
      fill(220, 200, 200, 90);//sea foam 3
      rect(0, height - 90, width, 90);
      fill(220, 200, 200);//solid background of sea
      rect(0, height - 60, width, 60);
      fill(177, 156, 217, 90);//the taro sea
      rect(0, height - 60, width, 60);
      pop();
    stroke(255);
    strokeWeight(3);
    var level = amplitude.getLevel();
    var cloudSize = map(level, 0, 1, 30, 50);
    //clouds' height wiggles in response to song volume
    for (var i = 0; i < clouds.length; i++) {
        var p = clouds[i];
        noStroke();
        fill(255); //white clouds
        ellipse(p.x - offset, p.y, p.w, cloudSize);
    }

    // if first cloud is offscreen to left, remove it
    if (clouds.length > 0 & cloudRight(clouds[0]) < offset) {
        clouds.shift();
    }
    // if last cloud is totally within canvas, make a new one
    if (cloudRight(cloudLast()) - offset < width) {
        var p = newcloud(cloudRight(cloudLast()), // start location
                            random(50, 320), // height of new cloud
                            140); // all clouds have width 140 for now
        clouds.push(p); //add to array of clouds
    }
    noStroke();
    // move the "landscape"
    // move and draw the "boba"
    //which cloud is current? linear search (!) through clouds
    var pindex = 0;
    while (cloudRight(clouds[pindex]) - offset + 20 < bobaX) {
        pindex += 1;
    }
    //now pindex is index of the cloud in the middle of canvas
    //find the cloud height
    var py = clouds[pindex].y;
    //if boba is above a cloud, fall toward it, but don't go past it
    if (bobaY <= py) {
        bobaY = min(py, bobaY + bobaDy); // change Y by Dy
    } else { // if we are below the cloud, fall to ground
      //to avoid this, once we are below a cloud, force Dy non-negative
      if (bobaDy < 0) {
          bobaDy = 0;
      }
      bobaY = min(height, bobaY + bobaDy);
    }
    //if the boba falls from a cloud, it will "jump" to the next cloud
    if (bobaY >= height) {
        bobaY = 0;
    }
    //move the "landscape"
    offset += 3;
    //accelerate boba with gravity
    bobaDy = bobaDy + 1;
}

function drawGreeting() {
  var level = amplitude.getLevel();
  var greetingSize = map(level, 0, 1, 25, 30); //control limits of greeting size
  for (i = 0; i < width; i++) {
    fill(210, 120, 120);
    textSize(greetingSize);
    text("welcome  to  boba  beach", width/5 + i, height/4 + i); //streaked greetings
  }
  fill(255, 196, 197); //light pink greeting
  strokeWeight(3);
  textSize(greetingSize);
  text("welcome  to  boba  beach", width/5, height/4);
}

function drawBoba() {
  var bobaX = width / 2;
  var level = amplitude.getLevel();
  var bobaSize = map(level, 0, 1, 35, 85); //control limits of boba size
  var eyeSize = map(level, 0, 1, 5, 10); //control limits of eye size
  //traits fluctuate in size depending on the song's volume.
  var mouthSize = map(level, 0, 1, 7, 15); //control limits of mouth size

  fill(blush - 100, 120, 120); //boba "blushes" when you make it jump by pressing any key
  noStroke();
  fill(230, 130, 140);
  ellipse(bobaX, bobaY - 20, bobaSize, bobaSize); //jumping boba
  fill(0);
  ellipse(bobaX - 7, bobaY - 20, eyeSize, eyeSize); //left eye
  ellipse(bobaX + 11, bobaY - 25, eyeSize, eyeSize); //right eye
  fill(120, 0, 32); //happy mouth
  arc(bobaX + 4, bobaY - 20, mouthSize + 3, mouthSize + 3, 0, PI + 50, CHORD);
}

function keyPressed() {
  bobaDy = -15; //velocity set to up when key is pressed
    if (blush === 200) { //changing the color of the boba
      blush = 255; //if the boba's R value is 200, and a key is pressed,
    } else {       //change the R value to 255, and vice-versa.
      blush = 200;
    }
}

For my final project, wanted to create a cute, simple, and clean animation with an interactive touchpoint- perhaps by pressing keys or clicking the mouse. My inspiration was to create something that brings the user a sense of delight. I wanted to animate with AfterEffects using the soundtrack “Boba Beach” and I attempted to over the summer, but didn’t finish, and that led me to want to create a cute thing for the final project. I was inspired by the delight and familiarity of platform games, and thought it would mesh well with my idea of having cute visuals that you can interact with if you so choose. I chose not to make the boba “die” when it falls off the clouds, like a classic platform game.

The jumping boba wiggles in size depending on the volume of the song, as do its eyes and mouth. The clouds passing by also wiggle. When you press any key, the boba will change color slightly and “blush” and it jumps as well. The greeting in the background also wiggles with the volume. I am pleased with the cute aesthetics and interaction I was able to make.

doodlings for composition ideating
I made these assets in Illustrator and had tried animating them with AfterEffects. This also served as color scheme inspiration.
screenshot: a little boba floating on a cloud above a sea of taro tea

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.

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.

sntong-Final-Project

This is a simple audio and visualization program that deals mainly with interaction of the keypad with music and geometric visualization. To start the program, press enter and play around with timing of sounds and visualization by pressing keys such as “W”,”A”,”S”,”D”, “I”, “J”, “K”, “L” that will work with the background music. Last but not least, have fun and explore different combination of keys to create cool visualizations.

sketch

// Scarlet Tong
//sntong@andrew.cmu.edu
// Final Project

// incrementally increase the x, y  parameter
var inc = 0.02;
// ze of each grid spacing
var scl = 48;
// rows and columns of the grid
var cols, rows;
// introducing a "time" parameter for the lines to move
var zoff = 0;
// variables the squares function will use
var topX;
var topY;
var topX1;
var topY1;
// difference variable that is used for the frames function below
var m = 0;

// declaring variables to store sound files
var backg;
var bass;
var chime;
var beat;
var popp;
// intializing variables that holds and stores Amplitude of the sound for
// the "sound wave" visualization
var amp;
var volhistory = [];
// to make sure sounds don't play and overlap with itself
var dJ = false;
// difference variable that the rings function uses
var step = 0;
// track click count to start the background music and other visualizations
var numClick = 0;
// difference variable used for the knitted function below
var column = 0;

function preload(){
  backg = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/background-1.wav");
  bass = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/bass.wav");
  chime = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/chimes.wav");
  beat = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/steady-beat.wav");
  popp = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pop.wav");
}

function setup() {
  createCanvas(480, 480);
  // define grid spacing for field function below
  cols = floor(width/scl);
  rows = floor(height/scl);
  // defining variables of for squares function
  topX = width/2;
  topY = height/2;
  topX1 = width/2;
  topY1 = height/2;
}

function draw() {
  background(0);
  // startup page for users before rest of the code runs
  if (numClick == 0) {
    // Ready? icon, press enter key to start
    fill(255);
    rect(200,200,80,80);
    textAlign(CENTER);
    fill(255,255,255,160);
    text("READY?",width/2,height/2-40);
    stroke(180,15,85,100);
    rect(210,245,60,20);
    text("PRESS",width/2,height/2);
    text("ENTER",width/2,height/2+20);
  }
   if (keyIsDown(13) & numClick == 0) {
    numClick +=1;
    // play background music and loop it
    backg.amp(0.5);
    backg.play()
    backg.loop();
    // variable that stores the values of amplitude of the music playing
    amp = new p5.Amplitude();
    stroke(255);
  } if (numClick == 1) {
    // draw the graph that changes based on amplitude of the music
      soundWave();
  }

    // if key "w" is pressed create a "random vector field" with low bass sound
  if (keyIsDown(87)) {
    field();
  }
    // if key "a" is pressed, separating squares with a drum sound
  if (keyIsDown(65)) {
    square();
  } else {
    topX= width/2;
    topY=height/2;
    topX1= width/2;
    topY1=height/2;
  }
  // if "s" is presssed, a series of "rings" will display along with chime sound
  if (keyIsDown(83)) {
    rings();
  }

  // if "d" is pressed, pattern of yellow dots start to appear with pop sound
  if (keyIsDown(68)) {
    pattern();
  }
  // if "i" is pressed a vizualization of corners moving apart
  if (keyIsDown(73)) {
    frames();
  }

  // if "j" is pressed, bars of orange and pink strips start to extend and overlap
  if (keyIsDown(74)) {
    knitted();
  }

  // if "k" is pressed, a set of three rotating shapes appears
  if (keyIsDown(75)) {
    triangles();
  }

  // if "l" is pressed, a grid of pink dots appears
  if (keyIsDown(76)) {
    for (var x = 0; x < width; x+=48) {
      for (var y = 0; y < height; y+=48) {
        fill(180,15,85,100,20);
        noStroke();
        ellipse(x+24+random(1),y+24+random(1),10,10);
      }
    }
  }
  // small text to help prompt users to use the keys to add sound or visual effects
  push();
  fill(100);
  noStroke();
  text("W",30,450);
  text("A   S   D",30,470);
  text("I",440,450);
  text("J   K   L",440,470);
  pop();

}

// assign sound to each key
  function keyPressed(){
    // if key "w" is pressed, play the low bass sound
    if (keyCode === 87) {
      bass.play();
      dJ = true;
    }
    // if key "s" is pressed, a small "chime" sound is played
    if (keyCode === 83) {
      chime.play();
      dJ = true;
    }
    // if "a" is pressed play the short drum sound
    if (keyCode === 65) {
      beat.play();
      dJ = true;
    }
    // if "d" is pressed, play pop sound
    if (keyCode === 68) {
      popp.play();
      dJ = true;
    }
  }

// graph the Amplitude of the sound
function soundWave(){
  // get Amplitude of sound and add it to the array
  var vol = amp.getLevel();
  volhistory.push(vol);
  stroke(255,255,255,170);
  noFill();
  push();
  // map the graph in the middle of the canvas
  translate(0,-height/2+40);
  beginShape();
  for (var i = 0; i < volhistory.length; i++) {
    // remap the values of the amplitude to fit within the canvas size
    var y = map(volhistory[i],0,1,height,0);
    strokeWeight(2);
    vertex(i,y);
    stroke(250,250,250,50);
    strokeWeight(1);
    // draw diagonal lines that help give a 3D sense
    line(i,y,-i,-y);
  }
  endShape();
  pop();
  if (volhistory.length> width) {
  // keep updating and shifting "old" graph backwards to draw new ones.
  volhistory.splice(0,1);
  }
}

//generate a vector field of swaying lines
function field (){
  var yoff = 0;
  // asgn a vector component to the grid that has x number of columns and y number of rows.
  for (var y = 0; y < rows+1; y++) {
    var xoff = 0;
    for (var x = 0; x < cols+1; x++) {
      // create random angle
      var angle = noise(xoff, yoff,zoff)* 40;
      // define angle as an vector to make the lines turn
      var v = p5.Vector.fromAngle(angle);
      xoff += inc;
      stroke(255);
      push();
      // tranlate lines to each intersection of the grid and draw it
      translate(x*scl+scl,y*scl);
      rotate(v.heading());
      strokeWeight(3);
      stroke(180,15,85,100,50);
      line(0,0,scl*2,0);
      pop();
    }
    yoff += inc;
    zoff += 0.00005;
  }
}


// draw two separating squares that move apart until they reach the edge of the canva
// before going back to the center of the canvas.
function square(){
  noStroke();
    // light red color
  fill(180,15,85,100);
  rectMode(CENTER);
  rect(topX1,topY1,200,200);
  // light orange color
  fill(215,122,97,100);
  rect(topX,topY,200,200)
  topX1+=1;
  topY1+=1;
  topX-=1;
  topY-=1;
  // reset squared to the middle of the canvas
  if (topX <80) {
    topX= width/2;
    topY=height/2;
    topX1= width/2;
    topY1=height/2;
  }
}

// make cirlces appear at a random rate to make a pattern
function pattern(){
  push();
  translate(width/2, height/2); // so that the curve is within the canvas
  beginShape();
  for(var i = 0; i < volhistory.length; i++){
    var theta = map(i,0,100,0,500);
    // give the randomly apparenting circles to make a pattern
    var a = map(volhistory[i], 0,1,-10,10);
    //Conchoid of de Sluze equation from Wolfram MathWorld
    var x = (1/cos(theta)+(a*cos(theta)))*cos(theta);
    var y = (1/cos(theta)+(a*cos(theta)))*sin(theta);
    noStroke();
    fill(215,122,97,100);
    //"polar array" the Conchoid from the center
    rotate(90);
    ellipse(x*20+random(0,1),y*20+random(0,1),4,4);
  }
  endShape(CLOSE);
  pop();
}

// draw spinning rings
function rings(){
  push();
  stroke(215,122,97);
  strokeWeight(5);
  strokeCap(SQUARE);
  arc(width/2,height/2,100,100,0-step,HALF_PI-step);
  strokeWeight(3);
  arc(width/2,height/2,80,80,QUARTER_PI-step,PI+HALF_PI-step);
  strokeWeight(2);
  arc(width/2,height/2,150,150,HALF_PI+QUARTER_PI+step,PI+HALF_PI+step);
  strokeWeight(1);
  arc(width/2,height/2, 200,200,0+step,PI+HALF_PI+step);
  // the variable makes each arc to change and rotate
  step+=0.1;
  pop();
}

function frames(){
  // setting up variable that governs the rate of which the corners move away
  if (m >= 0) {
    m+=0.5;
  } // if the displacement of the corners is more than 50 pixels, reset to 0
  if(m == 50) {
    m = 0;
  }
  // small frame
  stroke(255,255,255,150);
  strokeWeight(4);
  // top left corner
  line(190-m,190-m,190-m,240-m);
  line(190-m,190-m,240-m,190-m);
  // top right corner
  line(240+m,190-m,290+m,190-m);
  line(290+m,190-m,290+m,240-m);
  // bottom right corner
  line(290+m,240+m,290+m,290+m);
  line(290+m,290+m,240+m,290+m);
  // bottom left corner
  line(240-m,290+m,190-m,290+m);
  line(190-m,290+m,190-m,240+m);
}

function knitted(){
  // setting up the x and y values to draw the colored columns and rows
  for (var i = 0; i < 8; i++) {
    if (column >= 0) {
      column+=0.25;
    } if(column == width) {
      column = 0;
    }
    noStroke();
    fill(215,122,97,100);
    // yellow bars
    rect(i*width/8,0,30,height/8+column);
    fill(180,15,85,100);
    // pink bars
    rect(0,i*height/8,column,30);
  }
}

function triangles (){
  stroke(215,122,97,100);
  strokeWeight(2);
  push();
  translate(width/2,height/2);
  // set rotation of the triangles to increase with the frameCount
  rotate(radians(frameCount));
  triangle(-50,50,0,-50,50,50);
  strokeWeight(4);
  rotate(radians(frameCount*.5));
  triangle(-60,60,0,-60,60,60);
  strokeWeight(2);
  rotate(radians(frameCount*2));
  triangle(-65,65,0,-65,65,65);
  pop();
}

thlai-Project12-Proposal

I will be working with classmate Helen Wu from Section A.
I was inspired by one of my favorite arcade games, Dance Dance Revolution, and I thought it would be interesting to create something similar using the arrow keys. Essentially, the player will hit the arrow keys to the beat of a song while arrows move up (see picture). We are hoping to generate arrow keys based on the frequency/volume of the beat to create an entertaining game. I want to find a way to keep track of highest scores as well.

keuchuka – project 12 – proposal

For the final project, I want to create something that involves both generative and interactive components. I’m interested in creating generative motion graphics that involve typography, fill, and some 3D component. It will be generative either based on a set of data consisting of words (like a wikipedia page). It will also be dependent on also the mouse activity laid on the canvas. The shapes and lines will change according to interactivity, but type depends on the data fed in. The text interacts with the 3D shape by going around and behind it as well. I will be reading up on 3D super shapes and Dan Shiffman’s tutorials on them. Hopefully the type and the the shapes create a sense of aesthetically pleasant landscape that represents a set of data. I’m trying to create a piece of generative art that is not obviously showing a set of data, but looks like compositional, time based, motion graphics.


above is an image of a potential landscape composition

thlai-LookingOutwards12-Priors-and-Precursors

Dance Dance Revolution heavily inspired my Project 12 proposal, and although it is not necessarily an art piece, I think the game has several extremely interesting interactions that I could use for my project. Dance Dance Revolution, or DDR, did not originate in America – it originated in Japan in 1998 and was developed by a video game company called Konami. At the time, the game was critically acclaimed for being original and upbeat, and now it is seen not only in arcades but also in homes. The premise of the game is to step on the arrows that correspond with the ones shown on the screen, typically against another player, for points.
I definitely wonder about the code that created this game – I imagine it to be fairly complicated, since I can only comprehend maybe a quarter of what is going on. Either way, I find it an incredibly game and project. It brings back a lot of memories for me.

The second project is by a design creative studio called Design IO LLC called Connected Worlds. Connected Worlds is an interactive connected ecosystem that consists of six different ecosystems on interactive screens. The thing I like most about this installation is how interactive it is to the audience – it is almost like a game, and those are interactions I can use to inspire for my final project for this class, such as moving logs and connecting to creatures. It looks as though you are interacting with these different ecosystems as though you were there.Connected Worlds was developed using openFrameworks.

mjeong1-Project-12-Section A

Project Name: Feeding Packman

For final project  I am creating a shooting game. I want to combine packman game and 2D shooting game. The gamer has only two controls (mouse location on horizontal direction and key press to create the bullets or foods for packman). As we press key to create the foods(bullets) and shoot, the user has to control mouse to locate the position of ball shooting. The users have to aim at targeted packman to feed it. As we feed packman, packmans may want to disappear because they had enough food and want to leave. We have to continuously feed new comers. As we lever up, the bigger, and more starving packmans will come. They need more foods because they are hungrier than the previous packmans. Feeding them before they touch the bottom line is getting hard as more and hungrier packmans are coming to get foods. When the user fail to feed 5 packmans then the game is over.

I think key park for this game will be how we use the function of mouse press and location of mouse on the horizontal direction and I am also hoping to make the game graphically attractive by using many drawing and coloring commands.