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!

Leave a Reply