My final project is a simple game called, “Cloudy with a chance of dropping.”
it is basically a game in which you have to press one key, “g” to change direction of your character, in order to avoid the droppings from the sky. The game gets more and more difficult as you go
/*
Jihoon Park
Section A
jihoonp@andrew.cmu.edu
final project : cloudy with a chance of dropping
*/
var xPos = 300; //x position of person
var yPos =450; //y position of person
var dir = true; //direction factor for movement of person
var timer = 0; //reaction time for entering direction change
var interval = 10;
var gameDifficulty = 0.008; //game difficulty
var minimumDistance; //distance between person and dropping\
var playGame = true;
function setup() {
createCanvas(400, 500);
for (var i=0; i<5; i++) {
var droppingX = random(width);
var droppingY = random(height);
dropping[i] = makeDropping(droppingX, droppingY);
}
}
function draw() {
//game boundary
background(255);
rect(1,1, width-2, height-2);
//groundline
strokeWeight(4);
stroke(100);
line(1,height-13, width-1, height-13);
//rendering droppings from the sky
showDropping();
deleteDropping();
makeNewDropping();
//person movement on ground
if (dir == true){ //makes person move in positive x direction
xPos = xPos +3; //makes person reapper from left side
if (xPos > width){
xPos = 1;
}
} else{ //makes person move negative x direction
xPos = xPos - 3; //makes person reappear from right side
if (xPos < 0){
xPos = width;
}
}
personDisplay(xPos,yPos);
if (timer < interval){
timer = timer + 1;
}
//making "keypressed" only recognized once in an interval
if(keyIsPressed & timer == interval){
if(key =='g'){
if (dir == true){
dir = false;
} else {
dir = true;
}
timer = 0;
}
}
for(var i=0; i<dropping.length; i++){
if(yPos+35 >dropping[i].y+19 >yPos) {
if(xPos > dropping[i].x-14 > xPos+10 || xPos+10<dropping[i].x+14 < xPos) {
playGame=false;
}
}
}
}
//rendering player's character
function personDisplay(x, y) {
push();
translate(x, y);
strokeWeight(1);
stroke(50);
ellipseMode(CORNER);
ellipse(0,0, 10,10);
line(0,10, -5,15);
line(10,10, 15,15);
strokeWeight(2);
fill("red");
rect(0,10, 10,13);
fill("yellow");
rect(0,23, 10,7);
line(0,30, 0,35);
line(10,30, 10,35);
pop();
}
//-------------------------------------------------------------------gg
var dropping = [];
function droppingDisplay() {
push();
translate(this.x, this.y);
fill(208,168,92);
strokeWeight(2);
stroke(100);
ellipse(0,14,28,10);
ellipse(0,7,18,10);
ellipse(0,0,10,10);
pop();
}
function makeDropping(birthlocationX, birthlocationY) {
var dropping = {x: birthlocationX,
y: birthlocationY,
speed: random(2,5),
move: droppingMove,
display: droppingDisplay}
return dropping;
}
function droppingMove() {
if(playGame==true) {
this.y += this.speed;
}else{
this.y = this.y;
}
}
function makeNewDropping() {
var newDroppingLiklihood = 0.03;
newDroppingLiklihood += gameDifficulty;
if(random(0,1) < newDroppingLiklihood) {
dropping.push(makeDropping(random(width), 0));
}
}
function deleteDropping() {
var droppingToKeep = [];
for (var i=0; i<dropping.length; i++) {
if(dropping[i].y >500) {
droppingToKeep.push(dropping[i]);
}
}
}
function showDropping() {
for(var i=0; i<dropping.length; i++) {
dropping[i].move();
dropping[i].display();
}
}
//--------------------------------------------------------------
/*
function checkTouch() {
for(var i=0; i<dropping.length; i++){
if(dropping[i].y+19 > yPos & dropping[i].y-5 xPos+10 && dropping[i].x+14 < xPos) {
playGame = false;
}
}
}
}*/
]]>/*
Jihoon Park
Section A
jihoonp@andrew.cmu.edu
inClass 10.25
*/
var clouds = [];
var balloons = [];
var stork = [];
function setup() {
createCanvas(400,600);
for (var i=0; i<15; i++) { //initial placement of clouds
var cloudsX = random(width);
var cloudsY = random(height);
clouds[i] = makeClouds(cloudsX, cloudsY);
}
for (var i=0; i<5; i++) { //initial placement of storks
var storkX = random(width);
var storkY = random(100, 500);
stork[i] = makeStork(storkX, storkY);
}
for (var i=0; i<3; i++) { //initial placement of balloons
var balloonX = random(width);
var balloonY = random(height);
balloons[i] = makeBalloons(balloonX, balloonY);
}
frameRate(10);
}
function draw() {
background(132, 181, 204); //sky blue background
showClouds();
deleteClouds();
makeNewClouds();
showBalloons();
deleteBalloons();
makeNewBalloons();
showStork();
deleteStork();
makeNewStork();
myBalloon();
}
//---------------------------FUNCTIONS THAT MAKE CLOUDS--------------------------------------------------
function showClouds() { //this makes the clouds move down
for(var i=0; i<clouds.length; i++) {
clouds[i].move();
clouds[i].display();
}
}
function deleteClouds() { //deletes clouds that disappear from sight
var cloudsToKeep = [];
for (var i=0; i< clouds.length; i++) {
if(clouds[i].y >600) {
cloudsToKeep.push(clouds[i]);
}
}
}
function makeNewClouds() { //creates more clouds coming down
var newCloudLiklihood =0.05
if (random(0,1) < newCloudLiklihood) {
clouds.push(makeClouds(random(width), 0));
}
}
function cloudMove() { //sets the move property of clouds
this.y += this.speed;
}
function cloudDisplay() { //what clouds look like
var cloudSize=this.cloudSize;
fill(223, 255, 233);
noStroke();
push(); //moves the center point to center of cloud
translate(this.x, this.y);
ellipse(0, 0, cloudSize, cloudSize); //graphic elements of clouds
ellipse(0, cloudSize, 3*cloudSize, cloudSize);
ellipse(-cloudSize/2, cloudSize/2, cloudSize, cloudSize);
ellipse(cloudSize/2, cloudSize/2, cloudSize, cloudSize);
pop();
}
function makeClouds(birthLocationX, birthLocationY) { //function that makes the clouds
var clouds = {x : birthLocationX, //clouds are born in random places
y : birthLocationY,
speed : random(1, 5), //sets random speed of clouds
cloudSize : random(10, 25), //sets random size of clouds
move : cloudMove,
display : cloudDisplay}
return clouds;
}
//-------------------------------------------------------------------------------------------------------
//---------------------------FUNCTIONS THAT MAKE STORK---------------------------------------------------
function showStork() { //this makes the stork move left
for(var i=0; i<stork.length; i++) {
stork[i].fly();
stork[i].display();
}
}
function deleteStork() { //deletes stork that disappear from sight
var storkToKeep = [];
for (var i=0; i< stork.length; i++) {
if(stork[i].x <0) {
storkToKeep.push(stork[i]);
}
}
}
function makeNewStork() { //creates more stork coming from left
var newStorkLiklihood =0.03
if (random(0,1) < newStorkLiklihood) {
stork.push(makeStork(650, random(100, 500)));
}
}
function storkFly() {
this.x += this.speed;
}
function storkDisplay() { //makes graphic elements of the Stork
push();
translate(this.x, this.y);
stroke(140);
strokeWeight(1);
fill(255, 220, 98);
triangle(-50, 1, -4, -3, -4, 3); //makes beak
line(-50, 0, -4,0);
strokeWeight(2); //makes legs
line(70, 7, 110, 15);
line(110, 15, 117, 10);
line(110, 15, 120, 15);
line(110, 15, 117, 20);
noStroke();
fill(243, 239, 244);
ellipse(0, 0, 20, 20); //makes head
ellipse(50, 0, 50, 20); //makes body
beginShape(); //makes wings
curveVertex(40, 0);
curveVertex(40, 0);
curveVertex(60, -40);
curveVertex(80, -40);
curveVertex(60, 0);
curveVertex(60, 0);
endShape();
strokeWeight(6);
stroke(243, 239, 244);
line(5,0, 25, 0); //makes neck
fill(0);
noStroke();
stroke(0);
ellipse(0, -2, .2, .2); //makes eyes
pop();
}
function makeStork(birthLocationX, birthLocationY) {
var stork = {x : birthLocationX,
y : birthLocationY,
speed : -random(2, 6),
fly : storkFly,
display : storkDisplay}
return stork;
}
//-------------------------------------------------------------------------------------------------------
function showBalloons() { //this makes the balloons move up
for(var i=0; i<balloons.length; i++) {
balloons[i].move();
balloons[i].display();
}
}
function deleteBalloons() { //deletes Balloons that disappear from sight
var BalloonsToKeep = [];
for (var i=0; i< balloons.length; i++) {
if(balloons[i].y >600) {
balloonsToKeep.push(balloons[i]);
}
}
}
function makeNewBalloons() { //creates more Balloons coming down
var newBalloonLiklihood =0.05
if (random(0,1) < newBalloonLiklihood) {
balloons.push(makeBalloons(random(width), 600));
}
}
function balloonMove() { //sets the move property of Ballons
this.y += this.speed;
}
function balloonDisplay() {
push();
translate(this.x, this.y);
fill(173, 140, 82);
stroke(105, 84, 49);
strokeWeight(3);
beginShape(); //basket
vertex(-7, -7);
vertex(7, -7);
vertex(5, 5);
vertex(-5, 5);
endShape(CLOSE);
stroke(30, 40, 20);
strokeWeight(2);
line(-7, -7, -10, -20);
line(7, -7, 10, -20);
strokeWeight(.5);
fill(255, 97, 118);
ellipse(0, -30, 30, 30);
pop();
}
function makeBalloons(birthLocationX, birthLocationY) {
var balloon = {x : birthLocationX,
y : birthLocationY,
speed : -random(1, 6),
move : balloonMove,
display : balloonDisplay}
return balloon;
}
//---------------------------FUNCTION THAT MAKES MY BALLOON----------------------------------------------
function myBalloon() { //function makes the balloon im in in perspective
//basket
fill(105, 84, 49);
strokeWeight(10);
stroke(173, 140, 82);
beginShape();
vertex(0, 610);
vertex(50, 520);
vertex(350, 520);
vertex(400,610);
endShape(CLOSE);
//rope
stroke(30, 39, 20);
strokeWeight(5);
line(50,515, 20,70);
line(350,515, 380, 70);
//balloon
fill(255, 224, 151);
strokeWeight(1);
stroke(140);
beginShape();
curveVertex(200,-100);
curveVertex(50, -50);
curveVertex(-30, 100);
curveVertex(200, 50);
curveVertex(430, 100);
curveVertex(350, -50);
curveVertex(200, -100);
endShape(CLOSE);
fill(255, 161, 193);
beginShape();
curveVertex(-30, 100)
curveVertex(0, 100);
curveVertex(20,70);
curveVertex(50, -50);
curveVertex(-30, 0);
endShape(CLOSE);
fill(204, 125, 178);
beginShape();
curveVertex(430, 100)
curveVertex(400, 100);
curveVertex(380, 70);
curveVertex(350, -50);
curveVertex(430, 0);
endShape(CLOSE);
}
I created a perspective view from a hot balloon going up into the air. clouds’s downward movement makes an illusion that the viewer is going up while size variation gives the sky a sense of depth. To add more fun, a flock of storks appear as well as other balloons.
Yael Braha is a creative director from Rome, Italy, currently working for a design firm called Moment factory. She is involved in a wide range of artworks whether they involve computation or not, and her work is displayed world wide.Her works include big scale installations, film art, sculptures, paintings, graphics. Braha has been exploring the extent of art as means of communication and interaction, especially with the aid of computation.
This project installed in California Academy of Sciences in San Francisco is called “Animal Race.” It is an interactive installation that gets users to take a short race with an animal of their choice. The way it works is once the user chooses which animal to race, it will automatically compare it with the speed of the user and represent the result in graphics. It also shows a representation of compiled result of the races conducted for each animal.
This is a nice project for the museum that can bring people to get involved in learning experience, whereas traditional museum was focused on passive viewer stance. It presents a possible way for interactive learning that other museums can adopt.
/*
Jihoon Park
section A
jihoonp@andrew.cmu.edu
project 09
*/
var GrannyImg
function preload() {
var GrannyLocation ="http://i.imgur.com/sCHGvUW.jpg";
GrannyImg = loadImage(GrannyLocation);
}
function setup() {
createCanvas(616, 408);
background(0);
GrannyImg.loadPixels();
frameRate(10);
colorMode(RGB);
}
var rectangle = [];
function drawRect() {
var pixelX = random(0, width);
var pixelY = random(0, height);
var iX = constrain(floor(pixelX), 0, width-1);
var iY = constrain(floor(pixelY), 0, height-1);
var pixelColor = GrannyImg.get(iX, iY);
var rectLength = map(brightness(pixelColor), 0, 100, 0, 50);
//noStroke();
fill(pixelColor);
rectMode(CENTER);
rect(pixelX, pixelY, 4, rectLength);
}
function draw() {
drawRect();
}
I took a black and white photograph of my grandmother from last summer and turned it into a portrait consisted of strips.
//Jihoon Park
//section A
//jihoonp@andrew.cmu.edu
//project-07
var nPoints = 100;
var divider; //number of points in hypotrochoid
function setup() {
createCanvas(600,600);
frameRate(10);
}
function draw() {
background(0);
for(var i=0; i<10; i++) { //loops the Hypotrochoid with 30 pixel space
var col = map(i, 0, 10, 0, 255); //color map
stroke(col);
noFill(); //inner geometry fades
Hypo(i*30, mouseX/50); //changes the number of points according to mouse X
}
}
function Hypo(a, divider) {
var x;
var y;
var a; //radius of circumscribed circle
var b=a/divider; //radius of inscribed circle
var h = constrain(mouseY/10, 0, a); //length of rotating point generator
var ph = mouseX/50; //rotation of hypotrochoid
push(); //moves the origin of hypotrochoid to center
translate(width/2, height/2);
beginShape();
for(var i=0; i<nPoints; i++) {
var t = map(i, 0, nPoints, 0, TWO_PI);
x=(a-b)*cos(t) + h*cos(ph+t*(a-b)/b);
y=(a-b)*sin(t) - h*sin(ph+t*(a-b)/b);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
In this project I made a function called Hypo, which is a short term I gave for hypotrochoid. This geometry has 3 variables which are the radius of circumscribed circle, inner orbiting circle and the length of the line which is rotated from the center of orbiting circle. I made all of the variables modifiable according to the x and y position of the mouse, then looped the geometry to form an overlap.
In 2013, Moebio Lab, lead by Santiago Ortiz, created a visualized map of all conversations made in Twitter in a week period of February 15th to 22nd. Moebio Lab is a team of data scientists who concentrate on exploring creative and effective ways of visually representing empirical and textual data. A lot of their work forms a cluster of various data according to parameters such as hierarchy and frequency.
In this project, the threads are representation of the relationship between tweeter users according to tweets, retweets, tags, and comments. In a big picture, they are barely legible in individual sense, but the density of the threads show which and which has stronger relationship to each other. As the clusters are zoomed in, we are able to figure out which users are directly related in what way. The representation allows for the users to read the global and local interaction in the web sense.
This is a useful resource that could be applied in specific to creating statistics of public census, individual profiling, and human networking, which are useful to government organizations, job hunt/head-hunters, and consumer analysis branch of corporations. It leaves a possibility for development, as it could be more powerful if combined with statistical graph representation of the data.
//Jihoon Park
//Section A
//jihoonp@andrew.cmu.edu
//project-06
function setup() {
createCanvas(600, 400);
}
function draw() {
var H = hour();
var M = minute();
var S = second();
var Mil = millis();
var glac = (sin(radians(Mil/3600/1000*180))); //size change of glacier by minute
var shadR =(cos(radians(Mil/12/3600/1000*180)));//size change of penguin by second
var penR = abs(sin(radians(Mil/1000/60*180))); //rotation of shadow by hour
var snow = [0,2,4];
var centX = width/2;
var centY = height/2;
background(117, 230, 232); //creates the sky
textSize(15); //text specifications
fill("darkblue");
textFont("Courier New");
//writes out time above
text(nf(H, [], 0), 110, 30);
text(":", 130, 30);
text(nf(M, [], 0), 140, 30);
text(":", 160, 30);
text(nf(S, [], 0), 170, 30);
fill(42, 135, 232); //creates the water
noStroke();
rect(0,100, 600, 300);
fill(230,232,232); //creates background glacier
strokeWeight(2);
beginShape();
vertex(0, 70);
vertex(100, 80);
vertex(120, 110);
vertex(110, 115);
vertex(80, 115);
vertex(80, 110);
vertex(0, 110);
endShape(CLOSE);
beginShape();
vertex(200, 100);
vertex(230, 85);
vertex(240, 100);
endShape(CLOSE);
beginShape();
vertex(380, 105);
vertex(370, 80);
vertex(520, 83);
vertex(520, 75);
vertex(600, 75);
vertex(600, 110);
endShape(CLOSE);
//creates the glacier that increase and decrease according to minute
fill(225, 255, 236);
strokeWeight(1);
stroke(0);
//noStroke();
ellipse(300, 250, 200+200*glac, 100+100*glac);
//creates shadow that rotates by hour
fill(140);
noStroke();
push();
translate(centX, 260);
rotate(shadR);
ellipse(0,50, 50, 100);
pop();
//creates penguin that grows by second
fill(255,238,95);
triangle(290, 240, 285, 260, 295, 260); //penguin left foot
triangle(310, 240, 305, 260, 315, 260); //penquin right foot
fill(14, 25, 41);
noStroke();
ellipse(300, 220-50*penR, 30+25*penR, 60+50*penR); //penguin body
ellipse(300, 180-50*penR, 20+25*penR, 30+50*penR); //penguin head
ellipse(300, 240-15*penR, 40+10*penR, 40+10*penR); //penguin butt
push();
translate(310+15*penR, 210-40*penR);
rotate(radians(-30)); //penguin right fin
ellipse(0,0, 10, 40);
pop();
push();
translate(290-15*penR, 210-40*penR);
rotate(radians(30));
ellipse(0,0, 10, 40); //penguin left fin
pop();
fill(240);
ellipse(300, 230-50*penR, 15+25*penR, 50+50*penR); //penguin belly
fill(255, 238, 95);
noStroke(); //penguin beak
beginShape();
vertex(300, 180-60*penR);
vertex(305, 182-60*penR);
vertex(300, 184-60*penR);
vertex(295, 182-60*penR);
endShape(CLOSE);
fill(255);
ellipse(295, 175-60*penR, 10, 5); //penguin left eye
ellipse(305, 175-60*penR, 10, 5); //penguin right eye
fill(0);
ellipse(295, 175-60*penR, 2,2); //penquin left pupil
ellipse(305, 175-60*penR, 2,2); //penquin right pupil
for(i=0; i<width; i+=100) { //snow
for(j=0; j<height; j+=100) {
fill(255);
noStroke();
ellipse(i*random(0,2), j*random(0, 2), 5,5);
}
}
}
The clock incorporates three different elements to tell change in time. The penguin grows and shrinks by the second, the iceberg it stands on also grows and shrinks by the minute, while the shadow of the penguin rotates by the hour. There is no absolute measure of time in my clock, but it only shows the change. Though in the beginning, I imagined a penguin hatching out of an egg to grow as time goes by, but that turned out unfeasible with my coding skills…
]]>Montreal in March of 2013 was still in the midst of winter when Iregular unveiled their interactive installation called “Lift.” Iregular is a studio with Daniel Iregui at its head, seeking ways to mesmerize using computer generated art. The Lift was a projection set on a dome of 6 images that represented the city of Montreal. However, the fun part was that the audience could throw a glowing balloon into the wall, and the position and velocity of the balloon could give shifts to the projected video.
There was a controlled randomness to this installation, especially in the fact that no two balloons shot into the air were most unlikely to have the exact same motion. The following images on the dome were images never to be seen again.
]]>sketch
I was inspired by islamic geometric patterns as well as oriental window seals that overlapped and intersected perpetually. There are three components in this pattern, a vertical line and two zigzag lines. I created my own functions, “vertStrip” and “zigzag” to reduce redundancy in coding the overlapping strips.
//Jihoon Park
//Section A
//jihoonp@andrew.cmu.edu
//project-05
var i; //horizontal loop value for vertical strips
var j; //vertical loop value for vertical strips
var k; //horizontal loop value for black zigzag
var l; //vertical loop value for black zigzag
var m; //horizontal loop value for gray zigzag
var n; //vertical loop value for gray zigzay
function setup() {
createCanvas(800, 400);
background(236, 245, 255); //lightblue
//WHITE VERTICAL STRIPS
for (j=0; j<height+20; j+=20) {
strokeWeight(0.5);
fill(255, 142, 84); //orange red
for (i=0; i<width+20; i+=20) {
if ((i%40)==0) { //odd number columns
vertStrip(i, j);
} else { //even number columns
vertStrip(i, j-10);
}
}
}
// HORIZONTAL ZIGZAG
for (l=0; l<height+20; l+=20) {
for(k=0; k<width+80; k+=80) {
if ((l%40)==0) { //ODD ROWS
fill(160, 255, 99);//green //draws green zigzag strips
zigzag(k, l);
fill(78, 232, 194); //draws turquois zigzag strips
zigzag(k+20, l+10);
} else { //EVEN ROWS
fill(160, 255, 90); //draws green zigzag strips
zigzag(k-40, l);
fill(78,232,194);
zigzag(k+-20, l+10); //draws turquois zigzag strips
}
}
}
noLoop();
}
function vertStrip(i,j) {
beginShape(); //function that draws vertical strips
vertex(i, j+5);
vertex(i+5, j+2.5);
vertex(i+5, j+17.5);
vertex(i, j+20);
endShape(CLOSE);
}
function zigzag(k, l) { //function that draws zigzag strips
beginShape(); //all vertex of shapes are listed clockwise
vertex(k-15, l+2.5);
vertex(k-10, l+5);
vertex(k-15, l+7.5);
endShape(CLOSE);
beginShape();
vertex(k-10, l+5);
vertex(k+5, l-2.5);
vertex(k+10, l);
vertex(k-5, l+7.5);
endShape(CLOSE);
beginShape();
vertex(k+10, l);
vertex(k+15, l-2.5);
vertex(k+20, l);
vertex(k+20, l+5);
endShape(CLOSE);
beginShape();
vertex(k+25, l+2.5);
vertex(k+30, l+5);
vertex(k+50, l-5);
vertex(k+60, l);
vertex(k+60, l+5);
vertex(k+50, l);
vertex(k+30, l+10);
vertex(k+25, l+7.5);
endShape();
}
]]>While surfing over various works by 3D graphic artists, I noticed plenty were creating graphics that were so real, that they were not distinguishable from reality, or ones that very picturesque to draw an awe from the viewer. However, Mike Campau’s work hit me with an odd way. Thought the texture was realistic, the general form was not. His work was not necessarily the most well composed or beautiful. Nevertheless, what is clear in his graphics is that all of them get a sense of what is being said across to the viewer. It is clear to even a child that Steph curry is very hydrated and that helps his performance. viewer is struck with a fresh and revitalizing feeling of the image, and when they notice that it is an advertisement for Brita (the water filter jar), the same sense of image stays. This ability explains how Campau is so successful in the advertising business.
In addition, Campau treats computer graphic as computer graphic. By this, I mean there in some integrity in his image that prevents it from deceiving the viewer to think something unreal is real. What is the purpose if computer graphic, a tool to make something unreal, makes something so real that it is indistinguishable from photography? Campau instead, integrates photography into his art and generates a synergy between what is unreal and real.