// 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!