## kyungak + dayoungl – finalproject

For our final project, Sharon and I made a game named, “TOM.” In order to play TOM, users are to:

1. Use the arrow keys (up, down, left, right) to move the main character, TOM
2. Avoid contact with bombs – if contact is made, TOM dies and the game is over
3. Avoid contact with puffs – if contact is made, TOM loses a point (-1)
4. Consume hearts – if contact is made, TOM earns a point (+1)
5. Notice: If bombs make contact with hearts, the bomb bursts and gets rid of the hearts
6. Notice: Hearts randomly get patched across the canvas. It shrinks in size and disappears if not consumed by TOM.
7. Notice: When the game starts, you might immediately see the game over sign because the randomly generated bombs overlap with the initial position of TOM (100,100). Don’t panic and just refresh the webpage so you can restart.

Your goal is to get as much point as possible. Compete with friends and see who can get the most points!

PLAY ME

``````//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 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;

}
}

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;

}

}
}

//(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.setSpeed(2, random(0,360));
b.noisePosition = random(0, 1000);
b.maxSpeed = 2;

}

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

var e = createSprite(x, y);
e.setSpeed(2, random(0,360));
e.noisePosition = random(0, 1000);
e.maxSpeed = 2;

}

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

var a = createSprite(x,y);
a.setSpeed(2, random(0,360));
a.noisePosition = random(0, 1000);
a.maxSpeed = 2;

}

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

var p = createSprite(x, y);
p.setSpeed(-2, random(0,360));
p.maxSpeed = 1;

}

//Heart is created
function createHeart(x, y) {

var h = createSprite(x, y);
h.life = 300;

}

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

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

}

``````

## kyungak-lookingoutwards-12

(Jason Rohrer, “Inside a Star-Filled Sky”, 2011)

https://www.artsy.net/article/artsy-editorial-are-video-games-art

Jason Rohrer is a computer programmer and a game designer that not only produces games for its original purpose, but also as art. He codes creative games that are usually sold and played in the public domain, but also combines a series of them to exhibit as art works. Most shame came from the public who thought that games could not be art. However, Rohrer still believed them as artworks because creation of games was no different from painting to him. When I saw his works, I was inspired to create something similar to the pieces in his exhibitions. Similar to the format of the Pac man game, I wanted to have vivid graphics but a simple mechanism that kept the game running. Rohrer’s games and visuals were a great inspiration for me.

(Jenova Chen, “Flower”, 2009)

http://jenovachen.info/flower/

Jenova Chen is the designer of the playstation game, “Flower” that was released in 2009. Although this game is an actual game, it is largely considered as an art work for its aesthetic value. The interaction of the game with the players isn’t about winning or competing for a prize. The wander and exploration through the landscapes and the stunning visuals were the initial goals of this game. As visuals are important for the final project I’m planning, I wanted to get inspirations from the way she portrayed her objects. Her project was beautiful.

## kyungak-final-project-proposal

For the final Project, I will be collaborating with Sharon Lee from section E. 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. Sharon will focus on the visual materials, and code stage 1 (moving the characters and imbedding the animation). I will follow up with her code and add 2 more stages to the code. I will add attraction and repel code to the characters and the enemies.

## kyungak-project-11-Composition

``````//Kyunga Ko
//15104B
//kyungak@andrew.cmu.edu
//Project-11

var turtle = [];
var redcolor = 100;
var greencolor = 150;
var bluecolor = 200;
var xinc = 0;
var yinc = 0;
var zinc = 0;

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

background(255);

for(var i = 0; i < 50; i++) {
turtle[i] = makeTurtle(random(width),random(height));
turtle[i].setColor(color(redcolor,greencolor,bluecolor));
turtle[i].setWeight(0.4);
turtle[i].penDown();
frameRate(10);
}

}

function draw(){

for (var i = 0; i < 50; i++) {
turtle[i].setColor(color(redcolor,greencolor,bluecolor));
turtle[i].forward(xinc);
turtle[i].right(zinc);
turtle[i].back(xinc);

}

map(mouseX,0,600,0,5);
xinc = random(0,30);
yinc = random(0,30);
zinc = random(0,mouseX);

}

function mousePressed(){

redcolor = random(0,255);
bluecolor = random(0,255);
greencolor = random(0,255);

}

function turtleLeft(d){this.angle-=d;}
function turtleRight(d){this.angle+=d;}
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;}``````

I wanted to express snowflakes through the turtles function. When you move mouseX around the canvas, it changes the angle to which the snowflakes spread. When you click the mouse, the color changes. It will create a dynamic and a non-symmetrical snowflake across the canvas. It was a very interesting process, and the results were satisfying.

## kyungak-lookingoutwards-11

(Simon de Diesbach, Jonas Lacôte, Laura Perrenoud,  “The Computer Orchestra”, 2013)

The creators of “The Computer Orchestra” initially met  at University of Art and Design of Lausanne in Switzerland during their Bachelor’s degree in media and interaction design. This project started as a small project, but later grew into an amazing piece that was exhibited in various parts of the world.

“The Computer Orchestra” is an interactive installation that allows viewers to conduct their own orchestra.  Users can upload or download music samples and integrate them to their own taste using the simple interface within in the computer. The sounds also change according to space. Kinect connected to the center of the computer detects motion of the user’s hands and position and interacts accordingly.

I personally admire the interactivity of this artwork. Being able to produce an orchestra that usually needs a handful of people with computers sounds amazing. The original thought and the combination of interactiveness made the artwork accessible and fun. I feel like this artwork was also educational, which makes it extra worthy to exhibit.

## kyungak-project-10-generative-landscape

``````//Kyunga Ko
//15104B
//kyungak@andrew.cmu.edu
//Project 10

var terrainspeed = 0.0005;
var terraincurve = 0.025;
var binocular;
var cactus = [];

//loads the images from imgur (binoculars and cactus)
}

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

//initially iterates cactus
for (var i = 0; i < 5; i++){
var location = random(width);
cactus[i] = makeCactus(location);
}

frameRate(10);
}

function draw() {
background(214,196,211,200);

backgroundmountain();
bottomsand();

updateCactus();
displayCactus();
makeCactus();
moveCactus();

// structure of sun
fill(255,0,0,150);
noStroke();
ellipse(70,70,50,50);
stroke(255,0,0,150);
strokeWeight(3);
line(70,30,70,45);
line(70,95,70,110);
line(30,70,45,70);
line(95,70,110,70);

//Binoculars
image(binocular,mouseX-500,mouseY-500);
}

//updating cactus location and movement
function updateCactus(){
for (var i = 0; i < cactus.length; i++){
cactus[i].move();
cactus[i].display();
}
}

// adding new cactus from the left side of the canvas
var a = random(1);
if (a < 0.03) {
cactus.push(makeCactus(width));
}
}

//moving the position of cactus
function moveCactus() {
this.x += this.speed;
}

//drawing and displaying cactus
function displayCactus() {
push();
translate(this.x, this.height);
for(var i=0; i<this.number; i++) {
image(cactus1,this.x*i, 100);
}
pop();
}

//making cactus + variables needed to make cactus
function makeCactus(birthx) {
var cactus2 = {x: birthx,
number: floor(random(1,2)),
speed: -3,
height: random(90,100),
move: moveCactus,
display: displayCactus}
return cactus2;
}

//function that draws the mountains
function backgroundmountain() {

//back mountain
noStroke();
fill(9, 69, 32);
beginShape();
//for loop makes back layer of mountain
for (var x = 0; x < width; x++) {
var t = (terraincurve * 2 * x) + (millis() * terrainspeed);
var y = map(noise(t/2), 0, 1, 70, height);
curveVertex(x, y);
}
curveVertex(width, height);
curveVertex(0,width);
endShape(CLOSE);

//front mountain
noStroke();
fill(89, 107, 89,200);
beginShape();
//for loop makes front layer of mountain
for (var x = 0; x < width; x++) {
var t = (terraincurve * x) + (millis() * terrainspeed);
var y = map(noise(t/2), 0, 1, 0, height);
curveVertex(x, y);
}
curveVertex(width, height);
curveVertex(0,width);
endShape(CLOSE);

}

//function that draws the sand layer on the bottom
function bottomsand() {

//front mountain
noStroke();
fill(179,145,86);
beginShape();
//for loop makes the sand layers on the bottom
for (var x = 0; x < width; x++) {
var t = (terraincurve * x) + (millis() * terrainspeed);
var y = map(noise(t/2), 0, 1, 370, height);
curveVertex(x, y);
}
curveVertex(width, height);
curveVertex(0,width);
endShape(CLOSE);

}``````

For this project, I wanted to make a landscape that contained both a desert and a forest. On the bottom desert layer, I altered the original terrain function by reducing the amount of noise. This allowed me to make a smoother surface of sand. For the random cactuses, I made them into javascript objects and coded accordingly. The cactus image was photoshopped by me and embedded through imgur. I then utilized the provided terrain code to slightly alter and make the forest layers. I then gave a little twist by photoshopping a binocular image and putting it on top of the landscape function. It made it as if you are looking through the binoculars from a distance. Although the process was a bit rocky, I managed to understand and use the javascript object function. I was able to learn a lot through this project.

## kyungak-lookingoutwards-10

(Kate Hollenbach, USER_IS_PRESENT, 2017)

Kate Hollenbach is an artist and a designer that works with computational programs to generate her works. She holds MFA from UCLA and a degree of computer science and engineering from MIT and was a director of design and computation at Oblong industries. Now, she examines new technologies to create an interactive space that explores the connection between one’s body, gestures, and physical space in relation to technological devices, such as phones.

“USER_IS_PRESENT” is an expansion of the relationship I just stated above. The work consists of three monitors that split across virtual and physical spaces. Hollenbach recorded three different point of views of the phone: the actual screen, back camera, and front camera. She captured the motion of both the user, phone, and the outside world and tried to bring them altogether. I admire the concept of her work. The spontaneous capture of the three view points looked fascinating when they were put together. The emphasis on being in both virtual and physical space seemed amazing.

## kyungak-project-09-portrait

``````//Kyunga Ko
//15104B
//kyungak@andrew.cmu.edu
//Project 09

var selfportrait; //self portrait image
var x = []; //x position array
var y = []; //y position array
var dx = []; //x velocity array
var dy = []; //y velocity array

var imageURL = "https://i.imgur.com/pvmAYGW.jpg"
}

function setup() {
createCanvas(480, 480);
noStroke();

//for loop for assigning random values for x,y,dx,dy
for (var i=0; i<150; i++) {
x.push(random(width));
y.push(random(height));
dx.push(random(-10,10));
dy.push(random(-10,10));
}
}

function draw() {
//image(selfportrait,-250,-50);

//for loop for
for (var j=0; j<x.length; j++) {
//pixel colors from image is stored into x and y array
var color = selfportrait.get((x[j]+250), y[j]+50);
//canvas is filled with image color
fill(color);
//ellipse fills the canvas + random movements with dx,dy
ellipse(x[j],y[j],10,10);
x[j]+=dx[j];
y[j]+=dy[j];
}

//xpos and ypos is determined by mousex and mousey
var xpos = floor(mouseX);
var ypos = floor(mouseY);
//color is assigned to mousex and mousey
var color = selfportrait.get((xpos+250), ypos+50);

fill(color,25);
noStroke();
//according to mouse position canvas is colored
rect(xpos,ypos,10,10);

}
``````

1                               2                              3

1. A loop of 150 ellipses initially color the canvas
2. MouseX and MouseY function is used to fill in the blanks
3. Final portrait is done

For this project, I was able to reuse functions and skills that I previously learned from this class. I set up a series of position and velocity arrays to form a loop of circles that randomly moved across the canvas with the image colors. After most of the image was colored, you can also custom color the blanks with the mousex and mousey function. I thought this project was really interesting, and I am pretty satisfied with the result.

## kyungak-lookingoutwards-09

(Walt Disney Animation Studios, 2012, Paperman)

Link to the original post: https://courses.ideate.cmu.edu/15-104/f2017/2017/09/28/looking-outwards-05-3d-graphics/

As a student that personally admires all of the Disney films, I was very thrilled to come across Sarah’s post about Disney’s 3D graphics in the short film Paperman. Although this film is black and white, the intricate movements and details put into the figures, objects, and backgrounds make the scene live as if they are colored and real. I very much agree with Sarah’s comment about Disney sticking to the older practice of creating animation. The combination of artistic skills enabled the production of such a solid piece of work. Especially after knowing how intense and time consuming it is to draw each frame and convert it to 3D graphic images, I have deep respect to the animators at Walt Disney animation studios.

## kyungak-lookingoutwards-08

(Jake Barton, “Like Falling In Love”, 2012)