4. Project 10: Sonic Story

sketch – CopyDownload
// This program displays a game of cup pong.
// The 'characters' are the ball, cups, table, and water in the cups.
// When the ball bounces on different surfaces (on the floor, into a cup, etc.),
// it produces different sounds.
// One side wins when all of the cups are empty
//(or just a few if you change the 'win' variable in the draw function).

// sounds:
var watercup;
var emptycup;
var bouncefloor;
var throwing;
var gameover;


// objects:
var cup; // will have fields for cx, cy, and boolean isFull
var ball; // will have fields for x, y, dx, dy, and functions

// arrays:
var leftCups = [];
var rightCups = [];

function preload() {
    watercup = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/pong-sounds-with-liquid.wav");
    bouncefloor = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/bouncing-ping-pong-ball.wav");
    throwing = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/throwing-paper-in-trash.wav");
    gameover = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/ending.wav");
}

// makes a cup object, always full to begin
function makeCup(cx, cy) {
    cup = {x:cx, y:cy, isFull: true, drawc: drawCup};
    return(cup);
}

// makes a ball object
function makeBall(cx, cy, dirx, diry) {
    ball = {x:cx, y:cy,
            dx:dirx, dy:diry,
            drawb: drawBall,
            throwb: throwBall,
            resetb: resetBall,
            leftright: true};
    return(ball);
}

function setup() {
    createCanvas(480, 300);
    frameRate(35);	// high framerate is better for this program
    useSound();
    rectMode(CENTER);

    // fill cup arrays:
    // set x and y positions to create pyramid shape.
    // the if statements create the rows for the pyramid
    for (var i=0; i<10; i++) {
        if (i<4) {
	    lcup = makeCup(width/10+10,	(i*20)+120);
            rcup = makeCup(9*width/10-10, (i*20)+120);
        }
        else if (i<7) {
	    lcup = makeCup(width/10+30,	(i*20)+50);
            rcup = makeCup(9*width/10-30, (i*20)+50);
        }
        else if (i<9) {
	    lcup = makeCup(width/10+50,	i*20);
            rcup = makeCup(9*width/10-50, i*20);
        }
        else {
	    lcup = makeCup(width/10+70,	height/2);
            rcup = makeCup(9*width/10-70, height/2);
        }
        leftCups.push(lcup);
        rightCups.push(rcup);
    }

    // create ping pong ball
    let dy = random(-4, 4);
    ball = makeBall(5, height/2, 5, dy);
}

function soundSetup() { // setup for audio generation
    watercup.setVolume(0.5);
    bouncefloor.setVolume(0.5);
    throwing.setVolume(0.5);
    gameover.setVolume(0.5);
}


function draw() {
    background(133, 94, 66);

    // draw the table
    drawTable();

    // draw the cups
    for (var c=0; c<leftCups.length; c++) {
        leftCups[c].drawc();
        rightCups[c].drawc();
    }

    // draw the ball
    ball.drawb();

    // throw the ball
    ball.throwb();

    // check for winner
    let checkl = 0;
    let checkr = 0;
    for (l=0; l<leftCups.length; l++) {
        if (leftCups[l].isFull == false) { checkl+=1 }
    }
    for (r=0; r<rightCups.length; r++) {
        if (rightCups[r].isFull == false) { checkr+=1 }
    }
    // when one side wins, display text and play sound
    // change 'win' value to see game over sooner:
    let win = 10;
    if (checkl == win|| checkr == win) {
        gameover.play();
        textAlign(CENTER, CENTER);
        textSize(25);
        fill(0);
        rect(width/2, height/2, width/2, 50, 10);
        fill(255);
        text('Game Finished!', width/2, height/2);
        noLoop();
    }


}

// draws a green table with offwhite diagonal lines:
function drawTable() {
    let linescol = color(250, 250, 225);
    let tcol = color(0, 100, 100);
    strokeWeight(7);
    stroke(linescol);
    fill(tcol);
    rect(width/2, height/2, 4*width/5, 4*height/5);
    line(width/10, height/10, 9*width/10, 9*height/10);
    line(width/10, 9*height/10, 9*width/10, height/10);
}

// draws individual cups based on x and y fields:
function drawCup() {
    let diam = 20;
    fill(200, 0, 0);	// red cup
    stroke(255);
    strokeWeight(2);
    circle(this.x, this.y, diam);
    // if the cup hasnt been hit, it has water in it:
    if (this.isFull == true) {
        noStroke();
        fill(0, 0, 200);	// blue water
        circle(this.x, this.y, diam/2);
    }
}

// draws the ball
function drawBall() {
    stroke(0);
    strokeWeight(.5);
    fill(250);
    circle(this.x, this.y, 10);
}

//throws the ball
function throwBall() {
    if (this.leftright==true) {		// going left to right
        if (this.x < width/2) {
            this.x += this.dx;
            this.y -= this.dy;
        } else {
            this.x += this.dx;
            this.y += (1.5*this.dy);
        }
        // remove the water if the ball goes into a full cup and reset ball placement
	// play water cup noise if cup is hit
        for (var j=0; j<rightCups.length; j++) {
            if (dist(rightCups[j].x, rightCups[j].y, this.x, this.y)<=7 &
		rightCups[j].isFull==true) {
	   	watercup.play();
                rightCups[j].isFull = false;
                this.resetb();
            }
        }
    } else {				// going right to left
        if (this.x > width/2) {
            this.x -= this.dx;
            this.y -= this.dy;
        }
        else {
            this.x -= this.dx;
            this.y += (1.5*this.dy);
        }
	// same code to remove water from hit cup
        for (var j=0; j<leftCups.length; j++) {
            if (dist(leftCups[j].x, leftCups[j].y, this.x, this.y)<=7 &
		leftCups[j].isFull==true) {
	   	watercup.play();
                leftCups[j].isFull = false;
                this.resetb();
            }
        }
    }
    // no cups are hit, reset the ball position & play floor bounce track
    if (this.x > width || this.x < 0 ) {
       	this.resetb();
        bouncefloor.play();
    }
}

//resets the ball to the next players starting position
function resetBall() {
    this.leftright = -this.leftright;
    if (this.leftright == true) {this.x=10}
    else {this.x =width-10}
    this.y = height/2;
    this.dy = random(-4, 4);
    // plays a 'whoosh' track for each throw
    throwing.play();
}

I chose to make a program that displays a game of water pong. The sounds I use are a ‘whoosh’ noise when a ball is thrown, a ‘clink’ sound if the ball goes into a full cup, a bouncing pingpong ball noise if the ball does not go into any full cups, and a bell noise if there is a winner. My code is randomized in a way that every game will be slightly different.

Project: Sonic Story

luca sonic story

//Luca Cao
//lucacao@andrew.cmu.edu
//Section D

//Story: 
//pan put on stove. Sound 1
//Gas starts. Sound 2
//Steak cooks on pan and sizzle. Sound 3
//eats steak. Sound 4

var pan = {x:200,y:400,d:100,r:73,g:80,b:87,
            hx:200,hy:480,hw:15,hh:70,dy:20};//object pan
var stv = {x:200,y:200,d:150,r:33, g:37, b:41};//object stove
var stk = {x:200,y:200,w:40,h:60,r:220,g:24,b:54,dy:30};//object steak
var metal;
var gas;
var steak;
var eat;

function preload(){
    metal = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/metal.wav");
    gas = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/gas1.wav");
    steak = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/steak.wav");
    eat = loadSound("https://courses.ideate.cmu.edu/15-104/f2021/wp-content/uploads/2021/11/eat.wav");

}

function soundSetup(){
    metal.setVolume(5);
    gas.setVolume(0.5);
    steak.setVolume(1);
    eat.setVolume(2);
}

function setup() {
    createCanvas(400, 400);
    noStroke();
    frameRate(2);
    useSound();
}

function draw() {
    background(255, 243, 176);

    //platform
    push();
    fill(173, 181, 189);
    rect(0,0,400,400);
    fill(108, 117, 125);
    rect(0,320,400,90);
    pop();

    //controls
    push();
    if (pan.y <= 350){
        fill(0,255,0);
        ellipse(300,350,10,10);
        ellipse(350,350,10,10);
    }
    pop();

    //stove
    push();
    fill(stv.r,stv.g,stv.b);
    ellipse(stv.x,stv.y,stv.d,stv.d);

    if (pan.y <= 300){
        stv.r = 200;
        stv.g = 0;
        stv.b = 0;
        gas.play();
    }
    pop();

    //pan
    push();
    rectMode(CENTER);
    fill(pan.r,pan.g,pan.b);
    ellipse(pan.x,pan.y,pan.d,pan.d);
    rect(pan.hx,pan.hy,pan.hw,pan.hh);
    pan.y = pan.y - pan.dy
    pan.hy = pan.hy - pan.dy

    if (pan.y <= 200){
        gas.stop();
        pan.dy = 0; 
    }
        //pan.hy = 280
    
    pop();


    //steak
    if (frameCount >= 15){
        fill(stk.r,stk.g,stk.b);
        ellipse(stk.x,stk.y,stk.w,stk.h);
        steak.play();
        

        if (frameCount >= 20){
            stk.r = 157;
            stk.g = 2;
            stk.b = 8;

            if (frameCount >= 25){
                stk.r = 106;
                stk.g = 4;
                stk.b = 15;

                if (frameCount >= 35){
                    stk.r = 80;
                    stk.g = 6;
                    stk.b = 23;
                    stk.y = stk.y - stk.dy;
                    steak.stop();

                    if (frameCount >= 45){
                        eat.play();
                    }

                    if (frameCount >= 50){
                        eat.stop();
                        background(0);
                        noLoop();
                    }
                }
            }
        }
    }
}

I created the story of cooking a steak. I started by animating all my visual assets and making sure that they appear at the right time. After that, I added sound into my code based on the position of the assets, as well as the frame count. I stored all the values on my characters in object form, which helped me to better manipulate them. During the process, I had difficulties preloading sounds into my code and I later realized that I used the wrong template for my code. I enjoyed making this project because, besides visual interaction, I also get to experiment with sonic interaction and make the outcome more engaging.

Project: Computational Portrait (Custom Pixel)

project pixel sketch luca

var img;//image
var imgang = 90;//image angle

function preload(){
  img = loadImage('https://i.imgur.com/XCeFp0s.png');//load image from imgur.com
}

function setup() {

  createCanvas(391, 480);
  //background for contrast
  noStroke();
  imageMode(CENTER);
}

function draw() {

  background(0,0,0);

  for (var col = 0; col < img.height; col+=10){//I did column for height because my image was incorrectly loaded.
    for (var row = 0; row < img.width; row+=10){//row for height.

      var c = img.get(row,col);//extract pixel from image and set as color

      //set image to correct and central position
      push();
      translate(391,0);
      rotate(radians(imgang));
      fill(color(c));//fill with picture colors
      ellipse(col,row,7,7);//ellipses as pixels
      pop();

    }
  }

  push();//needs to be separate because of background setting

  //draw head
  stroke(230,230,0);
  strokeWeight(5);
  line(50,150,320,150);
  line(50,150,50,400);
  line(50,400,320,400);
  line(320,400,320,150);
  line(125,360,255,360);

  //moving eyes
  var wall1 = constrain(mouseX,120,150)
  var c = constrain(mouseY,225,255);
  var wall2 = constrain(mouseX,240,280)

  //eyes
  fill(230,230,0);
  ellipse(wall1,c,30,30);
  ellipse(wall2,c,30,30);

  pop();

}




I enjoyed making this project. I faced challenges when I tried to load my images and match pixels according to the image. I changed the image link to a direct link on Imgur and solved the problem. For the pixels, I used a for loop to match the pixels to the image, and by changing the number of increments for each run, I was able to change the size and density of my pixels. For my composition, I did not want to create a photorealistic representation, instead, I wanted some sort of interaction with the image, so I created the yellow face. Overall, this project was a challenge, but I learned more about images in p5.js.

Project 09: Computational Portrait

sketchDownload
// This program deconstructs an image and then reconstructs it in a new way.
// The image is sliced into pieces and then drawn together in a new order
// Horizontally and vertically

var img;
var lineHeight = [];
var lineWidth = [];
var numSlices = 6;   //must be even

// slices are ordered and grouped into 4 arrays
var imgSlices1 = [];
var imgSlices2 = [];
var imgSlices3 = [];
var imgSlices4 = [];

function preload() {
    img = loadImage('https://i.imgur.com/c6ZRijQ.jpg');
}

function setup() {
    createCanvas(480, 480);
    imageMode(CENTER);
    noStroke();
    img.loadPixels();

    // get x and y values for the slices based on canvas size and number of slices
    for (var i=0; i<numSlices; i++) {
        let h = height/(numSlices+1);
        let h1 = height/numSlices;
        let w = width/(numSlices+1);
        let w1 = width/numSlices;
        lineHeight[i] = h1*i + h1/2;
        lineWidth[i] = w1*i + w1/2;
        // rearrange image pieces based on odd or even and fill arrays
        if (i%2==0) {
          imgSlices2.push(img.get(0, lineHeight[i], width/2, h));
          imgSlices4.push(img.get(lineWidth[i], 0, w, height));
        }
        else {
          imgSlices1.push(img.get(0, lineHeight[i], width/2, h));
          imgSlices3.push(img.get(lineWidth[i], 0, w, height));
        }
    }
}

function draw() {
    //there is some background that shows ecpecially with small numSlices values
    // this sets background to match original image
    var bgrnd = img.get(random(width), random(height));
    background(bgrnd);

    //draw image in new order
    for (var i=0; i<numSlices/2; i++) {
        image(imgSlices1[i], width/4, lineHeight[i]*2);
        image(imgSlices2[i], 3*width/4, lineHeight[i]*2);
        image(imgSlices3[i], lineWidth[i], height/2);
        image(imgSlices4[i], lineWidth[i]+width/2, height/2);
    }
    noLoop();
}

Based on what I’ve seen classmates post, I am not sure I did this project correctly. I am really happy with my outcome, though, and it is close to what I visualized before I started writing any code. When I read the prompt for this assignment, I was inspired by I video I had seen of an artist cutting up pictures and then putting them back together in strange ways that added new perspective and dimension. With this in mind, I decided to cut up the image and then layer it on top of itself in new ways. Technically, the image is displayed twice, but not the same way either time. With a quick change of code you can see how the portrait is drawn with more or fewer ‘slices’.

numSlices = 4
numSlices = 6
numSlices = 10
numSlices = 30

Project 09 – Portrait

sketch
//Brandon Yi
//btyi@andrew.cmu.edu
//Section A


//Initialization
var img;
var counter = 0;

//preload image
function preload() {
  img = loadImage('https://i.imgur.com/ox0pEHV.jpg');
}


function setup() {
  img.resize(img.width/5, img.height/5); //Resizing image
  createCanvas(img.width, img.height); //Canvas size based on image size
  imageMode(CENTER);
  rectMode(CENTER);
  textAlign(CENTER);
  noStroke();
  background(255);
  img.loadPixels(); 
}

//drawing shapes based on mouse position to imitate loaded image
function draw() {
  if (counter == 0) {
    settingNumber();
    var pointcolor = img.get(mouseX, mouseY); //point color based on mouse position and image
    fill(pointcolor);
    rect(mouseX, mouseY, 15, 15); //draw rectangle in mouse position
  }
  else if (counter == 1) {
    settingNumber();
    var pointcolor = img.get(mouseX, mouseY);
    fill(pointcolor);
    ellipse(mouseX, mouseY, 15, 15); //draw circle in mouse position
  }
  else if (counter == 2) {
    settingNumber();
    var pointcolor = img.get(mouseX, mouseY);
    fill(pointcolor);
    rect(mouseX, mouseY, 30, 30);
  }
  else if (counter == 3) {
    settingNumber();
    var pointcolor = img.get(mouseX, mouseY);
    fill(pointcolor);
    ellipse(mouseX, mouseY, 30, 30);
  }
  else {
    settingNumber();
    var pointcolor = img.get(mouseX, mouseY);
    fill(pointcolor);
    rect(mouseX, mouseY, 50, 50);
  }
  
}

//Changing setting number and resetting canvas
function mousePressed() {
  counter++;
  counter = counter % 5;
  print(counter);
  background(255);
}

//Setting number in label
function settingNumber() {
    textSize(30);
    fill(0);
    rect(350, 590, 150, 50)
    fill(255);
    text("Setting " + (counter+1), 350, 600);
}

LO-9

Hello! For this weeks looking outwards I decided to explore Olia Lialina’s online art gallery. Olia is an internet artist and experimental film producer. She was born in Moscow and studied film criticism and journalism in Moscow State University, then got an art residencey in Budapest and Munich. Olia’s online gallery linked below is a massive website that displays her art in different spots on the page. With a galaxy background, navigating through the website shifts you around the page to different pieces and categories. I really like this piece because it navigating through it really does feel like walking through a well-curated gallery. I think this is an awesome example of what art galleries can look like in the finite in order to reach more people through the internet.

Center of the Universe

Project 9: Computational Portrait

sketch

var img;
var diameter;

function preload() {
    img = loadImage("https://i.imgur.com/VzFWKC5.jpg");
}

function setup() {
    createCanvas(320, 480);
    image(img, 0, 0, 320, 480);
    background(110);
}

function draw() {
    noStroke();
    x = random(2000);
    y = random(2992);
    c = img.get(x, y);
    fill(c);
    if (x < 1500 & x > 300 && y < 2000 && y > 550) {
        diameter = 10;
    } else {
        diameter = 20;
    }
    circle((x * 0.16), (y * .16), diameter);
}

LO 9

For this looking outwards, I decided to study Yael Braha, a large-scale dynamic display designer that combines traditional and non-traditional art practices, including ceramics, metal fabrication, metal casting, electronics, and mold making. She is originally from Italy where she studied Graphic Design at the European Institute of Design in Rome and then moved to the United States for her Master of Fine Arts in Cinema at San Francisco State University. 

One of her works that I found interesting was Artifacts, audio-reactive live show for the Minnesota Orchestra. The visuals are generated based on the timbre, amplitude, frequencies, patterns and narrative of the orchestra’s score in real time. It was captivating to see how she was able to merge a traditional experience of watching a symphony into something surreal, fantastical, and progressive.

project-09

sketch
function preload() {
    var myImage="https://i.imgur.com/0PVv59G.jpeg";
    loadedImage=loadImage(myImage);    
}

function setup() {
  createCanvas(400,400);
  background(0);
  loadedImage.resize(400,400);   
  loadedImage.loadPixels();
  frameRate(100000000000000000000000000000000000000000000000000000000000);
}

function draw() {
  var x=random(width);
  var y=random(height);
  var pixelx=constrain(floor(x),0,width);
  var pixely=constrain(floor(y),0,height);
  var pixelcolor=loadedImage.get(pixelx,pixely);    
  noStroke();
  fill(pixelcolor);    

  square(x,y,random(0,5));    


}