ghou-Final-Project

I wanted to create an interactive and hopefully addicting mini-game. This project is inspired by the old arcade games I used to spend all my allowance on to win the big prize at the top! Also the final stacked blocks of my project looks similar to a modern skyscraper building in the grey skylines.

sketch

//Grace Wanying Hou
//15-104 Section D
//ghou@andrew.cmu.edu
//Final Project

//blocks dimensions setup
var h = 20;
var w = 100;
var x = 0;
var y = 20;
var speed = 1;
var fall = 5;
var dropping = false;
var taps = 0;

//arrays
var blocks = [];
var land = [75];

//gameplay
var play = false;
var gameOver = false;
var win = false;


function setup() {
    createCanvas(250, 400);
    frameRate(50);
    
}
 
function draw(){
    noStroke();
    if (gameOver == true){
        if (play == true){//game screen once "gameover"
            makeBackground();
            text("YOUR SCORE WAS " + taps, 60, height - h*taps - 2 * h);
            text("PRESS ANY KEY TO PLAY AGAIN", 28, height - h * taps - h);
            push();
            textSize(10);
            text("screenshot and share your architecture masterpiece :)", 5, 30)//hehe i like architecture
            pop();
            updateDisplay();
        }

        if (win == true){//game screen once player wins
            makeBackground();
            text("YOU WIN",100,40);
            text("PRESS ANY KEY TO PLAY AGAIN", 28, height/2);
            push();
            textSize(10);
            text("screenshot and share your architecture masterpiece :)", 5, 30)
            pop();
            updateDisplay();
        }
        //resetting the variables when restarting game
        if (keyIsPressed){
            gameOver = false;
            play = false;
            win = false;
            blocks = [];
            land = [75];
            dropping = false;
            w = 100;
            x = 0;
            y = 20;
            speed = 1;
            fall = 5;
            taps = 0;
        }
    }
    
    else if (play == true){//screen once game starts
            makeBackground();
            text("PRESS SPACE TO STACK BLOCKS", 30, height/2);
            for (var i = 0; i < 3; i++){
                var xstart = width / 2 - 50;
                var ystart = height - 20;
                blocks[i] = makeBlock(xstart, ystart, 100);
            }//gameplay functions
            blockDrop();
            drawBlock();
            blockMove();
            addBase();
            updateDisplay();
            scoreDisplay();
    }
    
    else {
        if (play == false){//starting screen
            makeBackground();
            text("PRESS ANY KEY TO BEGIN GAME", 28, height/2);
            if (keyIsPressed == true){
                play = true;
            }
        }
    }
    
    if (w <= 0){
        gameOver = true;
        play = true;
    }
    
    else if (taps >= 16 & y >= 50){
        gameOver = true;
        win = true;   
    }
}

function makeBackground(){//making a gradient for the background
    strokeWeight(1);
    for (var i = 0; i < height; i++){
        stroke(255 - i / 8);
        line(0, i, width, i);
    }
}

function blockMove(){//hovering blocks moving side to side
    if (x >= width - w){
        speed = -1 - (taps * 0.2);
    }
    else if(x <= 0){
        speed = 1+(taps * 0.2);
    }
    x = x + speed;
}

function blockDrop(){//dropping blocks
    if (dropping == true){
        y = y + fall;
        speed = 0;
        while (y > height - h * taps){
            dropping = false;
            y = 20;
            speed = 1 + (taps * 0.2);
            fall = 5;
        }
    }
}

function keyTyped(){//setting the blocks to drop once space is pressed
    if (keyCode == 32 & dropping == false && play == true){
        taps = taps + 1;
        append(land, x);
        dropping = true;
    }
}

function drawBlock(){//drawing hovering block
    noStroke();
    fill(0);
    rect(x,y,w,h);
}


function scoreDisplay(){//displaying score (numbers of blocks fallen)
    push();
    fill(255);
    textSize(15);
    text(taps,120,height-5);
    pop();

}
    
function addBase(){//knida confusing measurements of blocks collected in the tower
    var currenth = height - taps * h - h;//current height of tower
    if (y == height - h * taps){//if falling blocks are on the LEFT side of the tower
        if (land[taps] <= land[taps - 1]){
            blocks.push(makeBlock(land[taps - 1], currenth ,w - (land[taps - 1] - land[taps])));
            w = w - (land[taps - 1] - land[taps]);
            shorten(land);
            append(land, land[taps-1]);
        }
        else if (land[taps] > land[taps - 1]){//if falling blocks are on the RIGHT side of the tower
             blocks.push(makeBlock(land[taps], currenth, w - (land[taps] - land[taps - 1])));
             w = w - (land[taps] - land[taps - 1]);
        }
    }
}

function updateDisplay(){//drawing and updating the display of the stacked blocks
    for (var i = 0; i < blocks.length; i++){
        blocks[i].add();
    }
}

function towerBlocks(){//drawing the blocks in the tower
    noStroke();
    fill(0);
    rect(this.x, this.y, this.bw, this.bh);
}

//objects created for each block in the tower
function makeBlock(xlocation, ylocation, currentwidth){
    var block = {x:xlocation,
                 y:ylocation,
                 bh:20,
                 bw:currentwidth,
                 add:towerBlocks,
                 }
    return block;
}

ghou-Project-12-Proposal

For my final project I would like to create a musical interaction application that also creates visuals when each note is played. I have thought about creating a visualization similar to a piano keyboard that users could click on with their mouse (or preferably touch screen/touch pads/tablet devices) and each click would produce a musical note audio corresponding to which notes the user had clicked. Each of the keyboards would then produce a little “randomized” visual when it is pressed and it would either display above the keyboard on the canvas or wherever the user clicks.

I will be using Javascript Objects to create the keyboard and also the visuals, which will most likely be a series of radiating line drawings of some sort (I have not decided yet). I could probably use the noise() function or just the random() function to make a moving display for the visual.

I think I can also develop this program further by programming a song that the user can follow along the keyboard and play. I think that could be a little too difficult to store inside a written script however. 

ghou-lookingoutwards-12

The Mylar Topology

This is an audio-visual piece intended for panoramic projection and spatial sound. This a piece in the form of visual music. It generates shapes based on the audio data interpreted by an algorithm. The artist, Paul Prudence, likes to do live performances because the visual produced in each performance is different each time due to how it is computed.

Paul Prudence has performed his work internationally and exhibited ways in which sound, space, and form can create intriguing cinematic experiences.

For the second project I will be looking at the interactive phone piano app Magic Piano by Smule. It is a relaxing app that contains several songs to play. Music notes are queued and prompted by little beams of light and the user must tap on them to play them that composes into a certain song. A user could also control which notes to play and the rhythm and speed.

I think the first project I looked at, the Mylar Typology, would be more immersive if the audience could also interact physically with the project. I think these two projects are great precedents to study for my final project, I would like to make a system that generates visuals from sounds generated by the user.

ghou-Project-11-Composition

sketch

//Grace Wanying Hou
//15-104 Section D
//ghou@andrew.cmu.edu
//Project 11

var turtle =[];
var count = 10;
var dp;



function preload(){
    var imageurl = "https://i.imgur.com/S483jxr.jpg";
    dp = loadImage(imageurl);//loading the pic of my boy friendo
}

function setup() {
    background(0);
    createCanvas(380,300);
    image(dp,0,0)
    dp.loadPixels();
    for (var i = 0; i < count; i ++) {//setup the strokes
        turtle[i] = makeTurtle(0, 0);
        turtle[i].penDown;
    }
    strokeJoin(MITER);
    strokeCap(PROJECT);
    frameRate(30);
}

function draw() {
    for (var i = 0; i < count; i ++) {
        var pointcolour = dp.get(floor(mouseX),floor(mouseY));
        turtle[i].setColor(color(pointcolour)); //setting the colour to the pixel at the mouse point
        turtle[i].setWeight(random(15));//randomizing the weight
        turtle[i].turnToward(mouseX,mouseY, turtle[0].angleTo(pmouseX, pmouseY)); //turn along mouse movement.
        turtle[i].forward(turtle[i].distanceTo(mouseX, mouseY));//move along mouse movement.
    }
}




//given turtle stuffs
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) {
        strokeJoin(MITER);
        strokeCap(PROJECT);
        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;
}

This week I used turtle graphics to abstract colours from a portrait and “painting” with strokes randomized by mouse movements and those colours.

 

ghou-lookingoutwards-11

Martin Backes

This week I am doing my Looking Outwards on a technologist, hacker, DJ, and composer Martin Backes. He is based in Berlin, Germany.

This piece is called I am Sitting in a Machine; it is a custom-made computer algorithmic work that begins with a recording of an artificial human voice that recites the text given in the video. The voice is then run through an MP3 encoder multiple times to distort the voice by revealing the data format. It’s interesting how this work strips away the more “human” parts of the speaking voice to create the automated voice and the screeching sound towards the later parts.

 

ghou-Project-10-Landscape

sketch

//Grace Wanying Hou
//15-104 Section D
//ghou@andrew.cmu.edu
//Project 10


//global variables
var frames = [];
var sm1 = 0.0003;
var sm2 = 0.00035;
var sm3 = 0.0005;
var detail1 = 0.03;
var detail2 = 0.015;
var detail3 = 0.01;

var birds = [];

function preload(){
//AW MY CUTE BIRDS 😀
    var filenames = [];
    filenames[0] = "https://i.imgur.com/TMM2wDR.png";
    filenames[1] = "https://i.imgur.com/yl73pp4.png";
    filenames[2] = "https://i.imgur.com/XihpVMA.png";
    filenames[3] = "https://i.imgur.com/yl73pp4.png";
    filenames[4] = "https://i.imgur.com/TMM2wDR.png";
    filenames[5] = "https://i.imgur.com/OY3iZ36.png";
    filenames[6] = "https://i.imgur.com/nGeaANh.png";
    filenames[7] = "https://i.imgur.com/OY3iZ36.png";
    
    for (i=0; i<filenames.length; i++){
        frames[i] = loadImage(filenames[i]);
    }
}


function setup() {
    createCanvas(250,400);
    frameRate(10);
    //there should be some birds on screen when the sketch is first opened
    for (var i=0; i<5; i++){
        var randoPosition = random(width+100);
        birds[i] = makeBird(randoPosition);
    }
    

}
 
function draw() {
    //loading the functions
    makeBackground();
    maybeAddNewBird(); 
    makeMountains();
    updateDisplayBirds();
    
}


function makeBackground(){//making a gradient for the background
    strokeWeight(1);
    for (var i=0;i<height; i++){
        stroke(255-i/8);
        line(0, i, width, i);
    }
}
function makeMountains(){
    noStroke();
    
    //back mountain
    fill(210);
    beginShape(); 
    for (var x1 = 0; x1 < width; x1++) {
        var t1 = (x1 * detail1) + (millis() * sm1);
        var y1 = map(noise(t1), 0,1, 0, height);
        vertex(x1,y1-80); 
    }
    vertex(width,height);
    vertex(0,height);
    endShape();
    
    //middle mountain
    fill(190);
    beginShape(); 
    for (var x2 = 0; x2 < width; x2++) {
        var t2 = (x2 * detail2) + (millis() * sm2);
        var y2 = map(noise(t2), 0,1, 0, height);
        vertex(x2,y2+80); 
    }
    vertex(width,height);
    vertex(0,height);
    endShape();
        
    //front mountain
    fill(170);
    beginShape(); 
    for (var x3 = 0; x3 < width; x3++) {
        var t3 = (x3 * detail3) + (millis() * sm3);
        var y3 = map(noise(t3), 0,1, 0, height);
        vertex(x3,y3+150); 
    }
    vertex(width,height);
    vertex(0,height);
    endShape();
}

function updateDisplayBirds(){//keep the birds in display
    for (var i=0; i<birds.length; i++){
        birds[i].move();
        birds[i].display();
    }
}

function maybeAddNewBird(){//low chance a new bird will be added each frame
    if (random(1) < 0.015){
        birds.push(makeBird(width+100));
    }
}
function birdMove(){//updating the bird speed
    this.x += this.speed;
}

function displayBird(){ //drawing the birds
    push();
    fill(255,255,255,this.trans);
    noStroke();
    translate(this.x,this.floatHeight);
    for (var i=0; i<this.size; i++){
        tint(255, this.trans+i*20);//a group of birds will have different transparencies
        var fc = frameCount % 5; //animating the birds
        image(frames[fc+i],this.x-this.disX*i,0-this.disY*i);// the birds will flap their wings staggered
    }
    pop();
}

function makeBird(birthplace){ //making the birds
    var bird = {x: birthplace,
                 disX: random(10,50),
                 disY: random(30),
                 size: floor(random(1,4)),
                 trans: random(30,150),
                 speed: random(-4,-2),
                 floatHeight: random(40,150),
                 move: birdMove,
                 display: displayBird,
                }
    return bird;
}

I went for a monotoned landscape for this week’s project inspired by Pittsburgh’s insanely gloomy weather the past two weeks. I created the three layers of mountains using the noise() function provided to us and altering the colour, speed, and detail to create the layered effect. I used Javascript Objects to control my birds; they are frames of individual images Photoshopped and uploaded onto imgur.com. I also tried to make clouds using ellipse() functions and stored objects but it did not give me the desired effect so I decided to take them out.

ghou-lookingoutwards-10

Landscape Abbreviated

This installation is a mechanic garden that forms a kinetic maze including modular pieces and rotating planters. the planters are made up with moss collected from the sides of buildings. The artist, Nova Jiang, wanted to create a piece that makes the space and time dynamics unpredictable. The planters are controlled by a computer software that generates new maze patterns based on mathematics, making the audience experience the space in different ways as they walk through it to interact with the piece.

This piece is amazing as it touches on not only technology but also art, 3D installation, and architectural landscape design. I find it very intriguing in the way she organizes space that engages the audience using a computer algorithm.

Nova Jiang is a Chinese artist based in Los Angeles from Auckland, New Zealand. She creates immersive, open-systems in her art work that encourages creative participation from her audience. She obtained her MFA in Media Art from UCLA.

 

ghou-Project-09-Portrait

sketch

//Grace Wanying Hou
//15-104 Section D
//ghou@andrew.cmu.edu
//Project 09

//global variables
var sw = [];
var a = 0;
var r = 2;
var rx = [];
var ry = [];

function preload(){
    var imageurl = "https://i.imgur.com/S483jxr.jpg";
    dp = loadImage(imageurl);
}

function setup(){
    createCanvas(380,300);
    dp.loadPixels();
    background(240,245,250);
    for (var i=0; i<10; i++){ //randomizing where spirals are
        rx[i] = random(380);
        ry[i] = random(300);
        sw[i] = random(2,8);
    }
}

function draw(){
    noStroke();
    a += 0.1;
    r += 0.1;
//setting up spirals 
    var x = rx[0] + r * -cos(a);
    var y = ry[0] + r * sin(a);
    var pointcolour = dp.get(floor(x),floor(y));
    fill(pointcolour);
    ellipse(x,y,sw[0]);
    
    var x1 = rx[1] + r * -cos(a);
    var y1 = ry[1] + r * sin(a);
    var pointcolour1 = dp.get(floor(x1),floor(y1));
    fill(pointcolour1);
    ellipse(x1,y1,sw[1]);
    
    var x2 = rx[2] + r * -cos(a);
    var y2 = ry[2] + r * sin(a);
    var pointcolour2 = dp.get(floor(x2),floor(y2));
    fill(pointcolour2);
    ellipse(x2,y2,sw[2]);

    var x3 = rx[3] + r * -cos(a);
    var y3 = ry[3] + r * sin(a);
    var pointcolour3 = dp.get(floor(x3),floor(y3));
    fill(pointcolour3);
    ellipse(x3,y3,sw[3]);
    
    var x4 = rx[4] + r * -cos(a);
    var y4 = ry[4] + r * sin(a);
    var pointcolour4 = dp.get(floor(x4),floor(y4));
    fill(pointcolour4);
    ellipse(x4,y4,sw[4]);
    
    var x5 = rx[5] + r * cos(a);
    var y5 = ry[5] + r * sin(a);
    var pointcolour5 = dp.get(floor(x5),floor(y5));
    fill(pointcolour5);
    ellipse(x5,y5,sw[5]);

    var x6 = rx[6] + r * cos(a);
    var y6 = ry[6] + r * sin(a);
    var pointcolour6 = dp.get(floor(x6),floor(y6));
    fill(pointcolour6);
    ellipse(x6,y6,sw[6]);
    
    var x7 = rx[7] + r * cos(a);
    var y7 = ry[7] + r * sin(a);
    var pointcolour7 = dp.get(floor(x7),floor(y7));
    fill(pointcolour7);
    ellipse(x7,y7,sw[7]);
    
    var x8 = rx[8] + r * cos(a);
    var y8 = ry[8] + r * sin(a);
    var pointcolour8 = dp.get(floor(x8),floor(y8));
    fill(pointcolour8);
    ellipse(x8,y8,sw[8]);
    
    var x9 = rx[9] + r * cos(a);
    var y9 = ry[9] + r * sin(a);
    var pointcolour9 = dp.get(floor(x9),floor(y9));
    fill(pointcolour9);
    ellipse(x9,y9,sw[9]);
    
}

I was a little inspired by the post-expressionism art period and Van Gogh’s paintings and his swirling brush strokes to create this portrait. I think the most difficult part of this project was setting up the variables. Overall I really enjoyed working on this; I wanted to set up a for() loop to create the 10 spirals but in the end I was unsuccessful although I am still thoroughly proud of my work.

ghou-lookingoutwards-09

Looking Outwards on Daniel Noh 

Ross Spiral by Ross Institute

Daniel is a peer from my architecture studio, in this Looking Outwards post I am looking into one of his posts from week 7. Ross institute is a school that focuses on applied, advanced research, modelling, and dissemination, they strive to minimize the delay between research and application. The Ross Spiral represents the data of subjects in curriculum K through 12. in Daniel’s post he has stated that he thinks it is “far more impressive” as a 3D diagram and interactive map compared to a 2D drawing. I think this is an interesting way of representing data meant for spatial learners, however, it did take some time to figure out how to interact with the diagram and extract data from it. I think it would be useful to have a fuller data spreadsheet of how this graph is generated, and what each shape represented.

ghou-lookingoutwards-08

Reza 

Reza a computational designer, software engineer, and creative director currently located in the Bay Area. He is currently working full-time at Google on WebAR as a User experience engineer. I watched his 50 minute lecture about physical generative design and his process he gave at the Eyeo Festival in Minneapolis.

One of my favorite ideas of his is the observation of organic shapes from the common things around us. His favorite “perfection” is the shapes that are made when milk is poured into coffee. The organic curves that are generated from their combination is what he strives to achieve in his generative design work. He works on many different scaled projects at a time and have produced many things in the past years. I admire how he combines the computational world with the physical.