Min Ji Kim Kim & Kristine Kim – Final Project

sketch

// Kristine Kim & Min Ji Kim Kim
// Section D & A
// younsook & mkimkim
// Final Project

// -------------------------------- VARIABLES --------------------------------

// GENERAL
var texts = [];
var people = [];
var peopleImages = [];
var character;

// MENU
var screen = "menu"; //screen always set to menu when first opened
var Bible;
var leftFrame;
var rightFrame;

//FEEDING THE 5000
var food = [];
var foodImages = [];
var disciple;
var crowd1;
var crowd2;
var crowd3;

// NOAH'S ARK
var ark;
var rain = [];
var animalImages = [];
var animals = [];
var offsetX; // offsets for mouse drag later
var offsetY;

// --------------------------- PRELOAD IMAGES ----------------------------------

function preload() {
    var foodLinks = [];
    foodLinks[0] = 'https://i.imgur.com/I2GtIHI.png'; // fish
    foodLinks[1] = 'https://i.imgur.com/37fSZcK.png'; // bread
    foodLinks[2] = 'https://i.imgur.com/U5WevzT.png'; // basket
    for (var i = 0; i < foodLinks.length; i++) { // push urls into array
        foodImages[i] = loadImage(foodLinks[i]);
    }

    var animalLinks = [];
    animalLinks[0] = 'https://i.imgur.com/CBoFToW.png'; // giraffe
    animalLinks[1] = 'https://i.imgur.com/mOTcpZg.png'; // koala
    animalLinks[2] = 'https://i.imgur.com/cIjfUHk.png'; // monkey
    animalLinks[3] = 'https://i.imgur.com/ucc7kcb.png'; // elephant
    animalLinks[4] = 'https://i.imgur.com/n3MKNo5.png'; // lion
    animalLinks[5] = 'https://i.imgur.com/fcfIkPJ.png'; // bird
    animalLinks[6] = 'https://i.imgur.com/XhSjml7.png'; // turtle
    animalLinks[7] = 'https://i.imgur.com/bq0OgoB.png'; // zebra
    for (var i = 0; i < animalLinks.length; i++) { // push urls into array
        animalImages[i] = loadImage(animalLinks[i]);
    }

    var textLinks = [];
    textLinks[0] = 'https://i.imgur.com/JB4gpam.png'; // Andrew Intro
    textLinks[1] = 'https://i.imgur.com/CTLxAP2.png'; // Andrew End
    textLinks[2] = 'https://i.imgur.com/XIGb2J9.png'; // Noah Intro
    textLinks[3] = 'https://i.imgur.com/uEHleCT.png'; // Noah End
    textLinks[4] = 'https://i.imgur.com/ouDdHh0.png'; // Feed Instructions
    textLinks[5] = 'https://i.imgur.com/84dBAhN.png'; // Ark Instructions
    for (var i = 0; i < textLinks.length; i++) { // push urls into array
        texts[i] = loadImage(textLinks[i]);
    }

    var peopleLinks = [];
    peopleLinks[0] = 'https://i.imgur.com/jZVql8t.png'; // Noah
    peopleLinks[1] = 'https://i.imgur.com/EDZROu3.png'; // Andrew
    peopleLinks[2] = 'https://i.imgur.com/moPXqEi.png'; // Jesus
    for (var i = 0; i < peopleLinks.length; i++) { // push urls into array
        peopleImages[i] = loadImage(peopleLinks[i]);
    }

    Bible = loadImage('https://i.imgur.com/VKVcQg5.png');
    leftFrame = loadImage('https://i.imgur.com/XyGYYj0.jpg');
    rightFrame = loadImage('https://i.imgur.com/jpBO0LB.jpg');
    character = loadImage('https://i.imgur.com/BiTQr7u.png');
    ark = loadImage('https://i.imgur.com/kqvTedI.png');
    crowd1 = loadImage('https://i.imgur.com/Gz2HLDi.png');
    crowd2 = loadImage('https://i.imgur.com/l4SCJCo.png');
    crowd3 = loadImage('https://i.imgur.com/JON4rd1.png');
}

// -----------------------------------------------------------------------------

function setup() {
    createCanvas(600, 600);
    strokeJoin(MITER); // turtle code stroke join & cap settings
    strokeCap(PROJECT);
    for(var i = 0; i < 300; i++) {
        rain.push(drop()); // load raindrops into array (for Noah's ark story)
    }
}

// DRAWING SCREENS
function draw() {
    if(screen == "menu") {
        menuScreen();
    }
    else if (screen == "feedIntro") {
        feedIntroScreen();
    }
    else if (screen == "feed") {
        feedScreen();
    }
    else if (screen == "feedEnd") {
        feedEndScreen();
    }
    else if (screen == "arkIntro") {
        arkIntroScreen();
    }
    else if (screen == "ark") {
        arkScreen();
    }
    else if (screen == "arkEnd") {
        arkEndScreen();
    }
}

// ---------------------------------- MENU -------------------------------------

function menuScreen() {
    background("#0F7B96");
    
    //table
    noStroke();
    fill("#553C2A");
    rect(0, height - 120, width, 120);
    
    //book
    image(Bible, 80, 320);
    
    //draw & change frame color if selected
    //left frame
    fill(0);
    if(mouseX < 270 & mouseX > 40 && mouseY > 140 && mouseY < 320) {
        fill("#AEA4FA");
    }
    rect(40, 150, 230, 180);
    image(leftFrame, 50, 160);

    //right frame
    fill(0);
    if(mouseX < 560 & mouseX > 330 && mouseY > 140 && mouseY < 320) {
        fill("#5DED79");
    }
    rect(330, 150, 230, 180);
    image(rightFrame, 340, 160);
    
    //text
    fill(255);
    textAlign(CENTER);
    textFont("Trebuchet MS", 25);
    text("Select a Bible story", width / 2, 60);
    textSize(20);
    text("Jesus feeds the 5000", 155, 130);
    text("Noah's Ark", 450, 130);
}

// SELECT A STORY
function mouseClicked() {
    if (screen == "menu") {
        if(mouseX < 270 & mouseX > 40 && mouseY > 140 && mouseY < 320) {
            screen = "feedIntro"; // click on left frame
        }
        if(mouseX < 560 & mouseX > 330 && mouseY > 140 && mouseY < 320) {
            screen = "arkIntro"; // click on right frame
        }
    }

    if (screen == "feedEnd" || screen == "arkEnd") {
        if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "menu"; // click on "menu" to go back to menu
        }
    }

    if (screen == "feedIntro") {
        if (mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "feed"; // click "go help ->" to go to main story
        }
    }

    if (screen == "arkIntro") {
        if (mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
            screen = "ark"; // click "go help ->" to go to main story
        }
    }
}

// --------------------------- JESUS FEEDS THE 5000 ----------------------------

//STORY  INTRODUCTION
function feedIntroScreen() {
    background(255);
    //display Andrew, basket, text, and button to go to main story
    image(peopleImages[1], 50, height / 4);
    image(foodImages[2], 230, 350);
    image(texts[0], 250, 120);
    goHelpButton();
}

// MAIN STORY SCREEN
function feedScreen() {
    background("#a9c75f");
    maze1();
    createMainChar(); //display character 
    image(peopleImages[2], 330, 280); //display Jesus
    for (var i = 0; i < food.length; i++) { //draw food inside the array
        food[i].draw();
    }

    //display basket at mouse location 
    var scaleWidth = foodImages[2].width * 0.4; //scale basket image 
    var scaleHeight = foodImages[2].height * 0.4;
    var bkx = scaleWidth / 2; // offset from left corner
    var bky = scaleHeight / 2;
    image(foodImages[2], mouseX - bkx, mouseY - bky, scaleWidth, scaleHeight);

    //display instructions and crowds
    image(texts[4], 0, 530);
    image(crowd1, 230, 380);
    image(crowd2, 310, 5);
    image(crowd3, 350, 40);

    //when character reaches the end of the maze, reset character position
    //clear food array and go to end screen
    if (people[0].x > width) {
        people[0].x = 10;
        people[0].y = 410;
        food = [];
        screen = "feedEnd";
    }
}

//CODE FOR FOOD IMAGES
// create an object for food images 
function makeFood(x, y, type) {
    var foods = {x: x,
                y: y,
                type: type,
                draw: foodDraw}
    return foods;
}

function foodDraw() {
    if (this.type === 'fish') { //draw bread at mouse location
        image(foodImages[0], this.x, this.y);
    }
    else if (this.type === 'bread') { //draw fish at mouse location
        image(foodImages[1], this.x, this.y);
    }
}

// interaction keys to make fish and bread on canvas at mouse location
function keyPressed() {
    if(screen == "feed") { // create fish = press f
        if (keyCode == 70) {
            var fx = foodImages[0].width / 2; // offset from left corner
            var fy = foodImages[0].height / 2;
            newFood = makeFood(mouseX - fx, mouseY - fy, 'fish');
            food.push(newFood);
        }
        if (keyCode == 66) { // create bread = press b
            var bx = foodImages[1].width / 2; // offset from left corner
            var by = foodImages[1].height / 2;
            newFood = makeFood(mouseX - bx, mouseY - by, 'bread');
            food.push(newFood);
        }
    }
}

// create maze path using turtle graphics
function maze1() {
    var ttl1 = makeTurtle(20, 480);
        ttl1.setColor(color("#a6927b"));
        ttl1.setWeight(40);
        ttl1.forward(150);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.right(90);
        ttl1.forward(280);
        ttl1.right(90);
        ttl1.forward(240);
        ttl1.right(90);
        ttl1.forward(80);
        ttl1.right(90);
        ttl1.forward(120);
        ttl1.left(90);
        ttl1.forward(100);
        ttl1.left(90);
        ttl1.forward(250);
        ttl1.right(90);
        ttl1.forward(200);
        ttl1.left(90);
        ttl1.forward(120);
        ttl1.left(90);
        ttl1.forward(70);
        ttl1.right(90);
        ttl1.forward(20);
    //stage for Jesus
    fill("#a6927b");
    rect(280, 250, 100, 100);
}

// STORY ENDING SCREEN 
function feedEndScreen() {
    background(169, 146, 119);
    //display Andrew, text and menu button
    image(peopleImages[1], 50, height / 4);
    image(texts[1], 250, 100);
    menuButton(); // go back to "menu" button
}

// ------------------------------ NOAH'S ARK -----------------------------------

// STORY INTRODUCTION
function arkIntroScreen() {
    background(255);
    //display Noah, text, ark and button to go to main story
    image(peopleImages[0], 50, height / 4);
    image(texts[2], 250, 130);
    image(ark, 250, 250);
    goHelpButton(); // button to go to main screen
}

// MAIN STORY SCREEN
function arkScreen() {
    // display background gradient
    var turquoise = color(16, 157, 172); 
    var navy = color(1,84,134);
    gradient(turquoise, navy);

    //display maze, ark, character and instructions
    maze2();
    image(ark, 370, 80);
    createMainChar();
    image(texts[5], 0, 550);

    // display animals
    for (var i = 0; i < animalImages.length; i++) {
        animals.push(makeAnimal(animalImages[i])); //push images into array
        animals[i].draw(); //draw animals
        // if the animal is moved, adjust that image location
        if (animals[i].moving) {
            animals[i].x = mouseX + offsetX;
            animals[i].y = mouseY + offsetY;
        }
    }

    // make it rain when pressing "r"
    if (keyIsDown(82)) {
        for (var r = 0; r < rain.length; r++) {
            rain[r].display();
            rain[r].falling();
        }
    }
    //when character reaches the end of the maze, reset character position,
    //clear animals array and go to end screen
    if (people[0].x > width) {
        people[0].x = 10;
        people[0].y = 410;
        animals = [];
        screen = "arkEnd";
    }
}

// to render background gradient for main story
function gradient(c1, c2) {
    noFill();
    noStroke();
    for (var x = 0; x < width; x++) {
        var mapColor = map(x, 0, width, 0, 2);
        var c = lerpColor(c1, c2, mapColor);
        stroke(c);
        line(x, 0, x, height);
    }
}

// create maze path using turtle graphics
function maze2() {
    var ttl2 = makeTurtle(20, 480);
        ttl2.setColor(color("#AF9879"));
        ttl2.setWeight(40);
        ttl2.forward(80);
        ttl2.left(90);
        ttl2.forward(400);
        ttl2.right(90);
        ttl2.forward(180);
        ttl2.right(90);
        ttl2.forward(150);
        ttl2.right(90);
        ttl2.forward(100);
        ttl2.left(90);
        ttl2.forward(120);
        ttl2.left(90);
        ttl2.forward(180);
        ttl2.right(90);
        ttl2.forward(170);
        ttl2.left(90);
        ttl2.forward(120);
        ttl2.left(90);
        ttl2.forward(300);
        ttl2.right(90);
        ttl2.forward(100);
}

// CODE FOR ANIMALS
// to click and drag animal image
function mousePressed() {
    for (var i = 0; i < animalImages.length; i++) {
        if (animals[i] == undefined) { // terminate if animals[i] is undefined
            return;
        }
        // check if mouse is on the animal image
        if (mouseX > animals[i].x & mouseX < animals[i].x + animalImages[i].width && 
            mouseY > animals[i].y && mouseY < animals[i].y + animalImages[i].height) {
            animals[i].moving = true;
            // if yes, track location of the mouse click to the corner of animal image
            offsetX = animals[i].x - mouseX;
            offsetY = animals[i].y - mouseY;
        }
    }
}

function mouseReleased() {
    //stop dragging animal
    for (var i = 0; i < animalImages.length; i++) {
        if (animals[i] != undefined) { //check if animals[i] is defined
            animals[i].moving = false;
        }
    }
}

// create an object for animal images
function makeAnimal(image) {
    var animal = {img: image,
                    x: random(10, 550),
                    y: random(10, 490),
                    moving: false,
                    draw: drawAnimal}
    return animal;
}

function drawAnimal() {
    image(this.img, this.x, this.y);
}

// CODE FOR RAIN
// create rain drop object
function drop() {
    var drop = {x: random(0, width),
                y: random(-5, height),
                len: random(5, 20),
                thick: random(1, 3),
                vel: random(5, 15),
                display: dropDisplay,
                falling: dropFalling}
    return drop;
}

// display rain drop
function dropDisplay() {
    noStroke();
    fill(255, 90);
    ellipse(this.x, this.y, this.thick, this.len);
}

// make raindrop fall
function dropFalling() {
    this.y += this.vel;
    if (this.y > height) {
        this.y = -this.len;
    }
}

//STORY END SCREEN
function arkEndScreen() {
    background(178, 153, 116);
    //display Noah, text and menu button
    image(peopleImages[0], 50, height / 4);
    image(texts[3], 250, 130);
    menuButton(); // go back to "menu" button

}

// -------------------------- CHARACTER & MOVEMENT -----------------------------

function createMainChar () {
    //create the character object
    people.push(makeCharacter());
    people[0].draw();

    //MOVE CHARACTER BY PRESSING ARROW KEYS
    if (keyIsPressed) {
        if (keyCode === UP_ARROW) {
            people[0].y -= 2;
        }
        else if (keyCode === DOWN_ARROW) {
            people[0].y += 2;
        }
        else if (keyCode === LEFT_ARROW) {
            people[0].x -= 2;
        }
        else if (keyCode === RIGHT_ARROW) {
            people[0].x += 2;
        }
    }
}

function makeCharacter() {
    var char = { x: 10, y: 410, draw: drawCharacter }
    return char;
}

function drawCharacter() {
    image(character, this.x, this.y);
}

// ----------------------------- EXTRA BUTTONS ---------------------------------

// create button to go back to menu after story ends
function menuButton() {
    textSize(20);
    fill(0)
    if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
        fill('#27AEE3'); // change color if mouse is hovering over
    }
    text('menu', 550, 550);
}

// create button to go to main story
function goHelpButton() {
    textSize(20);
    fill(0);
    if(mouseX > 500 & mouseY > 530 && mouseX < 600 && mouseY < 600) {
        fill('#27AEE3'); // change color if mouse is hovering over
    }
    text('go help -> ', 550, 550);
}

// ------------------------- TURTLE CODE FOR MAZES -----------------------------

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: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;}

Kristine and I created 2 interactive stories from the Bible since Christianity is something that we really value. We decided to create this as a method to teach children about the Bible while also letting them have fun.

Kristine worked on the “Feeding the 5000” story while I worked on the “Noah’s Ark” story. We met together throughout the week to make sure our two programs connected and worked smoothly which took the most time. I also took charge of securing of online images and creating the image arrays since I was working on the more image heavy portion and Kristine in turn worked on the menu screen and the character movement as well. We divided the work very evenly and made sure to consult with each other if we had problems or didn’t know how to do something.

The only thing you might need to know to play our game is to make sure to  completely go to the end of the path to the end of canvas width, since it goes to the next screen automatically once the character gets to the end.

We had so much fun creating this project!

Min Ji Kim Kim & Kristine Kim – Project Proposal

Read Kristine’s post before proceeding, as this will discuss our project in more detail. 

We thought it would be easier to walk through one of the scenarios we wanted to develop in order to explain how this project will work. One of the stories will be about how Jesus fed 5000 people with 2 fish and 5 loaves. The character would start on the left side of the canvas and the user would move it along the path using the arrow keys. Along the path, they would collect 2 fish and 5 breads. Then halfway, they would meet Jesus who they can click on, making Him say something in a text box. Then, you would click on Him again and there would be an animation in which randomized bread and fish would appear in the canvas. The user would then move along the path and reach the end of the path at the right side of the canvas.

In a similar manner we will generate one or two more stories the user can choose from. We will also add more objects and add more speech to make it interactive and tell the Bible story. 

I got inspiration from my Looking Outward post 12.

One of the pathways walking the user through the Bible story.
Beginning screen and one of the stories.

Min Ji Kim Kim – Looking Outwards 12

The first project that I drew inspiration from was Monument Valley created by Ustwo games using Unity software. This indie puzzle game allows the user to walk princess Ida through multiple pathways including optical illusions and objects in order to clear each stage. I really admire this game not only because it’s fun and calming, but also because of its aesthetics. The use of simple color and primitive shapes come together to create the intricate and complex landscape designs. I wanted to incorporate the idea of going through a pathway and make use of similar aesthetics that Monument Valley uses.

Some of the different landscape backgrounds for different stages in Monument Valley.

The other project I drew inspiration from was Hyper Light Drifter which is a 2d role playing game developed by Abylight Studios. The player controls the Drifter and goes through the different stories collecting items on the way and fights monsters. Our project wants to mimic the 2D pixel drawing style and how the character is able to interact with the environment.

Screen capture of one of the landscapes in Hyper Light Drifter.

Min Ji Kim Kim – Project 11 – Landscape

sketch

/*
Min Ji Kim Kim
Section A
mkimkim@andrew.cmu.edu
Project-11
*/

var luggage = [];

function setup() {
    createCanvas(480,450);
    frameRate(50);

    // create an initial collection of luggage
    for (var i = 0; i < 3; i++) {
        var rx = random(width);
        luggage[i] = makeLuggage(rx);
    }
}

function draw() {
    background(225, 225, 218);

    baggageClaim(); //background details

    updateLuggage(); //update luggage
    removeLuggage(); //remove luggage
    addLuggage(); //add luggage
}

function updateLuggage() {
    // update the luggage's position and display them
    for (var i = 0; i < luggage.length; i++) {
        luggage[i].move();
        luggage[i].display();
    }
}

function removeLuggage() {
    //remove luggage from array if it's out of sight
    var luggageToKeep = [];
    for (var i = 0; i < luggage.length; i++) {
        if (luggage[i].x + luggage[i].breadth > 0) {
            luggageToKeep.push(luggage[i]);
        }
    }
    luggage = luggageToKeep; //remember the surviving luggage
}

function addLuggage() {
    //with a very small probability, add a new luggage to the end
    var newLuggageProb = 0.008; 
    if (random(0,1) < newLuggageProb) {
        luggage.push(makeLuggage(width));
    }
}

// method to update position of luggage every frame
function luggageMove() {
    this.x += this.speed;
}

// draw the luggage
function luggageDisplay() {
    //bag
    noStroke();
    fill(this.r, this.g, this.b);
    rect(this.x, 360, this.breadth, this.h);

    //bag handle
    fill("#654321");
    var top = 350 + this.h; //top of bag
    rect(this.x + 20, top, this.breadth - 45, 5);
    rect(this.x + 20, top, 5, 10);
    rect(this.x + this.breadth - 25, top, 5, 10);

    //bag tag
    fill(245);
    stroke(this.r, 50, 150);
    strokeWeight(3);
    rect(this.x + 30, top + 20, 15, 27);
    line(this.x + 35, top, this.x + 35, top + 20);
}

// make a luggage bag object
function makeLuggage(beginX) {
    var lgg = {x: beginX,
                breadth: random(80, 120),
                speed: -1.0,
                h: -random(50, 100), //luggage height
                //set color
                r: random(10, 250),
                g: random(10, 250),
                b: random(10, 250),
                move: luggageMove,
                display: luggageDisplay}
    return lgg;
}

function baggageClaim() { //create background details
    noStroke();

    //floor
    fill(238, 239, 235);
    rect(0, 200, width, height);

    //windows
    fill(236, 236, 230);
    rect(0, 50, width, 120);
    for(i = 0; i < 6; i++) {
        stroke(255);
        strokeWeight(4);
        strokeCap(SQUARE);
        line(i * 85 + 25, 50, i * 85 + 25, 170);
    }
    line(0, 110, width, 110);
    line(0, 140, width, 140);

    chair();

    //carousel sign
    fill(90);
    rect(150, 45, 250, 60);
    rect(200, 10, 3, 35);
    rect(350, 10, 3, 35);
    noStroke();
    fill(29, 40, 80);
    rect(155, 65, 70, 35);
    fill(0);
    rect(235, 65, 160, 35);
    textSize(8);
    fill(255);
    text("Baggage Claim", 155, 60);
    text("Arrival Time", 235, 60);
    textSize(15);
    text("Delta    2:50", 270, 88);
    textSize(35);
    text("K", 180, 95);

    //conveyor belt
    fill(135, 147, 141);
    rect(0, 400, width, 20);
    fill(67, 67, 67);
    rect(0, 420, width, 5);
    fill(168, 184, 179);
    rect(0, 395, width, 5);
    rect(0,305, width, 5);
    fill(30);
    rect(0, 310, width, 85);
    for(j = 0; j < width; j++) { //belt lines
        stroke(15);
        strokeWeight(3);
        line(j * 30, 310, j * 30, 395);
    }
}

function chair() { //create a chair
    for(x = 0; x < 4; x++) {
        noStroke();
        fill(196, 197, 190);
        rect(80 + x * 22, 155, 20, 12);
        rect(80 + x * 22, 168, 20, 2);
        stroke(196, 197, 190);
        strokeWeight(2);
        strokeCap(SQUARE);
        line(x * 22 + 90, 167, x * 22 + 90, 172);
        line(x * 25 + 85, 172, x * 25 + 85, 180);
        strokeWeight(1);
        line(84, 172, 161, 172);
    }
}

I think this week’s project was the one that I had the most fun making but also the most challenging. Coming up with the idea was easy. I love to travel and I like staring at the baggage claim conveyor belt because if I stare long enough, it makes me feel like I’m moving. I quickly drew a sketch of what I wanted my landscape to look like.

My sketch of baggage claim

I then moved on to the starter code template and tried to understand what each part of the code was doing and how it was changing the image. This part was a little hard just because there were so many moving parts but I ultimately figured it out and then I tailored it one function at a time to match my sketch and create the final product. The colors and sizes of the bags are generated randomly.

Min Ji Kim Kim – Looking Outwards – 11

Playable minicade display.

Minicade, created by Chloe Varelidi, is essentially a mobile web-app built in JavaScript that allows you to play mini-games with your friends. I admire Varelidi’s work because it’s not only fun and interactive, but it also teaches one how to code their own mini-games, making learning fun. This could appeal to different age ranges, from young children learning how to code, to older people who want to make more complex games.

Chloe Varelidi received her Masters in Fine Arts at Parsons’ Design and Technology Program. She worked in game design studios and multiple organizations that mostly focus on incorporating play with human learning, such as Mozilla and littleBits where she created Minicade. She recently founded Humans Who Play, which is an organization that strives to use play to bring a positive impact on learning, especially in children. She currently resides in Washington D.C which is where Humans Who Play is also located at.

You can see more of her work here.

Min Ji Kim Kim – Looking Outwards – 10

Overview of the Prélude in ACGT project by Pierry Jaquillard.

Prélude in ACGT, created by Pierry Jaquillard at the Media and Interaction Design Unit at ECAL, utilizes Jaquillard’s own DNA chromosomes data and transforms it to generate sound. This project created through JavaScript, midi and Ableton Live, consists of  five interfaces. Two of the interfaces allow the user to control features such as tempo or musical arrangement while the other three, visualize sound, the algorithm type and the DNA itself. The user can also export the midi file to record and generate a musical score using music notation software.

User interface screens of the different features that can be controlled to manipulate the sound.

I really admire this project because it seamlessly combines the field of human biology with computer science. The idea of “coding” DNA is quite practically literally represented in this project. Furthermore, I believe that this project has endless possibilities. No one’s DNA is the same which means that using this software, we would be able to create extremely unique pieces of music. 

552 page musical score representing 0.2% of Jaquillard’s DNA.

Min Ji Kim Kim – Project 10 – Sonic-Sketch


sketch

I got this week’s project inspiration from the facebook emojis and decided to animate them with sound. You can click on each emoji and it will generate the corresponding mood sound. The hardest part of this project was trying to figure out how to use a local host and uploading it to WordPress, but overall, it was really fun!

/*
Min Ji Kim Kim
Section A
mkimkim@andrew.cmu.edu
Project-10
*/

var laugh;
var wow;
var crying;
var angry;

function preload() { //load sound files
    laugh = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/10/laugh.wav");
    wow = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/10/wow.wav");
    crying = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/10/crying.wav");
    angry = loadSound("https://courses.ideate.cmu.edu/15-104/f2019/wp-content/uploads/2019/10/angry.wav");
}

function setup() {
    createCanvas(480, 300);
    noStroke();
    //create different background colors
    fill("#184293"); //laughing emoji
    rect(0, 0, width / 4, height);
    fill("#05B5C3"); //wow emoji
    rect(width / 4, 0, width / 4, height);
    fill('#BC2D15'); //angry emoji
    rect(width / 2, 0, width / 4, height);
    fill(0); //sad emoji
    rect(width * 3 / 4, 0, width / 4, height);
}

function draw() {
    noStroke();
    //create 4 emoji heads
    for (i = 0; i < 4; i++) {
        fill("#FBD771");
        circle(i * width / 4 + 60, height / 2, 90);
    }
    
    //laughing emoji
    //eyes
    stroke(45);
    line(35, 130, 50, 135); //left
    line(35, 140, 50, 135);
    line(70, 135, 85, 130); //right
    line(70, 135, 85, 140);
    //mouth
    noStroke();
    fill(45);
    arc(60, 155, 55, 50, 0, PI);
    fill('#F35269');
    ellipse(60,170,38,20);
    
    //wow emoji
    //eyes & mouth
    fill(45);
    ellipse(160, 140, 13, 20);
    ellipse(200, 140, 13, 20);
    ellipse(180, 170, 25, 35);
    //eyebrows
    noFill();
    stroke(45);
    strokeWeight(3);
    curve(130, 180, 152, 125, 166, 120, 140, 120);
    curve(170, 140, 193, 120, 207, 125, 200, 150);

    //angry emoji
    //eyebrows
    stroke(45);
    strokeWeight(4);
    line(270, 150, 290, 155);
    line(310, 155, 330, 150);
    //eyes
    fill(45);
    circle(283, 157, 5);
    circle(318, 157, 5);
    //mouth
    ellipse(300,170,20,3);

    //crying emoji
    //eyes
    ellipse(400, 150, 10, 12);
    ellipse(440, 150, 10, 12);
    //eyebrows
    noFill();
    stroke(45);
    strokeWeight(3);
    curve(410, 130, 392, 140, 405, 135, 450, 160);
    curve(410, 150, 435, 135, 448, 140, 450, 165);
    //mouth
    arc(420, 175, 20, 15, PI, TWO_PI);
    noStroke();
    //tear
    fill("#678ad6");
    circle(445, 185, 15);
    triangle(438, 182, 445, 165, 452, 182);
}

function mousePressed() {
    if(mouseX < width / 4) { //play lauging sound
        laugh.play();
    }
    if(mouseX > width / 4 & mouseX < width / 2) { //play wow sound
        wow.play();
    }
    if(mouseX > width / 2 & mouseX < width * 3 / 4) { //play angry sound
        angry.play();
    }
    if(mouseX > width * 3 / 4) { //play crying sound
        crying.play();
    }
}

Min Ji Kim Kim – Project 09 – Portrait


sketch

I decided to use a picture of my brother who I miss so much. I played around with a lot of shapes and sizes and I decided to use a water drop shape because my brother loves rain.

halfway done rendering

final stage in rendering

original image of my brother

/*
Min Ji Kim Kim 
Section A
mkimkim@andrew.cmu.edu
Project-09
*/

var originalImage;

function preload() {
    var myImageURL = "https://i.imgur.com/hKHw7ls.jpg";
    originalImage = loadImage(myImageURL); //load image
}

function setup() {
    createCanvas(384, 480);
    background(0);
    originalImage.loadPixels();
    frameRate(1000); //make waterdrops appear faster
}

function draw() {
    var px = random(width); //x coordinate
    var py = random(height); //y coordinate
    var ix = constrain(floor(px), 0, width-1);
    var iy = constrain(floor(py), 0, height-1);
    var locationColor = originalImage.get(ix, iy); //get pixel color

    //make waterdrop shape
    var rectSize = random(3,10); //change waterdrop size
    noStroke();
    fill(locationColor);
    rect(px, py, rectSize, rectSize, 0, 5, 5, 5);
}

Min Ji Kim Kim – Looking Outwards – 09

Creative miniworld by Jan Reeh

For this week’s Looking Outward post, I chose to review Claire Yoon’s Looking Outwards 05. The 3D computer graphic piece that she reviewed was CG/FX artist Jan Reeh’s Creative miniworld created in 2012 through 3Ds Max and rendered in Vray. Similarly to Claire, I was drawn to this piece because of how the word “creative” is expressed very literally and how the artist weaves a story into this 3D piece.

Closeup of the letter C in Creative miniworld

The other part that really caught my eye was the level of extreme detail and texture Reeh created, such as the grass or the bricks on the letter A. Furthermore, the effective use of sound, such as the explosion and the car engine, combined with the use of color and texture create a synergy that really breathes life into this piece. Claire also mentioned how the canvas fills left to right mimicking how we read words left to right which I thought was spot on analysis on her part and ingenious of Reeh to do.

You can see Jan Reeh’s portfolio here.

Min Ji Kim Kim – Looking Outwards – 08

Ben Fry’s talk at Eyeo 2015.

Ben Fry is a data visualization expert and principal of Fathom Information Design, a design and software consultancy in Boston. He received his PhD in Computational Information Design from the Aesthetics and Computation Group at the MIT Media Lab. He also co-developed Processing, which he has received awards for.

Fry’s work focuses on data visualization as a means to help audiences understand and digest dense amounts of information. I really admire Fry’s portfolio because his visualizations are not only aesthetically pleasing, but also manipulate complex information to be easily digestible.

I was particularly interested in No Ceilings: The Full Participation Project. It visualizes over 850,000 data points from the last twenty years on gains women and girls have made around the world in terms of health, education, economic participation and social inclusion. As a woman myself, visually seeing what kinds of progress we have made in different sectors really inspired me.

Video overview of No Ceilings: The Full Participation Project.

Fry not only effectively visualizes data but also effectively discusses it as well. He thoroughly explains the background to his work as well as the actual work itself by going through it with the audience, giving them that comprehensive understanding that I want my work to have too.