dayoungl & kyungak – Final project

Please refer to the gif file for how the game works.The objective of our game, “TOM” is to survive from the bombs by navigating its to stay away from bombs. A little bonus of the game would be eating hearts to achieve higher points. One can navigate the character using the arrow keys. The scoreboard on the top right corner keeps track of the hearts the character eats. Each time character consumes a heart, it will be logged as +1 on the scoreboard; whenever the character comes into contact with the puffs, it will result in -1 point from the scoreboard. When the character comes into contact with the bomb, the game will end with a “gameover” message. When heart and bomb collides with each other, the heart will turn into a little fire icon indicating that the heart is gone.

Download the PLAY-ME version to play the game on your device.

PLAY-ME
GRADE-ME

data-width=”800″ data-height=”800″TOM-FINAL

//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 preload() {

  //Preloading gameover and scoreboard image
  gameover = loadImage("https://i.imgur.com/VlLC4xC.png");
  scoreboard = loadImage("https://i.imgur.com/8ke3Z26.png");

}

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;
          p.addSpeed(attraction, angle);

        }
      }

      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;
          p.addSpeed(attraction2, angle2);

        }

      }
  }

  //(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.addAnimation("bomb", "https://i.imgur.com/N4m1kty.png");
  b.setSpeed(2, random(0,360));
  b.noisePosition = random(0, 1000);
  b.maxSpeed = 2;
  bomb.add(b);

}

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

  var e = createSprite(x, y);
  e.addAnimation("bomb", "https://i.imgur.com/wzVAcbK.png");
  e.setSpeed(2, random(0,360));
  e.noisePosition = random(0, 1000);
  e.maxSpeed = 2;
  explosion.add(e);

}

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

  var a = createSprite(x,y);
  a.addAnimation("eat", "https://i.imgur.com/b9C1Xyl.png");
  a.setSpeed(2, random(0,360));
  a.noisePosition = random(0, 1000);
  a.maxSpeed = 2;
  eating.add(a);

}

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

  var p = createSprite(x, y);
  p.addAnimation("puff", "https://i.imgur.com/cs8Mkcr.png");
  p.setSpeed(-2, random(0,360));
  p.maxSpeed = 1;
  puff.add(p);

}

//Heart is created
function createHeart(x, y) {
  
  var h = createSprite(x, y);
  h.addAnimation("heart", "https://i.imgur.com/u2uRAYl.png");
  h.life = 300; 
  heart.add(h);

}

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

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

}

















eeryan + yoonyouk_Final Project

sketch

// Erin Ryan and Yoon Young Kim
// eeryan@andrew.cmu.edu
// yoonyouk@andrew.cmu.edu
// Section C and Section E
//FINAL PROJECT - water animation


//HOME PAGE VARIABLES
//STARTING CODE WITH HOME PAGE
var animation = 0;
//text position variables
var textStart1 = 0;
var textStart2 = 140;
var textStart3 = 280;
var textStart4 = 420;
var textSpace = 140;

//RAINFALL ANIMATION VARIABLES
var numClicks = 0; 
var fall = false; //starting the animation off
var water = [];
var xr; //x position of water droplets

//COHESION ANIMATION VARIABLES
var move = false;
var drop1; //first water object 
var drop2; //second water object 
var opacity = 100; //variable to deal with changing opacity of fills and strokes of different water objects

//RIPPLE ANIMATION VARIABLES
var rx;
var ry;
var diam;

//SPLASH ANIMATION VARIABLES
var SPLASH = [];
var droplets = [];
var dropX = -50; //x coordinate of the water drop
var dropY = 0; // y coordinate of the water drop
var splashpoint = 150;
var numClick = 0;
var explodeTime;
var timeElapsed;
var splashed = false;

function preload(){
    var splashImgs = [];
    //img links of the splash droplets
    splashImgs[0] = "https://i.imgur.com/Aau3BBu.png";
    splashImgs[1] = "https://i.imgur.com/C156jX4.png";
    splashImgs[2] = "https://i.imgur.com/nnR9v06.png";

    //cycling images by pushing into SPLASH array
    for(var i = 0; i<3; i++){
        SPLASH.push(loadImage(splashImgs[i]));
    }
}

function setup() {
  createCanvas(400, 300);
  //object declaration for cohesion animation
  drop1 = makeDrop(120, height / 2, 100);
  drop2 = makeDrop(width - 120, height / 2,100);
  //pushes raindrop objects into the array water
  for(var i = 0; i < 300; i++){
    xr = random(0, width); 
    water.push(makeRain(xr, 20, 5, 0)); 
  }
}

function draw() {
  //default page
  if(animation === 0){ 
    background(173, 212, 255);
    textSize(20);
    fill(255, 255, 255);
    textFont("Courier New")
    text("let's play with water!", width / 2 - 130, 100);
    menuText(200);
  }
  //ripple animation
  if(animation == 1){ 
    background(238, 252, 255);
    noStroke();
    fill(80, 130, 200);
    textFont("courier", 16);
    textAlign(CENTER);
    text("click to touch the water...", width / 2, 30); // creates text guiding user to press a key
    ripple(rx, ry);
    if(diam < 550){
      diam += 1; //circle expands
      opacity -= 0.4; //circle becomes less opaque as it expands
    }
    menuText(275);
  }
  //splash animation
  else if(animation == 2){
    background(238, 252, 255);
    noStroke();
    fill(80, 130, 200);
    textFont("courier", 16);
    textAlign(CENTER);
    text("click to splash water droplets", width / 2, 30); // creates text guiding user to press a key
    fill(26, 133, 192);
    if(dropY > 0 & dropY < splashpoint){
        droplet(dropX, dropY);
        dropY++;
    }
    if(dropY == splashpoint){
        splashed = true;
        if(explodeTime == null){
          explodeTime = frameCount;  
        }
    }
    if(splashed == true){
        timeElapsed = frameCount - explodeTime;
    for(var i = 0; i < 12; i++){
        if(timeElapsed == i){
            imageMode(CENTER);
            image(SPLASH[floor(i / 4)], dropX, dropY);
            }
        }
    }
    menuText(275);
  }
  //rain code animation
  else if(animation == 3){ 
    background(238, 252, 255);
    fill(80, 130, 200);
    textFont("courier", 16);
    textAlign(CENTER);
    text("click once for to make it rain...", width / 2, 30); // creates text guiding user to press a key
    text("click again for clear skies", width / 2, 55);
    if(fall){ 
      for(var i = 0; i < water.length; i++){
        water[i].render();
        water[i].fall();
      }
    }
    menuText(275);
  }
  //cohesion animation
  else if(animation == 4){ 
    background(238, 252, 255);
    textAlign(CENTER);
    noStroke();
    fill(80, 180, 200);
    textFont("courier", 16);
    text("click to see cohesion...", width / 2, 30);
    drop1.render();
    drop2.render();
    if(dist(drop1.x, drop1.y, drop2.x, drop2.y) > 0 & move){// if the two objects are not on top of each other and move == true
      drop1.x++;                                            // move the two drops towards each other and lessen the opacity of their strokes
      drop2.x--;
      opacity -= 1.3;
    }
    menuText(275);
  }
}
    
function keyTyped(){ // assigns a different value to the variable animation based on the key pressed
    if (key == 'r'){ 
      animation = 1;
    }
    if (key == 's'){ 
      animation = 2;
    } 
    if (key == 'u'){ 
      animation = 3;
    }                                             
    if (key == 'c'){ 
      animation = 4;
    } 
    
}

function menuText(posY){ //makes menu scroll with instructions
    noStroke();
    fill(80, 130, 200);
    textSize(10);
    text("press R for ripples", textStart1, posY);
    text("press S for splash", textStart2, posY);
    text("press U for rain", textStart3, posY);
    text("press C for cohesion", textStart4, posY);
    textStart1++;
    textStart2++;
    textStart3++;
    textStart4++;
    if(textStart1 > width){
        textStart1 = -140;
    }    
    if(textStart2 > width){
        textStart2 = -140;
    }
    if(textStart3 > width){
        textStart3 = -140;
    }
    if(textStart4 > width){
        textStart4 = -140;
    }
}

function mousePressed(){
  //variable reset for ripple code
  diam = 0;
  opacity = 100;
  rx = mouseX;
  ry = mouseY;
  if(animation == 2){
    numClick++;
    dropX = mouseX;
    dropY = 1;
    splashpoint = mouseY;
  }

  //rain
  if(animation == 3){
    numClicks++;
    if(numClicks%2 == 1){
      fall = true;
    }
    else{
      fall = false;
    }
  }

  //cohesion
  if(animation == 4){
    move = true;
  }
}

function ripple(px, py){ //draws ripples
  noFill();
  strokeWeight(2.5);
  stroke(0, 0, 255, opacity);
  ellipse(px, py, diam, diam);
  strokeWeight(2);
  ellipse(px, py, diam / 2, diam / 2);
  strokeWeight(1.5);
  ellipse(px, py, diam / 4, diam / 4);
}

function droplet(x, y){
  fill(26, 133, 192);
  //using the map function in order to expand the drop as it moves down
  var xmap = map(dropY, 0, height, 5, 15);
  var ymap = map(dropY, 0, height, 10, 30);
  noStroke();
  beginShape();
  curveVertex(x, y);
  curveVertex(x, y);
  curveVertex(x - xmap, y + ymap);
  curveVertex(x, y + ymap + xmap);
  curveVertex(x + xmap, y + ymap);
  curveVertex(x, y);
  curveVertex(x, y);
  endShape();    
}

//object implementation for cohesion animation
function drawDrop(){ //draws water drop for cohesion animation
  stroke(80, 130, 200, opacity);
  strokeWeight(3);
  fill(230, 242, 255);
  ellipse(this.x, this.y, this.w, this.w);
  noStroke();
}

function makeDrop(posX, posY, diam){//make water drop object for cohestion animation
  var drop = {x:posX, y:posY, w:diam, render:drawDrop};
  return drop;
}

//object implementation for rain animation
function makeRain(px, py, diam, velocity){ //make rain object
  var raindrop = {x:px, y:py, d:diam, v:velocity, render: drawRain, fall:rainFall};
  return raindrop;
}

//draws raindrop
function drawRain(){
  noStroke();
  fill(0, 10, 150, 60);
  ellipse(this.x, this.y, this.d, this.d);
  triangle(this.x - (this.d)/2, this.y, this.x, this.y - 5, this.x + (this.d)/2, this.y);
}

function rainFall(){
  this.v = random(0,8); //randomizess velocity variable
  this.y += this.v; //adds velocity to current y value of each rain drop objects so they'll fal at different speeds
  if(this.y >= height){ //resets rain drops to the top once it hits the bottom of the page
    this.y = 0;
  }
}

For this project, I collaborated with Erin Ryan from Lab section C to make a series of four water-based animations using different animation, interactive, and object oriented techniques. We coded the four interactive animations and the home screen separately, then used a series of conditionals to allow the user to toggle between different animations. We tried to establish cohesive visual language through use of color and simple shapes.

 

Initial sketches of water animations

mecha-alchan-final-project

Use the number keys in order to progress in the story!

sketch

var playerChoices = [];
var currentScene = 0;
var sceneList = [];

var leggyFish = [];
var leggyFishLoad = [];

var cat = [];
var catLoad = [];

var catFamily = [];
var catFamilyLoad = [];

var possums = [];
var possumsLoad = [];

var backgrounds = [];
var backgroundsLoad = [];

var endingImages = [];
var endingImagesLoad = [];

var items = [];
var itemsLoad = [];

function preload(){
    //preloads images for background, characters, items, etc.
    //imgur file link https://imgur.com/a/I9BTC

    //backgrounds
    //home
    backgrounds[0] = "https://i.imgur.com/fdhG0uX.png";
    //store
    backgrounds[1] = "https://i.imgur.com/XLXhiQ1.png";
    //street
    backgrounds[2] = "https://i.imgur.com/C9gVejq.png";
    //possum ending
    backgrounds[3] = "https://i.imgur.com/hoVazkD.png";
    //lose ending
    backgrounds[4] = "https://i.imgur.com/Dyp8s1Z.png";

    //characters
    //cat neutral
    cat[0] = "https://i.imgur.com/3edcYR9.png";
    //cat sad
    cat[1] = "https://i.imgur.com/u1bIhz2.png";
    //cat happy
    cat[2] = "https://i.imgur.com/YFuQ8tH.png";

    //cat family neutral
    catFamily[0] = "https://i.imgur.com/iWE061b.png";
    //cat family angry
    catFamily[1] = "https://i.imgur.com/dwXS352.png";
    //cat family happy
    catFamily[2] = "https://i.imgur.com/gJDwiOw.png";
    //cat full family
    catFamily[3] = "https://i.imgur.com/qJ2XmCm.png";

    //leggy fish neutral
    leggyFish[0] = "https://i.imgur.com/afO8XhG.png";
    //leggy fish sad
    leggyFish[1] = "https://i.imgur.com/h90qSVH.png";
    //leggy fish happy
    leggyFish[2] = "https://i.imgur.com/kSy0YDp.png";

    //possums neutral
    possums[0] = "https://i.imgur.com/BV6DYd7.png";
    //possums mad
    possums[1] = "https://i.imgur.com/2EGHdrk.png";

    //water ending
    endingImages[0] = "https://i.imgur.com/QwObsf3.png";
    //milk ending
    endingImages[1] = "https://i.imgur.com/NO4hAnK.png";
    //bad possum ending
    endingImages[2] = "https://i.imgur.com/smECEKi.png";
    //good possum ending
    endingImages[3] = "https://i.imgur.com/EX8XQjv.png";
    //bad cat ending
    endingImages[4] = "https://i.imgur.com/mjmR2QE.png";
    //good cat ending
    endingImages[5] = "https://i.imgur.com/Xj8lU3S.png";
    //leggy fish ending
    endingImages[6] = "https://i.imgur.com/ni1ZpWr.png";

    //knock off oreos image
    items[0] = "https://i.imgur.com/0RvrPHJ.png";
    //fish
    items[1] = "https://i.imgur.com/cIw1WkF.png";
    //grocery store PANTS
    items[2] = "https://i.imgur.com/bRV6gGk.png";
    //milk
    items[3] = "https://i.imgur.com/Psx2phG.png";

    // load all images and add to appropriate arrays
    for(var b = 0; b < backgrounds.length; b++){
        backgroundsLoad[b] = loadImage(backgrounds[b]);
    }
    for(var c = 0; c < cat.length; c++){
        catLoad[c] = loadImage(cat[c]);
    }
    for(var cF = 0; cF < catFamily.length; cF++){
        catFamilyLoad[cF] = loadImage(catFamily[cF]);
    }
    for(var l = 0; l < leggyFish.length; l++){
        leggyFishLoad[l] = loadImage(leggyFish[l]);
    }

    for(var p = 0; p < possums.length; p++){
        possumsLoad[p] = loadImage(possums[p]);
    }

    for(var e = 0; e < endingImages.length; e++){
        endingImagesLoad[e] = loadImage(endingImages[e]);
    }

    for(var i = 0; i < items.length; i++){
        itemsLoad[i] = loadImage(items[i]);
    }
}

function createScenes() {
    // create all scenes & choices and add them to an array
    // format: main dialogue, choice 1 text, choice 1 next scene #,
    //         choice 2 text, choice 2 next scene #,
    //         choice 3 text (or "none"), choice 3 next scene,
    //         background image, character image
    // should set up a spreadsheet to keep track of scene nums

    //scenes at home
    sceneList.push(makeScene("you wake up", "time for cereal", 1,
    "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("oh no! you're out of milk", "go to store", 4,
    "water's basically the same thing", 2, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    //ENDING 1
    sceneList.push(makeScene("this cereal is reacting strangely to water...","BOOM!!!",3,"none",0,"none",0,backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("your cereal spontaneously combusted", "none", 0, "none", 0, "none", 0, backgroundsLoad[0],backgroundsLoad[0]));

    //store scenes
    sceneList.push(makeScene("the sun is shining as you walk down the street", "head to the store", 5, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]))
    sceneList.push(makeScene("you're here for milk, but you're tempted to pick something else up", "resist the temptation", 6,
    "wander the aisles", 9, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("you're on a mission", "take your milk home", 7, "actually, wait...", 9, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));

    //ENDING 2
    sceneList.push(makeScene("you eat your cereal", "wow, you're so boring", 8, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("technically you win, but you are a loser", "none", 0, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    sceneList.push(makeScene("you head to the...", "junk food aisle", 10, "seafood section", 11, "dairy section", 6, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("you do love your sweets", "let's get some roreos", 13, "aren't you on a diet", 9, "wait what's that", 12, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("the fish are so fresh", "why not?", 25, "you don't even like seafood", 9, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("are those........ pants", "grocery store pants oh heck yeah", 42, "you don't trust no grocery store pants", 9, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("you have just enough money", "time to go home", 14, "none", 0, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));

    //possum scenes
    sceneList.push(makeScene("you stroll down the street", "what's that?", 15, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("something emerges from a trah can", "say hi to the... possums?", 16, "none", 0, "none", 0, backgroundsLoad[2], possumsLoad[0]));
    sceneList.push(makeScene("the possums eye your purchase", "excuse YOU, these are mine", 17, "offer a cookie", 20, "none", 0, backgroundsLoad[2], possumsLoad[0]));
    sceneList.push(makeScene("the possums watch disapprovingly as you walk down the street", "whatever, time for cookies", 18, "none", 0, "none", 0, backgroundsLoad[2], possumsLoad[1]));

    //ENDING 3
    sceneList.push(makeScene("every bite of cookie tastes like regret", "the possums have cursed you", 19, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("death is coming for you", "none", 0, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    sceneList.push(makeScene("the possum grabs the entire package out of your hands and vanishes", "oh well", 21, "none", 0, "none", 0, backgroundsLoad[2], possumsLoad[0]));
    sceneList.push(makeScene("you unlock the door with no cookies or milk", "you hear strange rustling sounds", 22, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("there's an army of possums in your house", "welcome your new family", 23, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[3]));

    //ENDING 4
    sceneList.push(makeScene("they push forward a gallon of milk", "you did the right thing", 24, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[3]));
    sceneList.push(makeScene("the possums are in the house", "none", 0, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[3]));

    //cat scenes
    sceneList.push(makeScene("you have just enough money", "time to go home", 26, "none", 0, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("you stroll down the street", "something scurries by", 27, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("a scrawny cat begs for help", "you coldly walk on", 28, "aw, he looks hungry", 34, "none", 0, backgroundsLoad[2], catLoad[1]));
    sceneList.push(makeScene("you are heartless, but not fishless", "continue on your way", 29, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("as you round the corner, you hear more meows", "it's a family of cats", 30, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[0]));
    sceneList.push(makeScene("you stare at each other", "suddenly, one speaks", 31, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[0]));
    sceneList.push(makeScene("where's father? he was supposed to bring us food", "uh oh...", 32, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[0]));

    //ENDING 5
    sceneList.push(makeScene("you remember the cat from before", "should have given him the fish", 33, "prepare to be eaten", 33, "none", 0, backgroundsLoad[2], catFamilyLoad[1]));
    sceneList.push(makeScene("you become cat food", "none", 0, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[1]));

    sceneList.push(makeScene("the cat politely takes the fish", "farewell sir", 35, "none", 0, "none", 0, backgroundsLoad[2], catLoad[0]));
    sceneList.push(makeScene("as you round the corner, you hear more meows", "it's a family of cats", 36, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[0]));
    sceneList.push(makeScene("you smile at them", "the cat from before appears!", 37, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[3]));
    sceneList.push(makeScene("he gives the fish to his family", "you swear you hear them say ''thanks'' to you", 38, "none", 0, "none", 0, backgroundsLoad[2], catFamilyLoad[3]));
    sceneList.push(makeScene("that was nice", "time to go home, finally", 39, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("when you get home, there's a package at your door", "there's a paw print on it", 40, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    //ENDING 6
    sceneList.push(makeScene("it's... a gallon of milk", "you tearfully thank the cats", 41, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("you have been blessed by cats", "none", 0, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    //leggy fish
    sceneList.push(makeScene("you have just enough money", "time to go home", 43, "none", 0, "none", 0, backgroundsLoad[1], backgroundsLoad[1]));
    sceneList.push(makeScene("you stroll down the street", "there's something odd over there", 44, "none", 0, "none", 0, backgroundsLoad[2], backgroundsLoad[2]));
    sceneList.push(makeScene("a fish head peaks at you from behind a bush", "why does this fish has legs", 45, "none", 0, "none", 0, backgroundsLoad[2], leggyFishLoad[0]));
    sceneList.push(makeScene("you should really get to know your neighbors", "...some other time", 46, "he looks sad and cold", 47, "none", 0, backgroundsLoad[2], leggyFishLoad[1]));
    sceneList.push(makeScene("what are you, heartless", "those pants won't fit you anyways", 47, "none", 0, "none", 0, backgroundsLoad[2], leggyFishLoad[1]));
    sceneList.push(makeScene("you look at your grocery store pants", "give the fish pants", 48, "give the fish pants", 48, "GIVE THE FISH PANTS", 48, backgroundsLoad[2], leggyFishLoad[1]));
    sceneList.push(makeScene("the fish hurriedly puts them on", "leggy fish looks quite dapper in those pants", 49, "none", 0, "none", 0, backgroundsLoad[2], leggyFishLoad[2]));
    sceneList.push(makeScene("you wave good bye", "leggy fish signals you to wait", 50, "none", 0, "none", 0, backgroundsLoad[2], leggyFishLoad[2]));
    sceneList.push(makeScene("the fish pulls a box from behind the bush", "thank you?", 51, "none", 0, "none", 0, backgroundsLoad[2], leggyFishLoad[2]));
    sceneList.push(makeScene("you head home with the box", "let's see what's inside", 52, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));

    //ENDING 7
    sceneList.push(makeScene("it's a gallon of milk", "wow, you have such nice neighbors", 53, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
    sceneList.push(makeScene("this is the true ending", "none", 0, "none", 0, "none", 0, backgroundsLoad[0], backgroundsLoad[0]));
}

function setup() {
    createCanvas(480, 360);
    createScenes();
}

function draw() {
    // render the current scene
    sceneList[currentScene].draw();
}

function keyPressed() {
    var sceneToChange;
    // check which key is pressed
    // & switch to the correct scene depending on the current scene
    if(key == 1) {
        sceneToChange = sceneList[currentScene].next1;
        currentScene = sceneToChange;
    } else if(key == 2 & sceneList[currentScene].opt2 != "none") {
        sceneToChange = sceneList[currentScene].next2;
        currentScene = sceneToChange;
    }
    // make sure this is a 3rd option
    else if(key == 3 & sceneList[currentScene].opt3 != "none") {
        sceneToChange = sceneList[currentScene].next3;
        currentScene = sceneToChange;
    }
}

function drawScene() {
    // draw background image
    image(this.bg,0,0,480,360);

    // draw character or item
    image(this.character,0,0,480,360);

    // text underlay
    fill(250, 250, 250, 200);
    noStroke();
    rect(0, (2/3)*height, width,(1/3)*height);

    // draw ending text
    if(currentScene == 3 || currentScene == 8 || currentScene == 19 || currentScene == 24 || currentScene == 33 || currentScene == 41 || currentScene == 53){
        textAlign(CENTER);
        image(backgroundsLoad[4],0,0);
        fill(255);
        text("press '1' to play again ", width/2, 290);
    }
    else{
        fill(0);
    }

    //adds items
    if(currentScene == 12){
        image(itemsLoad[2],0,0);
    }
    if(currentScene == 10){
        image(itemsLoad[0],0,0);
    }
    if(currentScene == 11){
        image(itemsLoad[1], 0, 0);
    }
    if(currentScene == 6 || currentScene == 40 || currentScene == 52 || currentScene == 23){
        image(itemsLoad[3],0,0);
    }

    //adds ending images
    if(currentScene == 3){
        image(endingImagesLoad[0],0,0);
    }
    if(currentScene == 8){
        image(endingImagesLoad[1],0,0);
    }
    if(currentScene == 19){
        image(endingImagesLoad[2],0,0);
    }
    if(currentScene == 24){
        image(endingImagesLoad[3],0,0);
    }
    if(currentScene == 33){
        image(endingImagesLoad[4],0,0)
    }
    if(currentScene == 41){
        image(endingImagesLoad[5],0,0);
    }
    if(currentScene == 53){
        image(endingImagesLoad[6],0,0);
    }
    // draw main dialogue
    textAlign(CENTER);
    textStyle(NORMAL);
    textFont("Courier", 12);
    text(this.dialogue, width/2, 260);

    // draw options
    textAlign(LEFT);
    textStyle(ITALIC);
    // check if each option exists before drawing it
    if(this.opt1 != "none"){
        text("1. " + this.opt1, width/2-150, 290);
    }
    if(this.opt2 != "none") {
        text("2. " + this.opt2, width/2-150, 310);
    }
    if(this.opt3 != "none") {
        text("3. " + this.opt3, width/2-150, 330);
    }
}

// create a scene object
function makeScene(words, one, n1, two, n2, three, n3, b, c) {
    var scene = {dialogue: words,
        opt1: one,
        next1: n1,
        opt2: two,
        next2: n2,
        opt3: three,
        next3: n3,
        bg: b,
        character: c,
        draw: drawScene}
        return scene;
    }

For this project, I collaborated with Allissa Chan in order to create a choice-based game revolving around a trip to the grocery store. We used objects in order to implement all of the scenes, and created our graphics using Adobe Photoshop. There are seven different routes/endings within the game (including our definition of a “true” ending).




sntong-Final-Project

This is a simple audio and visualization program that deals mainly with interaction of the keypad with music and geometric visualization. To start the program, press enter and play around with timing of sounds and visualization by pressing keys such as “W”,”A”,”S”,”D”, “I”, “J”, “K”, “L” that will work with the background music. Last but not least, have fun and explore different combination of keys to create cool visualizations.

sketch

// Scarlet Tong
//sntong@andrew.cmu.edu
// Final Project

// incrementally increase the x, y  parameter
var inc = 0.02;
// ze of each grid spacing
var scl = 48;
// rows and columns of the grid
var cols, rows;
// introducing a "time" parameter for the lines to move
var zoff = 0;
// variables the squares function will use
var topX;
var topY;
var topX1;
var topY1;
// difference variable that is used for the frames function below
var m = 0;

// declaring variables to store sound files
var backg;
var bass;
var chime;
var beat;
var popp;
// intializing variables that holds and stores Amplitude of the sound for
// the "sound wave" visualization
var amp;
var volhistory = [];
// to make sure sounds don't play and overlap with itself
var dJ = false;
// difference variable that the rings function uses
var step = 0;
// track click count to start the background music and other visualizations
var numClick = 0;
// difference variable used for the knitted function below
var column = 0;

function preload(){
  backg = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/background-1.wav");
  bass = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/bass.wav");
  chime = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/chimes.wav");
  beat = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/steady-beat.wav");
  popp = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/pop.wav");
}

function setup() {
  createCanvas(480, 480);
  // define grid spacing for field function below
  cols = floor(width/scl);
  rows = floor(height/scl);
  // defining variables of for squares function
  topX = width/2;
  topY = height/2;
  topX1 = width/2;
  topY1 = height/2;
}

function draw() {
  background(0);
  // startup page for users before rest of the code runs
  if (numClick == 0) {
    // Ready? icon, press enter key to start
    fill(255);
    rect(200,200,80,80);
    textAlign(CENTER);
    fill(255,255,255,160);
    text("READY?",width/2,height/2-40);
    stroke(180,15,85,100);
    rect(210,245,60,20);
    text("PRESS",width/2,height/2);
    text("ENTER",width/2,height/2+20);
  }
   if (keyIsDown(13) & numClick == 0) {
    numClick +=1;
    // play background music and loop it
    backg.amp(0.5);
    backg.play()
    backg.loop();
    // variable that stores the values of amplitude of the music playing
    amp = new p5.Amplitude();
    stroke(255);
  } if (numClick == 1) {
    // draw the graph that changes based on amplitude of the music
      soundWave();
  }

    // if key "w" is pressed create a "random vector field" with low bass sound
  if (keyIsDown(87)) {
    field();
  }
    // if key "a" is pressed, separating squares with a drum sound
  if (keyIsDown(65)) {
    square();
  } else {
    topX= width/2;
    topY=height/2;
    topX1= width/2;
    topY1=height/2;
  }
  // if "s" is presssed, a series of "rings" will display along with chime sound
  if (keyIsDown(83)) {
    rings();
  }

  // if "d" is pressed, pattern of yellow dots start to appear with pop sound
  if (keyIsDown(68)) {
    pattern();
  }
  // if "i" is pressed a vizualization of corners moving apart
  if (keyIsDown(73)) {
    frames();
  }

  // if "j" is pressed, bars of orange and pink strips start to extend and overlap
  if (keyIsDown(74)) {
    knitted();
  }

  // if "k" is pressed, a set of three rotating shapes appears
  if (keyIsDown(75)) {
    triangles();
  }

  // if "l" is pressed, a grid of pink dots appears
  if (keyIsDown(76)) {
    for (var x = 0; x < width; x+=48) {
      for (var y = 0; y < height; y+=48) {
        fill(180,15,85,100,20);
        noStroke();
        ellipse(x+24+random(1),y+24+random(1),10,10);
      }
    }
  }
  // small text to help prompt users to use the keys to add sound or visual effects
  push();
  fill(100);
  noStroke();
  text("W",30,450);
  text("A   S   D",30,470);
  text("I",440,450);
  text("J   K   L",440,470);
  pop();

}

// assign sound to each key
  function keyPressed(){
    // if key "w" is pressed, play the low bass sound
    if (keyCode === 87) {
      bass.play();
      dJ = true;
    }
    // if key "s" is pressed, a small "chime" sound is played
    if (keyCode === 83) {
      chime.play();
      dJ = true;
    }
    // if "a" is pressed play the short drum sound
    if (keyCode === 65) {
      beat.play();
      dJ = true;
    }
    // if "d" is pressed, play pop sound
    if (keyCode === 68) {
      popp.play();
      dJ = true;
    }
  }

// graph the Amplitude of the sound
function soundWave(){
  // get Amplitude of sound and add it to the array
  var vol = amp.getLevel();
  volhistory.push(vol);
  stroke(255,255,255,170);
  noFill();
  push();
  // map the graph in the middle of the canvas
  translate(0,-height/2+40);
  beginShape();
  for (var i = 0; i < volhistory.length; i++) {
    // remap the values of the amplitude to fit within the canvas size
    var y = map(volhistory[i],0,1,height,0);
    strokeWeight(2);
    vertex(i,y);
    stroke(250,250,250,50);
    strokeWeight(1);
    // draw diagonal lines that help give a 3D sense
    line(i,y,-i,-y);
  }
  endShape();
  pop();
  if (volhistory.length> width) {
  // keep updating and shifting "old" graph backwards to draw new ones.
  volhistory.splice(0,1);
  }
}

//generate a vector field of swaying lines
function field (){
  var yoff = 0;
  // asgn a vector component to the grid that has x number of columns and y number of rows.
  for (var y = 0; y < rows+1; y++) {
    var xoff = 0;
    for (var x = 0; x < cols+1; x++) {
      // create random angle
      var angle = noise(xoff, yoff,zoff)* 40;
      // define angle as an vector to make the lines turn
      var v = p5.Vector.fromAngle(angle);
      xoff += inc;
      stroke(255);
      push();
      // tranlate lines to each intersection of the grid and draw it
      translate(x*scl+scl,y*scl);
      rotate(v.heading());
      strokeWeight(3);
      stroke(180,15,85,100,50);
      line(0,0,scl*2,0);
      pop();
    }
    yoff += inc;
    zoff += 0.00005;
  }
}


// draw two separating squares that move apart until they reach the edge of the canva
// before going back to the center of the canvas.
function square(){
  noStroke();
    // light red color
  fill(180,15,85,100);
  rectMode(CENTER);
  rect(topX1,topY1,200,200);
  // light orange color
  fill(215,122,97,100);
  rect(topX,topY,200,200)
  topX1+=1;
  topY1+=1;
  topX-=1;
  topY-=1;
  // reset squared to the middle of the canvas
  if (topX <80) {
    topX= width/2;
    topY=height/2;
    topX1= width/2;
    topY1=height/2;
  }
}

// make cirlces appear at a random rate to make a pattern
function pattern(){
  push();
  translate(width/2, height/2); // so that the curve is within the canvas
  beginShape();
  for(var i = 0; i < volhistory.length; i++){
    var theta = map(i,0,100,0,500);
    // give the randomly apparenting circles to make a pattern
    var a = map(volhistory[i], 0,1,-10,10);
    //Conchoid of de Sluze equation from Wolfram MathWorld
    var x = (1/cos(theta)+(a*cos(theta)))*cos(theta);
    var y = (1/cos(theta)+(a*cos(theta)))*sin(theta);
    noStroke();
    fill(215,122,97,100);
    //"polar array" the Conchoid from the center
    rotate(90);
    ellipse(x*20+random(0,1),y*20+random(0,1),4,4);
  }
  endShape(CLOSE);
  pop();
}

// draw spinning rings
function rings(){
  push();
  stroke(215,122,97);
  strokeWeight(5);
  strokeCap(SQUARE);
  arc(width/2,height/2,100,100,0-step,HALF_PI-step);
  strokeWeight(3);
  arc(width/2,height/2,80,80,QUARTER_PI-step,PI+HALF_PI-step);
  strokeWeight(2);
  arc(width/2,height/2,150,150,HALF_PI+QUARTER_PI+step,PI+HALF_PI+step);
  strokeWeight(1);
  arc(width/2,height/2, 200,200,0+step,PI+HALF_PI+step);
  // the variable makes each arc to change and rotate
  step+=0.1;
  pop();
}

function frames(){
  // setting up variable that governs the rate of which the corners move away
  if (m >= 0) {
    m+=0.5;
  } // if the displacement of the corners is more than 50 pixels, reset to 0
  if(m == 50) {
    m = 0;
  }
  // small frame
  stroke(255,255,255,150);
  strokeWeight(4);
  // top left corner
  line(190-m,190-m,190-m,240-m);
  line(190-m,190-m,240-m,190-m);
  // top right corner
  line(240+m,190-m,290+m,190-m);
  line(290+m,190-m,290+m,240-m);
  // bottom right corner
  line(290+m,240+m,290+m,290+m);
  line(290+m,290+m,240+m,290+m);
  // bottom left corner
  line(240-m,290+m,190-m,290+m);
  line(190-m,290+m,190-m,240+m);
}

function knitted(){
  // setting up the x and y values to draw the colored columns and rows
  for (var i = 0; i < 8; i++) {
    if (column >= 0) {
      column+=0.25;
    } if(column == width) {
      column = 0;
    }
    noStroke();
    fill(215,122,97,100);
    // yellow bars
    rect(i*width/8,0,30,height/8+column);
    fill(180,15,85,100);
    // pink bars
    rect(0,i*height/8,column,30);
  }
}

function triangles (){
  stroke(215,122,97,100);
  strokeWeight(2);
  push();
  translate(width/2,height/2);
  // set rotation of the triangles to increase with the frameCount
  rotate(radians(frameCount));
  triangle(-50,50,0,-50,50,50);
  strokeWeight(4);
  rotate(radians(frameCount*.5));
  triangle(-60,60,0,-60,60,60);
  strokeWeight(2);
  rotate(radians(frameCount*2));
  triangle(-65,65,0,-65,65,65);
  pop();
}

cduong-Final Project

To be honest, more interesting looking at night after like 7pm.

sketch

//Name: Colleen Duong
//Email: cduong@andrew.cmu.edu
//Section: D
//Final Project

//empty array to store clouds
var clouds = [];

//variables for images
var liloandstitch;
var tangled;
var liloandstitchsurfboard;
var bighero6;

function setup() {
  createCanvas(1000 * 0.5, 500 * 0.5); //scales drawing for wordpress

  liloandstitch = loadImage("https://i.imgur.com/Q8WphXR.png");
  tangled = loadImage("https://i.imgur.com/IPR7Psj.png");
  liloandstitchsurfboard = loadImage("https://i.imgur.com/MovIC2B.png");
  bighero6 = loadImage("https://i.imgur.com/zhYJmIx.png");
}

function draw() {
  scale(0.5); //scales drawing for wordpress
  background(202, 230, 205);
  var H = hour();
  var M = minute();
  var S = second();

  //Sky Color
    //Changes sky color throughout the day according to the hour
  if(H > 0 & H < 13){ //1am to 12pm
		var skyR = H * (180/12); //red
		var skyG = H * (270/12); //green
		var skyB = H * (290/12); //blue
	}else if(H > 13 & H < 23){  //1pm to 11pm
    var skyR = 180 - (H - 12) * (180/12);
    var skyG = 270 - (H - 12) * (270/12);
    var skyB = 290 - (H - 12) * (290/12);
	}else{ //12am
    var skyR = 0;
    var skyG = 0;
    var skyB = 0;
  }


  fill(skyR, skyG, skyB); //Sky changes color according to the if/else statements above
  rect(530, 0, 500, 300);

  drawstars();

  secondstartotheright();

  updateAndDisplayClouds();
  addNewCloudsWithSomeRandomProbability();

  fill(202, 230, 205);  //Green
  rect(0, 0, 520, height);  //Hiro's Wallpaper

  sanfranstokyo();

  HirosRoom();

  clock();

  baymaxhead();

  tangledportrait();

  liloandstitchportrait();

  bighero6portrait();

  chair();
}

function updateAndDisplayClouds(){
  for(var i = 0; i < clouds.length; i++){
    clouds[i].move();
    clouds[i].display();
  }
}

function removeCloudsThatHaveSlippedOutOfView(){
  var cloudsToKeep = [];
  for(var i = 0; i < clouds.length; i++){
    if(clouds[i].x + clouds[i].breadth > 0){
      cloudsToKeep.push(clouds[i]);
    }
  }
  clouds = cloudstoKeep;
}

function addNewCloudsWithSomeRandomProbability(){
  //Spawn a new cloud to the right edge of the canvas
  var newCloudLikelihood = 0.01;
  if(random(0,1) < newCloudLikelihood){
    clouds.push(makeCloud(width));
  }
}

function cloudMove(){
  this.x += this.speed;
}

function cloudDisplay(){
  var cloudHeight = this.altitude * 20;

  push();
  translate(this.x, 50);

  var H = hour();

  //Changes Cloud Colors According to Time
  if(H > 0 & H < 13){ //1am to 12pm
    var skyR = H * (140/12); //red
    var skyG = H * (230/12); //green
    var skyB = H * (250/12); //blue
  }else if(H > 13 & H < 23){ //1pm to 11pm
    var skyR = 140 - (H - 12) * (140/12);
    var skyG = 230 - (H - 12) * (230/12);
    var skyB = 250 - (H - 12) * (250/12);
  }else{  //12am
    var skyR = 20;
    var skyG = 20;
    var skyB = 20;
  }

  fill(skyR, skyG, skyB);
  //Variables randomize the position and sized
  ellipse(0, cloudHeight, this.breadth, cloudHeight-10);
  ellipse(0, cloudHeight-210, this.breadth*0.6, cloudHeight-20);
  ellipse(0, cloudHeight-200, this.breadth, cloudHeight-10);
  ellipse(0, cloudHeight-100, this.breadth, cloudHeight-20);
  pop();
}

function makeCloud(birthLocationX){
  var clouds = {x: birthLocationX,
                breadth: 60,
                speed: -0.2,
                altitude: round(random(-1, 1)),
                move: cloudMove,
                display: cloudDisplay}
  return clouds;
}

function HirosRoom(){
  noStroke();

  //WALLPAPER BOTTOM TRIM
  fill(255);
  rect(0, 440, 1000, 60);
  //WALLPAPER BOTTOM TRIM

  //TRIANGULAR WALL
  fill(97, 69, 62);   //Darkest Brown
  triangle(0, 0, 200, 0, 0, 200);
  //TRIANGULAR WALL

  //GROUND
  fill(97, 69, 62); //Darkest Brown
  rect(0, 485, 1000, 15);
  //GROUND

  //DESK
  fill(209, 178, 169);  //Dark Brown
  rect(150, 300, 300, 40);
  rect(330, 300, 150, 185);

  push();
  stroke(191, 157, 148);  //Darker than Dark Brown
  strokeWeight(2);
  rect(340, 345, 130, 50);  //Drawers
  rect(340, 415, 130, 50);  //Drawers
  pop();

  fill(235, 208, 201);  //Light Brown
  rect(0, 300, 150, 185);
  //DESK

  //DESK ACCESSORIES
  fill(97, 69, 62);   //Darkest Brown
  rect(435, 235, 10, 30); //Pencil
  rect(450, 245, 8, 30); //Pencil
  fill(234, 112, 108);  //Light Red
  rect(430, 255, 30, 45); //Cup
  fill(97, 69, 62);   //Darkest Brown
  rect(320, 270, 120, 30);
  fill(68); //Super Dark Grey
  rect(145, 275, 80, 20);  //Computer
  fill(81, 80, 80); //Dark Grey
  rect(80, 145, 200, 130);  //Computer
  rect(115, 290, 140, 10);  //Computer
  fill(119); //Light Grey
  rect(90, 155, 180, 105);  //Computer
  fill(234, 112, 108); //Light Red
  rect(85, 265, 30, 30); //Post it
  //DESK ACCESSORIES

  //SHELF
  push();
  fill(187, 155, 148);  //Darker than Dark Brown
  rect(300, 40, 10, 90);
  rect(450, 40, 10, 90);

  fill(209, 178, 169);  //Dark Brown
  rect(280, 100, 200, 20);
  rect(280, 50, 200, 20);

  textSize(20);
  textStyle(BOLD);
  textFont("Verdana");
  fill(209, 178, 169);  //Dark Brown
  text("CLICK THE", 325, 50);
  text("PHOTOS", 335, 100);
  pop();
  //SHELF

  //WALL PICTURES
  //WALL PICTURES

  //WINDOW FRAME
  fill(240);
  rect(705, 0, 20, 300);  //Window Frame
  rect(525, 0, 20, 300);  //Window Frame
  rect(520, 280, width, 20);  //Window Frame
  push();
  noStroke();
  rect(706, 0, 19, 300);  //Window Frame
  rect(525, 0, 20, 300);  //Window Frame
  pop();

  fill(86); //Light grey
  rect(530, 0, 180, 10);   //Window Shutters (Left)
  rect(530, 15, 180, 10);   //Window Shutters (Left)
  rect(530, 30, 180, 10);   //Window Shutters (Left)
  rect(530, 45, 180, 10);   //Window Shutters (Left)
  rect(720, 0, width, 10);   //Window Shutters (Right)
  rect(720, 15, width, 10);   //Window Shutters (Right)
  rect(720, 30, width, 10);   //Window Shutters (Right)
  rect(550, 0, 5, 50); //Shutter Connector
  rect(695, 0, 5, 50); //Shutter Connector
  rect(730, 0, 5, 35); //Shutter Connector

  fill(200);
  rect(510, 300, width, 100); //Bed Frame
  fill(255);
  rect(510, 0, 30, 400);  //Bed Frame
  fill(220);
  rect(510, 300, width, 20);  //Bed Frame Back
  fill(255);
  rect(510, 300, 80, 20); //Bed Frame
  push();
  noStroke();
  rect(511, 0, 29, 400);  //Bed Frame

  pop();
  //WINDOW FRAME

  //BED
  fill(148, 160, 205); //Periwinkle
  rect(500, 335, 600, 150, 20);
  //BED
}

function sanfranstokyo(){
  var H = hour();
  var S = second();

  //SANFRANSTOKYO
  //Bridge
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(201, 70, 72); //Red
  }else{
    fill(137, 44, 49); //Darker Red
  }
  rect(690, 260, 200, 10);  //Horizontal
  rect(720, 190, 10, 200);
  rect(830, 190, 10, 200);

  push();
  noFill();
  if(H > 3 & H < 19){//4am to 7pm lighter color
    stroke(201, 70, 72); //Red
  }else{
    stroke(137, 44, 49); //Darker Red
  }

  strokeWeight(2);
  curve(710, -300, 729, 192, 831, 192, 800, -300);
  curve(700, -300, 618, 192, 720, 192, 800, -300);
  curve(850, -300, 839, 192, 933, 192, 710, -300);
  line(680, 250, 680, 260); //Left
  line(690, 241, 690, 260); //Left
  line(700, 229, 700, 260); //Left
  line(740, 222, 740, 260); //Mid
  line(750, 236, 750, 260); //Mid
  line(760, 246, 760, 260); //Mid
  line(770, 252, 770, 260); //Mid
  line(780, 254, 780, 260); //Mid
  line(790, 254, 790, 260); //Mid
  line(800, 250, 800, 260); //Mid
  line(810, 242, 810, 260); //Mid
  line(820, 228, 820, 260); //Mid
  line(850, 223, 850, 260); //Right
  line(860, 236, 860, 260); //Right
  line(870, 246, 870, 260); //Right
  line(880, 252, 880, 260); //Right
  pop();

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(219, 93, 100); //Light Red
  }else{
    fill(165, 61, 72); //Darker Light Red
  }
  rect(720, 190, 14, 10);
  rect(720, 215, 14, 10);
  rect(720, 240, 14, 10);
  rect(826, 190, 18, 10);
  rect(826, 215, 18, 10);
  rect(826, 240, 18, 10);
  //Bridge

  //Building 3 (Left)
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(200);
  }else{
    fill(150);
  }
  rect(655, 210, 30, 30); //Roof Box

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(230);
  }else{
    fill(180);
  }
  rect(620, 240, 70, 80); //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(50);
  }else{
    fill(255, 242, 6);
    if(S % 3){
      fill(249, 214, 38);  //Blinking Effect
    }//Light
  }
  rect(650, 250, 35, 10); //Ribbon Window
  rect(650, 265, 25, 10); //Ribbon Window
  //Building 3 (Left)

  //Building 2 (Right)
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(254, 252, 238); //Pale Yellow
  }else{
    fill(216, 213, 195); //Darker Pale Yellow
  }
  rect(880, 250, 70, 40); //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(79, 106, 112); //Teal
  }else{
    fill(50, 70, 73); //Darker Teal
  }
  triangle(860, 250, 880, 230, 900, 250); //Roof
  rect(880, 230, 70, 20); //Roof
  fill(0);
  rect(880, 210, 70, 20); //Roof

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(79, 106, 112); //Teal
  }else{
    fill(50, 70, 73); //Darker Teal
  }
  triangle(860, 210, 920, 160, 900, 210); //Roof
  triangle(870, 210, 920, 140, 950, 210); //Roof
  rect(880, 200, 70, 10); //Roof
  rect(915, 140, 70, 10); //Roof
  //Building 2 (Right)

  //Building 2 (Left)
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(254, 252, 238); //Pale Yellow
  }else{
    fill(216, 213, 195); //Darker Pale Yellow
  }
  rect(580, 220, 70, 80); //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(102, 72, 55); //Dark Brown
  }else{
    fill(73, 50, 39); //Darker Dark Brown
  }
  rect(580, 150, 70, 80); //Roof Box

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(144, 117, 108); //Light Brown Roof
  }else{
    fill(104, 81, 75); //Darker Light Brown Roof
  }
  rect(530, 220, 150, 10); //Roof

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(102, 72, 55); //Dark Brown
  }else{
    fill(73, 50, 39); //Darker Dark Brown
  }
  rect(580, 150, 70, 80); //Roof Box
  rect(530, 230, 120, 5); //Brace
  rect(530, 255, 120, 5); //Brace
  rect(600, 230, 5, 30); //Brace
  //building 2(Left)

  //Building 1 (Right)
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(255);
  }else{
    fill(200);
  }
  rect(930, 200, 100, 80);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(233);
  }else{
    fill(180);
  }
  rect(925, 200, 100, 2);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(255);
  }else{
    fill(200);
  }
  rect(925, 170, 100, 30);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(144, 117, 108);  //Brown
  }else{
    fill(107, 86, 81);  //Darker Brown
  }
  rect(925, 150, 100, 20);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(233);
  }else{
    fill(180);
  }
  rect(925, 150, 100, 2);  //Base
  rect(950, 110, 100, 20);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(255);
  }else{
    fill(200);
  }
  triangle(925, 150, 910, 130, 950, 130);
  rect(925, 130, 100, 20);  //Base

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(85, 96, 85);
  }else{
    fill(251, 237, 36); //Light
    if(S % 6){
      fill(249, 214, 38);  //Blinking Effect
    }
  }
  rect(935, 207, 30, 40);  //Window
  rect(970, 207, 30, 40);  //Window
  rect(935, 252, 30, 40);  //Window
  rect(970, 252, 30, 40);  //Window

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(233);
  }else{
    fill(180);
  }
  rect(943, 208, 2, 38);  //Window (T.Left)
  rect(955, 208, 2, 38);  //Window (T.Left)
  rect(936, 220, 28, 2);  //Window (T.Left)
  rect(936, 235, 28, 2);  //Window (T.Left)
  rect(978, 208, 2, 38);  //Window (T.Right)
  rect(990, 208, 2, 38);  //Window (T.Right)
  rect(971, 220, 28, 2);  //Window (T.Right)
  rect(971, 235, 28, 2);  //Window (T.Right)
  rect(943, 253, 2, 38);  //Window (B.Left)
  rect(955, 253, 2, 38);  //Window (B.Left)
  rect(936, 265, 28, 2);  //Window (B.Left)
  rect(936, 265, 28, 2);  //Window (B.Left)
  rect(978, 253, 2, 38);  //Window (B.Right)
  rect(990, 253, 2, 38);  //Window (B.Right)
  rect(971, 265, 28, 2);  //Window (B.Right)
  rect(971, 265, 28, 2);  //Window (B.Right)
  //Building 1 (Right)

  //Building 1 (Left)
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(255, 239, 205); //Pale Yellow
  }else{
    fill(234, 215, 181); //Darker Pale Yellow
  }
  rect(540, 100, 50, 200);
  rect(590, 120, 20, 5); //Sign
  rect(590, 200, 20, 5); //Sign

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(234, 112, 108); //Pale Red
  }else{
    fill(206, 91, 91); //Darker Pale Red
  }
  rect(600, 115, 50, 100); //Sign

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(255, 239, 205); //Pale Yellow
  }else{
    fill(234, 215, 181); //Darker Pale Yellow
  }
  rect(605, 120, 40, 90); //Sign

  push();
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(85, 52, 148); //Bright-ish Dark Blue
  }else{
    fill(255); //Brighter Bright-ish Dark Blue
    if(S % 2){  //Light Blinking Effect
      fill(117, 91, 178);
    }
  }
  textSize(25);
  textStyle(BOLD)
  text("ホ", 613, 150);
  text("テ", 613, 180);
  text("ル", 613, 210);  //Hotel
  pop();

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(80); //Dark Grey
  }else{
    fill(40); //Darker Grey
  }
  rect(590, 210, 20, 5); //Sign
  rect(590, 245, 20, 5); //Sign

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(119); //Light grey
  }else{
    fill(70); //Darker Light Grey
  }
  rect(610, 200, 60, 60); //Sign

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(80); //Dark Grey
  }else{
    fill(40); //Darker Grey
  }
  rect(610, 200, 25, 60); //Sign

  push();
  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(80);
  }else{
    fill(150);
    if(S % 2){  //Light Blinking Effect
      fill(255);
    }
  }
  textSize(8);
  textStyle(BOLD);
  text("ミ", 655, 213);
  text("ッ", 655, 226);
  text("キ", 655, 239);
  text("|", 659, 252);
  text("マ", 640, 213);
  text("ウ", 640, 226);
  text("ス", 640, 239);  //Mickey Mouse!
  pop();

  if(H > 3 & H < 19){//4am to 7pm lighter color
    fill(247, 223, 181);  //Dark Pale Yellow
  }else{
    fill(221, 194, 151); //Darker Dark Pale Yellow
  }
  rect(540, 100, 55, 10);
  rect(540, 160, 55, 10);
  rect(540, 220, 55, 10);

  if(H > 3 & H < 19){//4am to 7pm lighter color
  fill(234, 206, 150); //Dark Pale Yellow Shadow
  }else{
    fill(209, 180, 130); //Darker Dark Pale Yellow Shadow
  }
  rect(540, 110, 50, 2);
  rect(540, 170, 50, 2);
  rect(540, 230, 50, 2);
  //Building 1 (Left)
  //SANFRANSTOKYO
}

function drawstars(){
  var H = hour();

  //Draws Stars in the sky after 7pm
    if(H > 3 & H < 19){
    }else{
      fill(255);
      rect(600, 100, 5, 1);
      rect(602, 98, 1, 5);
      rect(700, 150, 5, 1);
      rect(702, 148, 1, 5);
      rect(800, 80, 5, 1);
      rect(802, 78, 1, 5);
      rect(750, 40, 5, 1);
      rect(752, 38, 1, 5);
      rect(888, 120, 5, 1);
      rect(890, 118, 1, 5);
      rect(940, 80, 5, 1);
      rect(942, 78, 1, 5);
      rect(620, 80, 5, 1);
      rect(622, 78, 1, 5);
      rect(760, 140, 5, 1);
      rect(762, 138, 1, 5);
    }
}


function secondstartotheright(){  //Peter Pan Easter Egg
  var H = hour();

  if(H > 2 & H < 23){  //Star only appears at 11pm
  }else{
    fill(175, 223, 249);
    rect(950, 70, 10, 1);
    rect(955, 66, 1, 10);
  }
}

function clock(){

  var H = hour();
  var M = minute();
  var S = second();

  //WALL-E's Eve
  fill(250);  //Arms
  ellipse(559, 240, 10, 22);
  ellipse(580, 240, 10, 22);
  fill(255); //Body
  ellipse(570, 220, 27, 27);
  ellipse(570, 240, 22, 50);
  fill(0);  //Face
  ellipse(570, 220, 20, 15);
  if(H == 8 & M == 30 && S%2){  //If it is 8:30 am the alarm starts (her eyes blink green) for Hiro to wake up and go to class
    fill(62, 173, 50); //Green Eyes
  }else{
    fill(80, 159, 214); //Blue Eyes
  }
  ellipse(566, 220, 5, 8);
  ellipse(574, 220, 5, 8);
  //WALL-E's Eve

  //The clock
  fill(50);
  rect(550, 260, 70, 40, 10);
  rect(560, 257, 10, 5, 5);
  rect(572, 257, 10, 5, 5);
  fill(0);
  rect(565, 265, 50, 30, 5);
  //The clock

  if(S % 4){  //Blink Blink
    fill(198, 0, 0);

    if (H > 12 || H == 0) { //Converts it to twelve hour clock
      H = abs(H - 12)}
    if(M < 10){
      text(H + " : 0" + M, 575, 285); //If the time is before 10 minutes it still shows two digits "01, 02, etc"
    }
    text(H + " : " + M, 575, 285) //Shows time on the clock
  }else{
    fill(0);
  }
}

function chair(){
  //CHAIR
  fill(50); //Close To Black
  rect(200, 250, 140, 120, 10);
  rect(260, 370, 20, 20);
  rect(200, 380, 140, 20);
  rect(265, 390, 10, 40);
  rect(260, 420, 20, 40);
  rect(210, 460, 120, 15);
  ellipse(215, 480, 20);
  ellipse(325, 480, 20);
  ellipse(270, 480, 20);
  //CHAIR
}

function baymaxhead(){
  fill(255);  //Baymax's Head
  ellipse(50, 280, 50, 40);
  ellipse(43, 282, 40, 35);
  ellipse(57, 282, 40, 35);

  fill(0);  //Baymax's Eyes
  ellipse(40, 280, 10, 10);
  ellipse(60, 280, 10, 10);
  rect(40, 278, 20, 2);

  fill(122, 81, 53); //Brown
  rect(10, 290, 80, 10);  //Plate-like thing
}

function tangledportrait(){
  fill(163, 107, 160); //Purple
  rect(300, 170, 60, 25);
  fill(45, 47, 85); //Dark Blue
  rect(300, 195, 60, 20);
  fill(248, 172, 147); //Peach

  image(tangled, 313, 175, tangled.width/8, tangled.height/8);

  if(mouseIsPressed & mouseX >= 300 * 0.5 && mouseX <= 360 * 0.5 && mouseY >= 170 * 0.5 && mouseY <= 215 * 0.5){ //When you click on the photo (scaled) an image will pop on the computer screen
    fill(163, 107, 160); //Purple
    rect(90, 155, 180, 70);

    //Clouds
    for(var i = 0; i < 5; i++){
      fill(111, 90, 155);
      ellipse(118 + 300 * i/12, 225, 50, 30);
    }
    //Clouds

    //Castle
    fill(34, 35, 59); //Dark Blue

    rect(160, 200, 60, 40);
    rect(150, 215, 80, 40);
    rect(180, 175, 10, 60);
    rect(190, 190, 15, 60);
    rect(170, 190, 5, 60);
    //Castle

    fill(45, 47, 85); //Dark Blue
    rect(90, 225, 180, 35);
    for(var i = 0; i < 5; i++){ //The Lanterns
      var x = 5;
      var y = 10;
      fill(248, 172, 147); //Peach
      rect((110) + i/7 * 240, 170 + i, x, y);
      rect((170) + i/10 * 150, 195 - i/2, x/1.3, y/1.3);
      rect((170) + i/4 * 30, 210 + i/2, x/2, y/2);
      fill(254, 218, 181); //Light Yellow
      rect((110) + i/7 * 240, 178 + i, x, y/4);
      rect((170) + i/10 * 150, 201 - i/2, x/1.3, y/6);
      rect((170) + i/4 * 30, 214 + i/2, x/2, y/9);
    }

    //Boat
    fill(248, 228, 196);  //Yellow (Rapunzel's Hair)
    rect(200, 237, 2, 5);
    rect(205, 237, 2, 5);
    fill(99, 48, 46); //Brown
    rect(200, 240, 20, 5);
    triangle(200, 240, 195, 240, 200, 245);
    triangle(220, 240, 225, 240, 220, 245);
    //Boat
  }

}

function liloandstitchportrait() {
  fill(253, 244, 172); //Yellow
  rect(380, 160, 60, 35);
  fill(117, 178, 225); //Blue
  rect(380, 191, 60, 10);
  fill(93, 158, 198); //Blue
  rect(380, 193, 60, 10);
  fill(82, 143, 181); //Blue
  rect(380, 195, 60, 10);

  push();
  beginShape();
  fill(251, 178, 81); //Orange
  curveVertex(400, 200);
  curveVertex(380, 205);
  curveVertex(405, 190);
  curveVertex(440, 205);
  curveVertex(490, 240);
  endShape();
  pop();
  image(liloandstitchsurfboard, 415, 163, liloandstitchsurfboard.width/7, liloandstitchsurfboard.height/9);
  fill(251, 178, 81); //Orange
  rect(415, 198, 10, 5);


  if(mouseIsPressed & mouseX >= 380 * 0.5 && mouseX <= 440 * 0.5 && mouseY >= 160 * 0.5 && mouseY <= 205 * 0.5){ //When you click on the photo (scaled) an image will pop on the computer screen
    fill(253, 244, 172); //Yellow
    rect(90, 155, 180, 80)

    //Ocean
    fill(117, 178, 225); //Blue
    rect(90, 240, 180, 20);
    fill(93, 158, 198); //Blue
    rect(90, 235, 180, 5);
    fill(82, 143, 181); //Blue
    rect(90, 230, 180, 5);
    //Ocean

    //Sand
    push();
    beginShape();
    fill(251, 178, 81); //Orange
    curveVertex(100, 200);
    curveVertex(90, 260);
    curveVertex(170, 220);
    curveVertex(270, 260);
    curveVertex(300, 230);
    endShape();
    pop();
    //Sand

    image(liloandstitch, 145, 192, liloandstitch.width/5, liloandstitch.height/5);
  }
}

function bighero6portrait(){
  fill(208, 35, 39); //Red
  rect(370, 220, 50, 50);
  fill(255);
  rect(375, 225, 40, 15);
  rect(375, 245, 40, 5);
  rect(375, 255, 40, 15);

  if(mouseIsPressed & mouseX >= 370 * 0.5 && mouseX <= 420 * 0.5 && mouseY >= 220 * 0.5 && mouseY <= 270 * 0.5){ //When you click on the photo (scaled) an image will pop on the computer screen
    fill(208, 35, 39); //Red
    rect(90, 155, 180, 105);
    image(bighero6, 105, 172, bighero6.width/1.5, bighero6.height/1.5)
  }
}

I really wanted to code Sanfranstokyo but I realized there weren’t enough reference pictures that I could find so I referenced a picture of Sanfranstokyo and made it an outside window view from Hiro’s bedroom. I drew out Hiro’s bedroom on illustrator first before coding it (which was actually really fun to do even though it was tedious). Some things that I tried to implement into my code include:
1. Clouds that move through the sky and change color, with the sky, according to the time of day. You can tell what the time of the day is by looking at Hiro’s clock near his bed.
2. Eve from WALL-E (on top of the clock)’s eyes actually change color when it is 8:30am as if to indicate that it’s time for Hiro to wake up and go to school
3. After 7pm stars start to appear in the sky because it’s night time
4. After 7pm the buildings also start to get darker to match with the darkening sky. The windows light up and they also flash every couple seconds (differing per building) and the signs in japanese flash as if to attract people to come in

I also decided to add some easter eggs in the code. Spoilers of the easter eggs below 🙂 Read w/ caution
1. When it’s 11pm you can see a “Second star to the right” that’s blue and larger than the other stars: Peter Pan
2. Two drawings on the wall are from two disney movies that I also really love


Night Time + Second Star to the Right


It’s getting darker, Evening Time


Morning!


Reference photos and drawing of Hiro’s room

Zipped file of actual sized canvas with working clouds

cduong_SectionD_FinalProject

Yoonseo1- Final project

TURN UP YOUR SOUND!

My exploration on the final project was on illustrating the beauty of space and exploration. I tried on how to create 3D experience in p5.js. I have successfully developed beginning exploration scene with
interaction between characters, but I could not get to the next part, which character is visible and exploring the foreign planet. I am still very satisfied with what I came up with.
Some sound effects are from free-sound effects and music from No Man’s Sky.

Press ENTER to continue on dialogues and Scripts.
Animation below will tell you control, but in case you miss it.
W to raise speed and S to lower speed.
Enjoy!

Beginning of Space Exploration

//Name: Yoonseo(Dave) Choi
//Andrew ID: yoonseo1
//15-104: final project
//Space exploration 
stars = [];
stars.length = 2500;
var speed = 1; var ox;var oy;var nx;var ny;var Sspeed;var galaxy;var planet1;
var ship; var dTodestine; // distance left to planet
var arrive = false; var dialoague = true; var main = true; var control = true;
var imgplanet;
var pr = 0; // planet raito
var startup = false; var Onwarp = false; var durWarp = false; var off = false;
var counter = 0; //counter for the string output
var warp; var end; var engine; var starthyp;
var fcount=0; // custom frame count
var tposx; var barh; var slow;
var tposy; var tboxx; var tboxy; var dstart = true; 
var BGM;
var currentText; 
var num = 0; // for calling dialogues
var diagarray = []; //array for dialogues
var diagCount = 13; // total dialogues
var monologues = false; // monologue boolean
var comm = true;  // communication boolean
var portrait = []; // portrait animation calling
var monoarray = []; // monologue array 
var monotext; // current monologues
var monocount = 4; // total monologues
var nnum = 0; //calling monologues
var crystal; // crystal image
var aimOn = false;  // boolean for aim setting
var crossline; //cross line image
var da = 0; // darkness level for the black out later. 
var distort1;
var distort2;
var distort3;
var distort4;
function preload(){
		//Sound calling

		BGM = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/BGM.mp3"); //back ground music
		warp = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/warp.wav"); //warping sound
		end = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/End.wav"); // end of warping sound
		starthyp = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/hyps-2.wav"); // beginig of warping
		engine = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/engine-start-2.wav"); // engine sound 
		IamHere = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/Arrived.mp3"); // when arrived to planet
		Digital = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/Typing.wav"); // typing sound
		Intro = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/Intro-theme.wav"); // intro main sounds
		Message = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/message-receive.wav"); // coordinate exchange
		slow = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/engine-back.wav"); // deceleration 

		crossline = loadImage("https://i.imgur.com/hbpD5CT.png"); 
		crystal = loadImage("https://i.imgur.com/sm0Kud3.png");
		galaxy = loadImage("https://i.imgur.com/59T2snK.jpg");
		ship = loadImage("https://i.imgur.com/vIFxRkT.png");
		warpped = loadImage("https://i.imgur.com/gjcQn7H.jpg"); // altered space image
		imgplanet = loadImage("https://i.imgur.com/Je1AEea.png"); // planet image

		// portrait animation call
		distort1 = loadImage("https://i.imgur.com/gXjhgGZ.png");
		distort2 = loadImage("https://i.imgur.com/rx5N8wr.png");
		distort3 = loadImage("https://i.imgur.com/OGEuf4o.png");
		distort4 = loadImage("https://i.imgur.com/oi7RWEZ.png");
		
		portrait.push(distort1);
		portrait.push(distort2);
		portrait.push(distort3);
		portrait.push(distort4);

		//calling the dialogues and monologues. 
		
		for (var i =0; i < 13; i ++){ // calling dialogues 
		diagarray.push(loadStrings('https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/info'+ i + '.txt'));
		}
		for (var m = 0; m < 4; m ++){ // calling monologues
		monoarray.push(loadStrings('https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/mono'+ m +'.txt'));
		}
}
function setup() {
  createCanvas(480, 480);
  background(0);
  Intro.loop();	//BGM play
  tposx = width-200; // setting position for the text
  tposy = 100;
  tboxx = 200;
  tboxy = height/2;
  currentText = diagarray[0];
 	for (var i = 0; i < stars.length; i++){ //array for creating stars
 		stars[i] = new makeStar();
 	
 	}
}
function makeStar() {
	var star = { 	x : random(-width,width),  // random position in X
					y : random(-height,height), // random position in Y
					z : random(width), // for acceleration of stars
					pz: this.z,
					R : random(100,255), //colors
					G : random(150,200),
					B : random(150,255),
					update: starupdate,
					Display: starmake

				}
				return star;
}
function approach(x,y,x2,y2){ // displaying planet

	image(imgplanet,x,y,x2,y2)
}
function UD(spe){ // displaying speed meter
	textAlign(CENTER);
	textSize(10);
	stroke(0,255,0);
	text("Speed Meter",width-40,height/2+60);

	noFill();
	stroke(0,255,0)
	rect(width-50,height/2+50.5,25,-51)
	fill(255,0,0);
	noStroke();
	rect(width-49.5,height/2+52,25,spe);
	noFill();
}
function starmake(){ // creating starts
		
		fill(this.R,this.G,this.B,aplh); //fill with colors
		noStroke(); 
		var sx = map (this.x/this.z,0,1,0,width); // x movement of stars 
		var sy = map(this.y/this.z,0,1,0,height); // y movement of stars 
		var r = map (this.z,0,width,10,0); // raidus change so it gets large as user get closer
		var aplh = map (this.z,0,width,10,700) // alpha level 
		if (Sspeed < 34){ // while it is not warping
		ellipse(sx,sy,r,r); //creating visible stars
		fill(255,255,255);
		ellipse(sx,sy,r/2,r/2)
	}
	else if (Sspeed >= 34){ // if in state of warpping
			var px = map (this.x/this.pz,0,1,0,width); // get the x 
			var py = map(this.y/this.pz,0,1,0,height); // get the y 
			this.pz =this.z; // update z 
			stroke(255)
			line(px,py,sx,sy); //create line from previous stars to current creating lines
		}
	
}
function starupdate(){
	this.z = this.z -Sspeed; // movement of the stars based on the speed of the ship.
	if (this.z < 1){ // if it is out set new position to it. 
		this.z = width; 
		this.x = random(-width,width);
		this.y = random(-height,height);
		this.pz = this.z;
	}
}
function keyReleased(){ // preventing constant sound creation. 
	// W = 87, S =83
	if (keyCode === 87 & Onwarp == false && dialoague == false){
		engine.stop(); // engine stop when up arrow is disabled
	}
	if (keyCode === 83 & Onwarp == false && dialoague == false){
		slow.stop(); // decelerating sound stop 
	}
}
function keyPressed(){
	if (keyCode === 87  & Onwarp == false && dialoague == false){
		engine.loop(); // when up is pressed, engine creates sound
	}
	if (keyCode === 83 & Onwarp == false && dialoague == false){
		slow.loop(); // when down is pressed slow 
	}
	if (keyCode === 13 & dialoague == true && frameCount/5 > 60){ // for dialogues when enter is pressed. 
		
		diagCount -= 1; // keep track of dialogues
		num += 1; // move on to next line
		currentText = str(diagarray[num]); // current text set to next line  
		counter = 0; // counter set to 0 every time enter is pressed 
		if(num > 13){ // preventing error lines appearing 
			num = 13; 
		}
		
		if (num< 13){ // prevent playing sound at the end of line
		Digital.play();
		}
		if (num == 6){ // alarams the coordinate message
			Message.play();
		}

	}
	if ( keyCode === 13 & monologues == true){ // when enter pressed on monologues part
		monocount -= 1; // track of monologues 
		nnum += 1; //move on to the next lien 
		counter = 0; // reset counter 
		monotext = str(monoarray[nnum]); // set current monologues 
		if (nnum == 3){ // when at the last line play 
			Digital.play();
		}
		if (nnum > 3){ // prevent error in monologues message 
			
			nnum = 3
			monologues = false; 
		}
		if (nnum < 3){ // prevent playing sound at the end of line 
			Digital.play();
		}
	}
}
function draw() {
	noCursor(); // no cursor 
	rectMode(CORNER); // rectangle set corner to default 
	barh = -map(Sspeed,0,27,0,40); // tracking the speed of the ship for speed meter
	engine.setVolume(0.3); // set volumes of sounds 
		starthyp.setVolume(0.1);
		warp.setVolume(0.3);
		end.setVolume(0.3);
		slow.setVolume(0.3);
		 var  f = frameCount % 3; //getting the timing for the frame.  
	if (main == true){ // in main screen. 
		textAlign(CENTER); // Set the text in the center
		background(0); // back ground to black 
		fill(255); // fill the text with white for lcontrast 
		textSize(50); // set the size of the test to be 50. 
		text("Start Exploration?", width/2, height/2 -100); // starting sentence 
			if (frameCount % 30 == 1 || frameCount % 30 == 2 || frameCount % 10 == 3){
			fill(0);
			}
			textSize(20);
			text("Press S to Start",width/2, height/2 + 100); // display blinking effect of the satar
				if(keyCode == 83){
					Intro.stop();
					BGM.loop(); // let the BGM loop at the main screen., 
				main = false;
				}
	}
	if (arrive == false & main == false){ // when the main screen is off and moved to the actual game

		fcount += 1; // custom frame count
		background(0); //set back ground to black 
		image(galaxy,0,0); // display the galaxy image
 
    	if ( dialoague == false){ // i f dialogues to false 
    		background(0); // set back ground to black 
			image(galaxy,0,0); //show space image 
    	}
		if (keyIsDown(87) & control == true && dialoague == false){
		
			speed += 1; //raise speed
			}
		if (keyIsDown(83) & control == true && dialoague == false){
			speed -= 1; // reduce speed 
			}
			Sspeed = map(speed,0,100,0.5,20); // factor of speed 
		if (Sspeed < 0){
			Sspeed = 1;// not letting speed to go under 1
			}
		if (Sspeed > 40){
			Sspeed = 40; // maximum speed limit 
			}
		
		if (Sspeed >= 27){ 
			Sspeed += 8 // let speed to go up automatic for warp. 
			}
		if (Sspeed >= 27 & Onwarp == false){ // set warp true and play warpping sounds
			Onwarp = true; // this is to prevent sounds to play constantly
			engine.stop();
			starthyp.play();
			}
		if (Sspeed >= 34 & durWarp == false){ // when the speed is greater than 34, warp initiates
			warp.loop();
			durWarp = true; //allows star to be lines for faster movment visual
			}
		if (Sspeed >= 34){
			image(warpped,0,0); //back ground image alters 
			aimOn = false; 
			control = false; //not allowing user input 
		}
	push();
	translate(width/2,height/2);
for(var i = 0; i < stars.length; i ++){ // putting stars into display 
		stars[i].update();
		stars[i].Display();
	}
	
	pop();
	if (aimOn == true){
	//image(crossline,mouseX-crossline.width/2,mouseY-crossline.height/2);	
	}
	UD(barh); //display HUD 

	if (Sspeed <34){ // allow sHUD to be displayed before warp
		UD(barh)
	image(ship,0,0);
	}else if (Sspeed >= 34){
		UD(barh)
	dTodestine -= 10;
	image(ship,random(-5,0),random(-5,0)); //during warp ship shakes 
	}
	if ( fcount/5 > 60 & dstart == true){ // begining scene start
			Digital.play();
			dstart = false; 
		}
		if ( fcount/5 > 60){ // start of the dialogues
		counter += 1; //start counter for the string output speed
		textSize(20); // set size of text 
		if (num == 9){ // no more animation at dialogue 9 
			comm = false;
		}
  		if (num > 1 & comm == true){  // show animation 
  			image(portrait[f],350,0,100,100);
  		}
  		if (dialoague == true){ // when the dialogue is true 
  		for(var t =0; t < currentText.length; t ++){
  			fill(255,0,0);
  			if (num == 1 || num == 3||num == 5 || num == 7 || num == 9){ // protagonist commentary
  				fill(255,255,0);
  				textAlign(CENTER);
  				text(
    				currentText[t].substring(0, counter),
    				70,height/2+50,350,100);
    	
  			}else{
  			textAlign(LEFT);
  			text(
    				currentText[t].substring(0, counter), //info/ N's commentary
    				tposx,tposy,tboxx,tboxy);
  				}
 
  			}
    	if (diagCount ==0){// if reached to end of dialogue
    		counter =0; //reset 
    		dialoague = false; 
    		dTodestine = 7000; //set distance to the planet
    		diagCount = -1; // not letting any overlap of numbers
    		aimOn = true;
    		
    		}
    	}
    }
	}
	if (dTodestine < 800 & off == false){ //one time running codes 
		monologues = true;
		BGM.stop();
		IamHere.play(); //arriving sound
		warp.stop();
		Digital.play();
		end.play(); // end warp sound
		monotext = monoarray[0];
		off = true;
	}
	if (dTodestine < 800){
		pr += 0.25
		ox = width/2-pr;
		oy = height/2-pr;
		nx = pr*2
		ny = pr*2;
		approach(ox,oy,nx,ny) // set the planet to get large as it approaches
		control = false; //no control input
		speed -= 3; // slow down after warp 
	if (Sspeed <34){
		UD(barh);
		image(ship,0,0);
		dTodestine -= 0.75; // set distance reduce amount 
	}
	}

	if ( dTodestine < 800 & monologues == true){ //monologues display 
			textSize(20);
				for(var t =0; t < monotext.length; t ++){
  				fill(255,0,0);
  			
  				fill(255,255,0);
  				textAlign(CENTER);
  				text(
    			monotext[t].substring(0, counter),
    			70,height/2+50,350,100);
  				}
			}
	

	if (dTodestine < 100){ //if get close to planet
		da += 10;
		fill(0,da); //black out start  
		rect(0,0,width,height)

	}
	if (dTodestine  < 0){
		arrive = true; //arrive to true
		dTodestine = 0;  
		speed = 0;
		monologues = false;
		clear(); //reset the scene
		background(0);
		fill(255);
		textSize(40);
		textAlign(CENTER);
		text("...To Be Continued....",width/2,height/2); // message for continued 
}
}