Nadia Susanto – Final Project

sketch

// Nadia Susanto
// nsusanto@andrew.cmu.edu
// Section B
// Final Project

var terrainSpeed = 0.0005;
var terrainDetail = 0.003;
var clouds = [];
var pipes = [];
var birdY = 300;
var birdX = 65;
var birdGravity = 0.75;
var birdVelocity = 0;
var birdUpForce = -18;
var secs = 0;


function setup() {
    createCanvas(600, 600);
    background(135,235,250);
    pipes.push(makePipe());
    //initalizing clouds
    for (var x = 0; x < 5; x++) {
        var cx = random(width);
        clouds[x] = makeClouds(cx);
    }

    frameRate(60);

}

function draw() {
    //blue sky
    background(135,235,250);
    //show mountains and waves
    makeMountains();
    makeWaves();
    //show clouds
    addNewClouds();
    updateAndDisplayClouds();
    removeCloudsOutofView();
    //pipes
    addNewPipes();
    updateAndDisplayPipes();
    //bird
    drawBird();
    updateBird();
    //collision detection for bird with pipe
    topCollision();
    bottomCollision();
    if (frameCount % 60 == 0) {
        secs += 1;
    }
    //score
    fill("black");
    textSize(30);
    textAlign(LEFT);
    text("TIME = " + secs, 5, 50);

}

//collision for bird with top pipe
function topCollision() {
    for (var i = 0; i < pipes.length; i++) {
        if ((birdY < pipes[i].top + 30) & (birdX > pipes[i].x && (birdX < pipes[i].x + pipes[i].w))) {
            gameOver();
          }
      }
}

//collision for bird with bottom pipe
function bottomCollision() {
    for (var i = 0; i < pipes.length; i++) {
        if ((birdY > pipes[i].top + 150) & (birdX > pipes[i].x && (birdX < pipes[i].x + pipes[i].w))) {
            gameOver();
          }
      }
}

//game over function that stops the game when triggered
function gameOver() {
    fill("red");
    textAlign(CENTER);
    textSize(60);
    text("GAME OVER", width/2, height/2);
    noLoop();
}

//constantly calling the pipes
function updateAndDisplayPipes() {
  for (var i = 0; i < pipes.length; i++) {
      pipes[i].move();
      pipes[i].draw();
    }
  }

function addNewPipes() {
    if (frameCount % 150 == 0) {
        pipes.push(makePipe());
    }
}

//moving the pipes right to left
function movePipe() {
    this.x -= this.speed;
}

function drawPipe() {
  noStroke();
  //top pipe
  fill(112,186,45);
  rect(this.x, 0, this.w, this.top);
  rect(this.x - 5, this.top - 2, this.w + 10, 20, 10);
  //bottom pipe
  rect(this.x, height, this.w, this.top - height + 150);
  rect(this.x - 5, this.top + 135, this.w + 10, 20, 10);
}

//object for pipe
function makePipe() {
    var pipe = {x: width,
                w: 50,
                top: random(50, height/2),
                speed: 1.5,
                move: movePipe,
                draw: drawPipe
                }
    return pipe;
}

//drawing the bird
function drawBird() {
    //legs
    fill(0);
    ellipse(birdX - 10, birdY + 15, 3, 10);
    ellipse(birdX + 10, birdY + 15, 3, 10);
    //halo
    noFill();
    stroke("gold");
    ellipse(birdX, birdY - 20, 40, 5);
    //body
    fill("yellow");
    ellipse(birdX, birdY, 35, 35);
    //eye
    fill(0);
    ellipse(birdX + 5, birdY - 5, 5);
    //beak
    fill("orange");
    triangle(birdX + 18, birdY - 4, birdX + 23, birdY, birdX + 18, birdY + 4);

}

//implementing velocity and gravity
function updateBird() {
  birdVelocity += birdGravity;
  //air resistance
  birdVelocity *= 0.9;
  birdY += birdVelocity;
  //making sure it doesnt go beyond top and bottom of canvas
  if (birdY > height) {
      birdY = height;
      birdVelocity = 0;
    }
  if (birdY < 0) {
      birdY = 0;
      birdVelocity = 0;
  }
}

//adding up force to bird velocity
function birdUp() {
    birdVelocity += birdUpForce;
}

//if space bar pressed, trigger the bird to go up
function keyPressed() {
    if (key == ' ') {
        birdUp();
    }
}

//constantly calling the clouds
function updateAndDisplayClouds() {
    for (var x = 0; x < clouds.length; x++){
        clouds[x].move();
        clouds[x].draw();
    }
}

function removeCloudsOutofView() {
    var cloudsKeep = [];
    for (var x = 0; x < clouds.length; x++) {
        if (clouds[x].x > 0) {
            cloudsKeep.push(clouds[x]);
        }
    }
    clouds = cloudsKeep; //remember the clouds
}

function addNewClouds() {
    var cloudProb = 0.01;
    //if random number less than probability then a new cloud is shown
    if (random(0, 1) < cloudProb) {
        clouds.push(makeClouds(width));
    }
}

function cloudsMove() {
    //move the clouds from right to left
    this.x -= this.speed;
}

function drawClouds() {
    //draw the white clouds
    fill("white");
    ellipse(this.x, this.y, this.width, 10);
    ellipse(this.x - 25, this.y - 10, 35, 30);
    ellipse(this.x + 25, this.y - 10, 30, 30);
    ellipse(this.x + 5, this.y - 15, 40, 25);
}

function makeClouds(cloudX) {
  //creating object for cloud
  var cloud = {x: cloudX,
              y: 50,
              width: random(50, 100),
              speed: 0.50,
              move: cloudsMove,
              draw: drawClouds}
  return cloud;
}

//adopted the terrain starter code to make mountains in background
function makeMountains() {
    noStroke();
    fill(127,221,136);
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail*3) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, height/4, height/3);
        vertex(x, y);
      }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
}

//adopted the terrain starter code to make ocean waves
function makeWaves() {
    noStroke();
    fill(1, 108, 194);
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail/3) + (millis() * terrainSpeed/2);
        var y = map(noise(t), 0, 1, height/2, height);
        vertex(x, y);
      }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
}

For my final project I made angel bird! I have always been a gamer at heart and love competition whether it be beating my peers or my personal bests. Originally for my proposal I wanted to do scream go hero but had difficulties with voice recognition. Flappy bird was my backup and I am really happy with the way it turned out. I used my knowledge of objects to create the generative backgrounds and the pipes, and I believe my angel bird with a halo is pretty cute.

How the game works:

The game automatically starts and all you have to do is press the space bar to make the bird go up. Instead of scoring, you want to beat your personal best times as you want to see how long you can go without the dreaded “GAME OVER.” Enjoy!

Nadia Susanto – Project 12 – Final Proposal

For the final project, I want to challenge myself by learning a p5js function we did not learn about. I want to create an interactive game using speech/voice recognition. I want to create a game like Scream Go Hero where the user has to “scream” to get the avatar to move. A soft voice would make the avatar move. A loud voice would make the avatar jump. The higher the volume, the higher the avatar can jump. The objective of the game will be the same as the avatar has to collect as many objects as it can without falling through the cracks. The actual game doesn’t have much design into it, so I want to create a version where it incorporates a generative landscape and other obstacles.

If I have having trouble getting the speech recognition to work, then I will do a version of flappy bird.

Scream Go Hero actual game
Scream Go Hero is known for being a very funny game, so I am excited to be able to play this myself with my friends.
Rough sketch outline of what I want my game to look like
Backup: A version of flappy bird

Nadia Susanto – Looking Outwards – 12

I wanted to look at Phoenix Perry and Heather Kelley because they are both game developers. Phoenix Perry created a game called Bot Party where it explores intimacy through physical play using sound. It’s an interactive sound experience for humans and the bots need help from humans to communicate with their friends. The technology itself uses proprietary bot to skin to skin to bot communication protocol to send encoded secret messages.

Phoenix explaining her game and why she made it
Closer look into the aspect of the game where the bots have to touch each other

Heather Kelley collaborated with several others on the project Fabulous/Fabuleux. It is a physical interface game for public interior spaces where players solve “connect the dots” challenges using the hotspots of the room. The players uses a “squisher” interface object and by connecting the hotspots it reveals objects on screen which relate to the fairy tale “The Girl Who Trod On A Loaf.”

Video demonstrating the game being played

Both of these games interest me because they require physical human interaction within it. I will be doing a project that requires human interaction, so I was inspired by these projects.

To learn more about bot party click below:

http://playbotparty.com/2018/01/24/WhatIsBotPartyl-prep/

To learn more about Fabulous/Fabuleux click below:

http://www.perfectplum.com/portfolio/fabulousfabuleux/

Nadia Susanto – Project 11 – Generative Landscape

sketch

// Nadia Susanto
// nsusanto@andrew.cmu.edu
// Section B
// Project-11-Generative Landscape


var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var boats = [];
var clouds = [];

function setup() {
    createCanvas(480, 480);
    //initalizing boats
    for (var i = 0; i < 3; i++){
        var bx = random(width);
        boats[i] = makeBoats(bx);
    }
    //initalizing clouds
    for (var x = 0; x < 5; x++) {
        var cx = random(width);
        clouds[x] = makeClouds(cx);
    }

    frameRate(20);
}

function draw() {
    //pinkish sky
    background(254, 165, 159);
    //show mountains and waves
    makeMountains();
    makeWaves();
    //show boats
    addNewBoats();
    updateAndDisplayBoats();
    removeBoatsOutofView();
    //show clouds
    addNewClouds();
    updateAndDisplayClouds();
    removeCloudsOutofView();

}

function updateAndDisplayClouds() {
    //constantly calling the clouds
    for (var x = 0; x < clouds.length; x++){
        clouds[x].move();
        clouds[x].draw();
    }
}

function removeCloudsOutofView() {
    var cloudsKeep = [];
    for (var x = 0; x < clouds.length; x++) {
        if (clouds[x].x > 0) {
            cloudsKeep.push(clouds[x]);
        }
    }
    clouds = cloudsKeep; //remember the clouds
}

function addNewClouds() {
    var cloudProb = 0.01;
    //if random number less than probability then a new cloud is shown
    if (random(0, 1) < cloudProb) {
        clouds.push(makeClouds(width));
    }
}

function cloudsMove() {
    //move the clouds from right to left
    this.x -= this.speed;
}

function drawClouds() {
    //draw the white clouds
    fill("white");
    ellipse(this.x, this.y, this.width, 10);
}

function makeClouds(cloudX) {
  //creating object for cloud
  var cloud = {x: cloudX,
              y: random(10, 100),
              width: random(50, 100),
              speed: 0.50,
              move: cloudsMove,
              draw: drawClouds}
  return cloud;
}



function updateAndDisplayBoats() {
    //constantly calling the boats
    for (var i = 0; i < boats.length; i++){
        boats[i].move();
        boats[i].draw();
    }
}

function removeBoatsOutofView() {
    var boatsKeep = [];
    for (var i = 0; i < boats.length; i++) {
        if (boats[i].x > 0) {
            boatsKeep.push(boats[i]);
        }
    }
    boats = boatsKeep; //remember the boats
}

function addNewBoats() {
    //if random number less than probability then a new boat is shown
    var boatProb = 0.005;
    if (random(0, 1) < boatProb) {
        boats.push(makeBoats(width));
    }
}

function boatsMove() {
    //move the boats from right to left
    this.x -= this.speed;
}

function drawBoats() {
    //random color for boats
    fill(this.colorR, this.colorG, this.colorB);
    //base of boat
    arc(this.x, 350, 75, 50, 0, PI, CHORD);
    //pole holding the sail
    ellipse(this.x, 330, 10, 80);
    //sail of boat
    triangle(this.x, 290, this.x, 330, this.x + 15, 310);
}

function makeBoats(boatX) {
    //creating object for boat
    var boat = {x: boatX,
                colorR: random(0, 255),
                colorG: random(0, 100),
                colorB: random(0, 200),
                speed: 1,
                move: boatsMove,
                draw: drawBoats}
    return boat;
}

//adopted the terrain starter code to make mountains in background
function makeMountains() {
    noStroke();
    fill(35, 144, 79);
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail*3) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, height/4, height/2);
        vertex(x, y);
      }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
}

//adopted the terrain starter code to make ocean waves
function makeWaves() {
    noStroke();
    fill(1, 108, 194);
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail/3) + (millis() * terrainSpeed/2);
        var y = map(noise(t), 0, 1, height/2, height);
        vertex(x, y);
      }
    vertex(width, height);
    vertex(0, height);
    endShape(CLOSE);
}

For this project I went back to a time when I was in Banff, Canada. I would canoe or ride in a boat on the lake with the mountains behind me. I created moving mountains and moving ocean waves with boats of random colors popping in and out. It was tough at first to figure out how to code the objects, but it was a fun project and I am happy with the final product.

My idea sketched out

Nadia Susanto – Looking Outwards – 11

Chloe Varelidi is an indie game designer/developer that designs and builds playful products that empowers humans to be creative, kind, and curious.

One of her projects was the Minicade, and this was a collaboration with Atul Varma for her artist residency at Eyebeam. The Minicade is a website and app where people can collaboratively build mini arcade games with multiple users. Each person can add a link to one or more games to a custom playlist and instantly play them as one massive game, that keeps track of score and increases the difficulty. Its very simple to use and users can either play the games already provided or remix the mini-game with their own code. While the Minicade is mostly used by kids to encourage them to learn the basics of programming, it is fun for everyone to use.

The use of mini-games itself reminds me of mini-games in popular apps like Dumb Ways to Die, and it adds a cool competitive aspect for kids to interact with each other by building games they did themselves.

The Minicade also has a creative external feature looking like an emoji come to life
A user interacting with the Minicade

To learn more about this project, click the links below:

http://www.minica.de/

https://www.vice.com/en_us/article/wnpj3b/provoking-participation-through-art-at-eyebeams-2015-annual-showcase

Nadia Susanto – Project 10 – Sonic Sketch

sketch

// Nadia Susanto
// nsusanto@andrew.cmu.edu
// Section B
// Project-10-Interactive Sonic Sketch


function preload() {
    //loaded image from imgur
    TigerWoodsImg = loadImage("https://i.imgur.com/ETVJsHl.jpg");
    golfhitSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/golfhit.wav");
    tigerRoarSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/tigerroar.wav");
    golfBallCupSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/golfballincup.wav");
    cheeringSound = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/11/cheering.wav");
}


function setup() {
    createCanvas(600, 600);
    TigerWoodsImg.resize(600, 600);
    useSound();
}


function soundSetup() { // setup for audio generation
    golfhitSound.setVolume(1);
    tigerRoarSound.setVolume(1);
    golfBallCupSound.setVolume(1);
    cheeringSound.setVolume(1, 3);
}


function draw() {
    background(200);
    image(TigerWoodsImg, 0, 0);
}

function mousePressed() {
    //sound of a golf ball being hit when clicked on the caddy
    if (mouseX > 400 & mouseX < 500 && mouseY > 400) {
        golfhitSound.play();
    }
    else {
        golfhitSound.pause();
    }

    //sound of cheering when clicked on the crowd behind the green
    if (mouseY < 300 & mouseY > 150) {
        cheeringSound.play();
    }
    else {
        cheeringSound.pause();
    }

    //sound of a tiger roar when clicked on Tiger Woods
    if (mouseX < 300 & mouseX > 200 && mouseY > 350) {
        tigerRoarSound.play();
    }
    else {
        tigerRoarSound.pause();
    }

    //sound of a golf ball going in the hole when clicked on flag
    if (mouseX < 330 & mouseX > 300 && mouseY > 250 && mouseY < 320) {
        golfBallCupSound.play();
    }
    else {
        golfBallCupSound.pause();
    }
}

In the spirit of Tiger Woods winning his 82nd PGA Tour win this past weekend, I wanted to use a picture of him at Augusta National for the Masters and incorporate multiple sounds. I included a tiger roar from the animal itself when you click on Tiger Woods, a sound of the golf ball being hit when clicked on Tiger’s caddy on the right, a sound of the crowd cheering when clicked on the many people in the back of the green, and the sound of a golf ball going into the hole when clicked on the yellow flag on the green.

Nadia Susanto – Looking Outwards – 10

The Computer Orchestra is an interactive orchestra consisting of multiple computers. It was created by fragment.in, and the goal was to let the user conduct their own orchestra and music. The conductor’s hand movements are accurately recognized using an Xbox Kinect motion controller that is connected to a central computer. Instructions are given to many musician screens. Screen-musicians then send the sound to the conductor and produces visual feedback.

What I love most about the Computer Orchestra is that it crowdsources sounds that people can upload, and then the musician can access it and play it. It’s incredible to see that one person can control the music through simple hand motions and gestures. The simple interface of the centralized computer also makes it extremely easy for the conductor to change where he wants vocals, violin, etc.

Video demonstrating a user setting up the Computer Orchestra and then conducting it with his hand motions.
Another demonstration of a conductor using the Computer Orchestra for a Ted Talk

To learn more about the Computer Orchestra, click the link below:

https://www.fragment.in/project/computer-orchestra/

Nadia Susanto – Project 09 – Computational Portrait

sketch

// Nadia Susanto
// nsusanto@andrew.cmu.edu
// Section B
// Project-09-Computational Portrait

var underImage;

function preload() {
    //preloading image from imgur
    //var myImage = "https://i.imgur.com/R80wzCp.jpg";
    var myImage = "https://i.imgur.com/uezsOBb.jpg";
    underImage = loadImage(myImage);
}

function setup() {
    createCanvas(480, 480);
    //resize the image so it fits the canvas
    underImage.resize(480, 480);
    background(0);
    underImage.loadPixels();
    frameRate(100);

}

function draw() {
    var px = random(width);
    var py = random(height);
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    //gets colors from specific image location
    var colorXY = underImage.get(ix, iy);

    //random rectangles
    stroke(colorXY);
    strokeWeight(random(1, 10));
    noFill();
    rect(ix, iy, 20, 10);
}

//random ellipses when mouse is pressed
function mouseDragged() {
    ellipse(mouseX, mouseY, random(5, 50), random(5, 30));
}

For my portrait picture I used a picture of myself in a bamboo forest in Japan. I decided to use this picture because it has many different shades of green to the image. Since there was only one main color, I wanted to incorporate different shapes. The main shape is a rectangle, and when the mouse is dragged it switches to ellipses.

A few seconds
30secs – 1 minute
Original image

Nadia Susanto – Looking Outwards – 09

I looked at Ammar Hassonjee’s LO 2. He studied a generative art project called “Breathing Wall II” by Behnaz Farahi in 2014, a USC architecture professor. The installation is made out of wood, PVC, and fabric. To capture the hand motions and signals they use many systems like Leap Motion system and DC systems then project contour lines on the wall.

Video demonstrating the Breathing Wall installation

Ammar liked the relationship between movement, light, and color and how it gave power to users to interact with that environment. He also says his favorite types of art are ones that are adaptive and involves user activity. I can agree that this is my favorite type of art as well because involving human behavior brings extra beauty to the artwork.

What I love about this project is that it seems so simple and has a deeper meaning to it. Farahi mentioned how mobile devices used touch and gesture-based languages like swiping, clicking, or dragging for natural control. With the rise of technology and social media, we are entranced by this environment of likes and scrolling through people’s photos with meaningless connections. We forget the real surrounding environment around us, so this project sets a great reminder that those basic controls can be used to control the surrounding environment.

Farahi interacting with installation
A closer look at a user interacting with the wall. Notice also the contour lines on the wall.

To learn more about this installation, click the link below:

http://behnazfarahi.com/breathing-wall-ii/

Nadia Susanto – Looking Outwards – 08

Kim Rees is the Head of Information Visualization at Periscopic, a socially conscious data visualization firm based in Portland, Oregon. Kim has garnered many awards and has presented herself to be a prominent figure in the world of information visualization. Kim’s work has been featured in the MOMA, the Parsons Journal of Information Mapping, and was an award winner in the VAST 2010 Challenge.

I really admire her work because she is taking her skills of creating beautiful pieces of information visuals to talk about bigger societal issues that are needed in this day and age. Below is one of her famous works regarding gun violence. What many don’t understand is that there is an overwhelming magnitude of loss from US gun deaths. The orange line depicts the person that died, and the white line that continues from the orange depicts how long they could’ve lived for. By this heart-wrenching visual, its easy to see how many years of life were stolen at the hands of guns.

An example of what Kim Rees did at Periscopic to visually describe gun violence

To see the whole visual from above come to life, click the link below:

https://guns.periscopic.com/?year=2013

While Kim Rees was unable to showcase her works with Periscopic at Eyeo, her talk on the future of data was inspiring. She was not afraid to seem controversial and had great insights into privacy, actualized data, and more. Kim values open data and believes that using more and more data can help solve social issues. Watch her talk below at Eyeo 2014.

Video of Kim Rees’s talk at the 2014 Eyeo Festival