dayoungl & kyungak – Final project

Please refer to the gif file for how the game works.The objective of our game, “TOM” is to survive from the bombs by navigating its to stay away from bombs. A little bonus of the game would be eating hearts to achieve higher points. One can navigate the character using the arrow keys. The scoreboard on the top right corner keeps track of the hearts the character eats. Each time character consumes a heart, it will be logged as +1 on the scoreboard; whenever the character comes into contact with the puffs, it will result in -1 point from the scoreboard. When the character comes into contact with the bomb, the game will end with a “gameover” message. When heart and bomb collides with each other, the heart will turn into a little fire icon indicating that the heart is gone.

Download the PLAY-ME version to play the game on your device.

PLAY-ME
GRADE-ME

data-width=”800″ data-height=”800″TOM-FINAL

//Kyunga Ko
//15104B
//kyungak@andrew.cmu.edu
//Capstone Project:Tom and Toms (COMPLETE VERSION)

var bomb;
var puff;
var heart;
var explosion;
var tomcharacter; 
var eating;
var gameover;
var scoreboard;
var score = 0;

function preload() {

  //Preloading gameover and scoreboard image
  gameover = loadImage("https://i.imgur.com/VlLC4xC.png");
  scoreboard = loadImage("https://i.imgur.com/8ke3Z26.png");

}

function setup() {
  createCanvas(800,800);  

  //Grouping variables
  bomb = new Group();
  puff = new Group();
  heart = new Group();
  explosion = new Group();
  tomcharacter = new Group();
  eating = new Group();

  //Create bomb at random locations on canvas
  for(var i=0; i<15; i++) {
    createBomb(random(0,width), random(0,height));
  }

  //Single character "Tom" is created
  for(var i=0; i<1; i++) {
    createTom(100, 100);
  }

}

function draw() {
  background(230);
  //Reduce the size of the heart by the rate of the frameCount
  if(frameCount%60==0 & heart.length<5) {
    //Create hearts at random locations on the canvas
    createHeart(random(0,width), random(0,height)); 
  }
  
  //Recycle puff on four sides = randomly displaced
  if(frameCount%60==0 & puff.length<10) {
    var canvasside = floor(random(0,4));
    
    if(canvasside == 0) //left
      createPuff(0, random(height));
    if(canvasside == 1) //right
      createPuff(width, random(height));
    if(canvasside == 2) //top
      createPuff(random(width), 0);
    if(canvasside == 3) //bottom
      createPuff(random(width), height);
      
    }
  
  //(BOMB) Bomb orientation in general
  for(var i = 0; i<bomb.length; i++) {
  
    var b = bomb[i];
    b.noisePosition += 0.1;
    b.rotation += (noise(b.noisePosition)-0.5)*10;
    b.setSpeed(2, b.rotation);
    randomrelocation(b);

  }
  
  //(PUFF) When puff collides with bomb and heart
  for(var i = 0; i<puff.length; i++) {
      var p = puff[i]; 
      randomrelocation(p);

      for(var j = 0; j<bomb.length; j++) {
        var b = bomb[j]; 
        //Distance btw puff and bomb
        var dis = p5.Vector.dist(p.position, b.position); 
        
        //Puff and bomb does not attract
        if(dis < 70) {   
          var angle = degrees(atan2(b.position.y-p.position.y, 
            b.position.x-p.position.x));
          //repel
          var attraction = -30 / dis;
          p.addSpeed(attraction, angle);

        }
      }

      for(var z = 0; z<heart.length; z++) {
        var h = heart[z]; 
        //Distance btw heart and puff
        var dis2 = p5.Vector.dist(p.position, h.position); 
        
        //Puff and heart attract
        if(dis2 < 30) {   
          var angle2 = degrees(atan2(h.position.y-p.position.y, 
            h.position.x-p.position.x));
          var attraction2 = 100 / dis2;
          p.addSpeed(attraction2, angle2);

        }

      }
  }

  //(HEART) When heart collides with bomb and puff
  for(var i = 0; i<heart.length; i++) {

      var h = heart[i]; //save in a temp variable
      h.scale = map(h.life, 300, 0, 1, 0);
      h.overlap(bomb, bombeatsheart);
      h.overlap(puff, puffeatsheart); 

  }

  //(TOM) When Tom collides with bomb and heart
  for(var i = 0; i<tomcharacter.length; i++) {

    var t = tomcharacter[i]; //save in a temp variable
    t.overlap(bomb, bombmeetstom); 
    t.overlap(heart, heartmeetstom);
    t.overlap(puff, puffmeetstom);
   
  }

  //Scoreboard
  image(scoreboard, 580, 15); //Scoreboard image
  textSize(30);
  fill(0); 
  text(score,670,90); //Displays the score

  //Draws all sprites
  drawSprites();

}

//Makes Tom move up, down, left, right using the arrow keys
function keyPressed(){
  var tab = 20;
  var clickCount = 0;

  for (var i = 0; i<tomcharacter.length; i++ ){
    var t = tomcharacter[i];

    if (keyIsPressed === true){
      clickCount ++; //clickcount increases with movement
    }

    if (keyIsDown(LEFT_ARROW)){
      t.position.x -= tab; //left
    }

    if (keyIsDown(RIGHT_ARROW)){
      t.position.x += tab; //right
    }

    if (keyIsDown(UP_ARROW)){
      t.position.y -= tab; //up

    } else if (keyIsDown(DOWN_ARROW)){
      t.position.y += tab; //down
      }
    
  }
  
}

//The object dissapears outside the canvas and is randomly located again
function randomrelocation(w) {
   //wrap around the screen
    if (w.position.x > width)
      w.position.x = 0;
    if (w.position.x < 0)
      w.position.x = width;
    if (w.position.y > height)
      w.position.y = 0;
    if (w.position.y < 0)
      w.position.y = height;

}

//When puff eats the heart, they multiply x2 
function puffeatsheart(puff, heart) {
  puff.remove();
  createPuff(heart.position.x, heart.position.y);

}

//When Tom meets puff, score decreases by one
function puffmeetstom(puff, tomcharacter) {
  tomcharacter.remove();
  score--;

}

//Bomb eats/gets rid of the heart + explosion sign
function bombeatsheart(bomb, heart) {
  bomb.remove();
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  createExplosion(heart.position.x, heart.position.y);
  

}

//Tom eats heart and +1 sign comes up
function heartmeetstom(heart, tomcharacter) {
  tomcharacter.remove();
  aftereatingheart(heart.position.x, heart.position.y);
  score++;
  
}

//When bomb meets Tom, Tom dies and game over sign comes up
function bombmeetstom(bomb, Tom) {
  bomb.remove();
  noLoop();
  push();
  scale(0.7);
  image(gameover, 175, 400);
  pop();

}

//Bomb is created
function createBomb(x, y) {

  var b = createSprite(x, y);
  b.addAnimation("bomb", "https://i.imgur.com/N4m1kty.png");
  b.setSpeed(2, random(0,360));
  b.noisePosition = random(0, 1000);
  b.maxSpeed = 2;
  bomb.add(b);

}

//When bomb eats heart, explosion is created to indicate that a heart was ate
function createExplosion(x, y) {

  var e = createSprite(x, y);
  e.addAnimation("bomb", "https://i.imgur.com/wzVAcbK.png");
  e.setSpeed(2, random(0,360));
  e.noisePosition = random(0, 1000);
  e.maxSpeed = 2;
  explosion.add(e);

}

//After Tom eats heart, +1 sign is created
function aftereatingheart(x, y) {

  var a = createSprite(x,y);
  a.addAnimation("eat", "https://i.imgur.com/b9C1Xyl.png");
  a.setSpeed(2, random(0,360));
  a.noisePosition = random(0, 1000);
  a.maxSpeed = 2;
  eating.add(a);

}

//Puff is created
function createPuff(x, y) {

  var p = createSprite(x, y);
  p.addAnimation("puff", "https://i.imgur.com/cs8Mkcr.png");
  p.setSpeed(-2, random(0,360));
  p.maxSpeed = 1;
  puff.add(p);

}

//Heart is created
function createHeart(x, y) {
  
  var h = createSprite(x, y);
  h.addAnimation("heart", "https://i.imgur.com/u2uRAYl.png");
  h.life = 300; 
  heart.add(h);

}

//Tom is created
function createTom(x, y) {

  var t = createSprite(x, y);
  t.addAnimation("tomcharacter", "https://i.imgur.com/Q8FnPtP.png", 
    "https://i.imgur.com/QzOR227.png");
  tomcharacter.add(t);

}

















dayoungl Looking Outwards 12

 

For the final project, we took our concept from “Pac Man” and an online game called “agar.io”. Because everyone knows how Pac Man goes, I will discuss more on agar.io. My first encounter with agar.io was when I was back in high school. Everyone in my grade used to play this game and how this game works is that you simply log-in to the team server and you can play with your friends that way. This game was developed by  a 19 ear old Matheus Valadares. The concept of the game is to “bulk up” by eating other cells in the game; more specifically, The objective of Agar.io is to grow a cell on a petri dish by swallowing both randomly generated pellets (agar), which slightly increases a cell’s mass, and smaller cells, without being swallowed by larger cells. This game was coded using C++ and javascript.

Here is a link to the game.

 

dayoungl Final Project Proposal

For the final Project, I will be collaborating with Kate Ko from section B. Together, we will be using p5js to create a Pac-man inspired interactive game which will be divided into 3 stages. The basic components of the game include a main character in which users are able to control with keys, enemies of the main character, and the “foods” the character feeds on to either get larger or smaller. From stage 1 to 3, the stages get harder with more frequencies of “enemies” appearing on the screen.  In order to progress to the next stage, the users need to reach certain points. Users gain points by the number of enemies they defeat..? We are still working on the structure of the game, but I hope this give a general idea of what our game will be like. In terms of diving up workload, we will be working together to create the basic structure of the program (the ; I will be focusing mainly on the visual components and integrating them into the code and Kate will be focusing on the coding that’s needed afterwards, mostly working on interactive element of the code.

dayoungl Looking Outwards-11

For this week’s looking outwards, I looked into a concept of computer orchestra. The computer orchestra was created by group of students from ECAL, which stands for the University of Art and Design of Lausanne, Switzerland in 2013. What is interesting about their project is that the compute orchestra is not an orchestra based on computer generated sound but sounds that users upload to a server that’s later integrated into a form of an orchestra. Just like any other human orchestra, there is a conductor (a person) and musicians (computers). Rather than describing it in words, It’s really easier to understand the concept when you look at the attached video above. The way that the voices uploaded to the server is played according to gestures of the conductor; of course, conductor’s gestures are programmed accordingly and conductor can control so many aspects of the orchestra just by using his or her body. The students programmed the computer orchestra using Processing, SimpleOpenNi, and Ableton Live. On their website, they also specified that they used 10-12 computers, tripods, and Kinect.

Computer Orchestra is an interactive installation consisting of multiple computers. Close to a configuration of a classical orchestra, it proposes a new approach to music by allowing the user to conduct his/her own orchestra.

Movements of his/her hands are recognized accurately with a Kinect motion controller connected to a central computer. It will then give instructions to a multitude of musician screens. Screen-musicians then not only send sounds back to the conductor but also produce visual feedback.

dayoungl Project-11

sketch

//Sharon Lee
//dayoungl@andrew.cmu.edu
//Section E
//Project 11 - freestyle turtle

// makeTurtle(x, y) -- make a turtle at x, y, facing right, pen down
// left(d) -- turn left by d degrees
// right(d) -- turn right by d degrees
// forward(p) -- move forward by p pixels
// back(p) -- move back by p pixels
// penDown() -- pen down
// penUp() -- pen up
// goto(x, y) -- go straight to this location
// setColor(color) -- set the drawing color
// setWeight(w) -- set line width to w
// face(d) -- turn to this absolute direction in degrees
// angleTo(x, y) -- what is the angle from my heading to location x, y?
// turnToward(x, y, d) -- turn by d degrees toward location x, y
// distanceTo(x, y) -- how far is it to location x, y?
var t1;
var t1;

function setup(){
  createCanvas(400,400);
  background(220);
  noLoop();

  t1 = makeTurtle(width/2, height/2); //start drawing from the centre
  t1.setColor(0);
  t1.setWeight(1.5);
  t1.penDown();
  for (var i = 0; i < width; i ++){
    //randomize stroke colour & direction
    var x = floor(random (1,4));
    if (x == 1){
      t1.setColor("yellow");
      t1.forward(12);
      t1.right(90);
    }
    if(x == 2){
      t1.setColor("red");
      t1.forward(12);
      t1.left(10); // adding a bit of randomness to 90 degree angles
    }

    if(x == 3){
      t1.setColor("blue");
      t1.back(20);
      t1.left(90);
    }
  }
}

//turtle API
function turtleLeft(d) {
    this.angle -= d;
}
 
 
function turtleRight(d) {
    this.angle += d;
}
 
 
function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}
 
 
function turtleBack(p) {
    this.forward(-p);
}
 
 
function turtlePenDown() {
    this.penIsDown = true;
}
 
 
function turtlePenUp() {
    this.penIsDown = false;
}
 
 
function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}
 
 
function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}
 
 
function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}
 
 
function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}
 
 
function turtleSetColor(c) {
    this.color = c;
}
 
 
function turtleSetWeight(w) {
    this.weight = w;
}
 
 
function turtleFace(angle) {
    this.angle = angle;
}
 
 
function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}











For this project, I wanted to create something simple yet interesting. Instantly, I was reminded of legos because how it works is very simple – you simply stack the blocks on top of each other. However, there are millions of ways to apply this simple mechanism to create so many different things. Another source of inspiration for the project came from one of my favourite painter, Mondrian. The three primary colours combined with 90 degree angles are indications of my inspiration from Mondrian’s works.

dayoungl Project -10

sketch

//Sharon Lee
//dayoungl@andrew.cmu.edu
//Section E
//Assignment 10 - Generative Landscape
var terrainSpeed = 0.00015;
var terrainDetail = 0.001;
var parasol = [];
var cBlue = (115,151,232);
var cWhite = (234,238,247);
var x;
var y;
var location;


function preload(){
    imgParasol = loadImage("https://i.imgur.com/9wvs2bI.png");
    airplane = loadImage("https://i.imgur.com/M6sAe2x.png");
    airplane2 = loadImage("https://i.imgur.com/5j9Uq5v.png");
}

function updateParasols(){
    for (var i = 0; i < parasol.length; i ++){
        parasol[i].move();
        parasol[i].display();  
    }
}

function addParasols(){
    var a = random(1);
    if (a < 0.03){
        parasol.push(makeParasols(width));
        parasol.push(makeParasols(height));
    }
}

function moveParasols(){
    this.x += this.speed;
}


function makeParasols(pointX){
    var parasol1 = {x: pointX,
        number: floor(random(1,3)),
        speed: 0.001,
        height: random(0,50), 
        move: moveParasols,
        display: displayParasols}
    return parasol1;
}

function oceanTerrain(){
    //ocean layer-1
    noStroke();
    fill(77,124,191);
    beginShape();
    for (var x = 0; x < width; x++){
       var t = (x * terrainDetail) + (millis() * terrainSpeed);
       var y = map(noise(t), 0, 1, 0, height - 30);
        vertex(x,y);
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE);

    //ocean layer-2
    noStroke();
    fill(77,124,191,120);
    for (var x = 0; x < width; x ++){
        var t = (x* terrainDetail * 2) + (millis() * terrainSpeed);
        var y = map(noise(t/2), 0, 1, 10, height - 50);
        vertex(x,y);    
    }
    curveVertex(width, height);
    curveVertex(0,width);
    endShape(CLOSE);
}

function displayParasols(){
    push();
    translate(this.x, this.height);
    for (var i = 0; i < this.number; i++){
        image(imgParasol, random(0, width),random(30,90));
    }
    pop();
}

function setup() {
    createCanvas(480,300);
    for(var i = 0; i < 5; i ++){
        location = random(width);
        parasol[i] = makeParasols(location);
    }
    frameRate(10);
}

function draw() {
    background(228,211,207);
   
    updateParasols();
    addParasols();
    displayParasols();
    moveParasols();
    makeParasols();
    oceanTerrain();

    image(airplane2, mouseX - 80, mouseY - 50);
    push();
    tint(255,128);
    image(airplane, mouseX + 50, mouseY - 150);
    pop();

}   







For project 10, I aimed to create a bird-eye-view landscape of a beach. Using the given terrain code, I manipulated it and lower the amount of noise so it resembles the smooth curves of the waves instead of pointy and rough terrain of mountains that the code was originally intended for. I added parasols as the elements to show the panning of the “camera”. I also added in airplane and its shadow just as a fun element users could play around by using their mouse.

dayoungl Looking Outwards – 10

Caroline Sinder’s Nudge Nudge

Idea sketch
Diagram of her methods
Prototype in a form of a lamp.

For this week’s Looking Outwards, we are focusing on women practitioners in the field of computational design. From a list given from the professor, I randomly selected an artist named Caroline Sinders. She introduced herself as many things but among them, I think how she described herself as a machine learning designer and a digital anthropologist was quite interesting. Looking through her website, I realized that a lot of the things she do and experiments with are things that are done frequently in CMU such as Human Computer Interaction (HCI) and merging of technology and design. Especially, I made a strong connection looking at one of her work “Nudge Nudge”, which is a wearable watch that doesn’t tell time but tells something in relation to time — Google Calendar Events. The idea itself was so clever to begin with. Her wearable tells time in relation to a meeting, class, or anything marked in the calendar and tells you how much time you have in between through variation of colour. Another thing that draw me in was her ideation process; it was very similar to what we do in research methods class as Design majors. She not only thought about the aesthetics and the delivery of the idea of changing colour but also about people’s response to the colour change through experimenting with putting stickers on participants and how distracted they felt when they were reminded of having stickers on their shirts; this experiment was done to measure the level of distraction people not wearing the Nudge would get when they are near an individual wearing Nudge. Little considerations like this revealed something I learned in class and through her post, I was able to see my learnings put into practice.

dayoungl Looking Outwards -09

yoonyoung’s looking outwards 1

For this week’s Looking Outwards, I looked into my friend Yoonyoung’s first Looking Outwards post which highlights the BMO200 Fountain. (The topic of the first looking outwards post was investigating technological art or design that inspires you.) BMO is a bank in Montreal and this fountain was made in celebration of the 200th anniversary of the bank. I found her post on this piece of object interesting because the project was made with not only the artists but also the members and the employees under BMO. Although there isn’t much written about the specific contributions the employees of the bank made to the final piece, the idea of interactive imagery of water falling into a pond is stunning; with this piece, the users can “throw” a coin of wish on their mobile devices. I think the interactive portion of the project is a great representation of how machines and technology is able to copy or iterate human motion. The idea behind this is that interaction can happen separately from just a single visual space but also the individual users’ devices too. The YouTube video above is a good compilation of the process of the project from the beginning to end.

dayoungl Project-09

sketch

//Sharon Lee
//dayoungl@andrew.cmu.edu
//Section E
//Project-09 Portraits
var img;
var smallPoint = 3;
var largePoint = 6;

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

function setup() {
  createCanvas(640,360);
  imageMode(CENTER);
  noStroke();
  background(255);
  img.loadPixels();
}

function draw() {
  var pointilize = map(mouseX, 0, width, smallPoint, largePoint);
  var x = floor(random(img.width));
  var y = floor(random(img.height));
  var pix = img.get(x, y);
  //fill using pixel colours from the iamge
  fill(pix, 50);
  //create random size hearts
  ellipse(x, y, pointilize, pointilize);
  ellipse(x + pointilize,y, pointilize, pointilize);
  triangle(x - pointilize/2 - 1, y, x + pointilize *1.5, y, x + pointilize/2 + 1, y + pointilize);
}



dayoungl Looking Outwards – 08

https://twitter.com/sandsfishhttps://twitter.com/sandsfishhttps://twitter.com/sandsfish

https://www.sandsfish.com/skullwhispering/

For this week’s Looking Outwards, I chose to study the work of Sands Fish who is currently researching at a MIT Media Lab’s Civic Media Group. He introduces himself as both an artist and a researcher whose interests lie in the field of computer science and design. I thought his works would be interesting to investigate because his works lie closely to the environment of CMU where I’m studying design. I thought it would be interesting to learn about his works and try to identify with some of the design practices I am learning and doing here in CMU.

For his Eyeo 2017 lecture, he focused on “Building Parallel Realities”. Sands Fish specifically focused on futures and how speculative designs can contribute to ” shift us into another reality via objects and devices that aren’t born of the status quo, or of our own time or place”. Mainly, his lecture focuses on the ways to integrate individuals from different backgrounds into one. In this talk, Sands explores how, using design, art, and media, we can embody ideas and worlds in objects, and look critically at our assumptions about how our world has to be. He details his work at the MIT Media Lab building provocative police futures to question who participates in this design space, and how we might create more humane alternatives.