akluk-final-project

For my project I mainly based my project on whack a mole game combined with the pokemon that everyone loves, Diglet. The game lasts for 60 sec and during time the player would want to hit as many diglets as possible. Once the game ends the user can press r to restart the game. Hope you enjoy the game!

Screenshot of the game

sketch

//Alvin Luk
//Section A
//akluk@andrew.cmu.edu
//Final Project

//initialize constants and variables
//number of rows of diglets in the canvas
var rows = 3;

//body height of the diglet
var diglet_h = 30;
//number of diglets in the game
var num_diglets = 11;
//array to contain the diglet objects
var diglets = [];
//temporary dummie variable to help push all the diglets 
var temp_diglet;
//number of diglets the player has hit in a single run of game/score
var num_hit;
//number of 0.5 sec passed elapsed
var time_elapsed = 0;
//duration of game 60sec
var game_time = 120;
//whether the game has ended
var ended = 0;
//hammer mode to determine if hammer is down or up
var mode; 
//start position for even rows
var startx1 = 60;
//start position for odd row
var startx2 = 120;
//spacing with each diglet
var spacing = 120;
//height spacing
var dy = 90;


function setup() {
    createCanvas(480, 360);
    //creates the diglets in the right positions
    // and pushes it into the array of diglets
    for (var i = 0; i < rows; i++) {
        //even rows
        if ((i % 2) == 0){
            for (var j = startx1; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
        //odd rows
        else {
            for (var j = startx2; j < width; j += spacing){
                temp_diglet = new diglet(j,dy*(i+1));
                diglets.push(temp_diglet);
            }
        }
    }
    //initialize score for player
    num_hit = 0;
    //update the diglets ever half second to determine if they pop up
    //and update timer every 0.5 sec
    setInterval(function(){
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].update();
        }
        time_elapsed += 1;
    }, 500);
}

function draw() {
    background(40,180,40);
    noStroke();
    //change the display of the hammer 
    if (mouseIsPressed){
        mode = 1;
    }
    else {
        mode = 0;
    }

    //end the game when the timer has ended 
    if (time_elapsed >= game_time){
        ended = 1;
    }
    //if game has not ended, draw the holes for the diglets in the correct location
    if (ended == 0){
        for (var i = 0; i < rows; i++) {
            //odd rows
            if ((i % 2) == 0){
                for (var j = 60; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
            //even rows
            else {
                for (var j = 120; j < width; j += 120){
                    drawHole(j,dy*(i+1));
                }
            }
        }
        //draw every diglet in the array of diglets
        for (var index = 0; index < num_diglets; index ++){
            diglets[index].draw();
        }   
        //draw hammer in passive position     
        if (mode == 0) {
            fill(130,82,1);
            rect(mouseX-5,mouseY-25,10,50);
            fill(120);
            rect(mouseX-25,mouseY-35, 50,20);
        }
        //draw hammer in active position
        else {
            fill(130,82,1);
            rect(mouseX,mouseY-5,50,10);
            fill(120);
            rect(mouseX-10,mouseY-25, 20,50);
        }

        //display score and time left for the game
        fill(255);
        textSize(15);
        text("Score : " + num_hit, 400,340);
        text("Time Left : " + (game_time-time_elapsed)/2,5,340);
    }
    //game over screen
    else {
        fill(0);
        rect(0,0,width,height);
        fill(255);
        text("Game Over!", width/2 - width/10, height/2);
        text("Final Score : " + num_hit, width/2 - width/10,height/2 + height/15);
        text("Press R to restart", width/2 - width/10, height/2 + 2*height/15);
    }

}

//draw the hole sorry for much random numbers to make it look natural
function drawHole(x,y){
    fill(0);
    ellipse(x,y,80,40);
    fill(103,104,76);
    ellipse(x-40,y,22,12);
    ellipse(x+40,y,22,12);
    fill(90,77,65);
    ellipse(x-32,y+8,20,12);
    ellipse(x+28,y+8,24,14);
    fill(119,120,119);
    ellipse(x-22,y+13,20,12);
    ellipse(x+12,y+16,24,15);
    fill(100,100,100);
    ellipse(x-4,y+18,28,15);   
}


//object of diglet 
function diglet(x,y,duration){
    //base variables
    this.x = x;
    this.y = y;
    this.duration = duration;
    //draw the diglet, with eyes and body
    this.draw = function() {
        if (this.duration > 0) {
            //brown of diglet
            fill(181,147,119);
            rect(this.x-diglet_h/2,this.y-diglet_h,diglet_h,diglet_h);
            ellipse(this.x,this.y-diglet_h,diglet_h,diglet_h);
            
            fill(0);
            ellipse(this.x-diglet_h/6,this.y-diglet_h,3,6);
            ellipse(this.x+diglet_h/6,this.y-diglet_h,3,6);
            fill(255);
            ellipse(this.x-diglet_h/6,this.y-diglet_h-2,1,1);
            ellipse(this.x+diglet_h/6,this.y-diglet_h-2,1,1);
            //nose color
            fill(239,187,210);
            ellipse(this.x,this.y-diglet_h+6,diglet_h/3,5);
        }
    }
    //update whether the diglet appears
    this.update = function(){
        if (this.duration > 0){
            this.duration = this.duration - 0.5;
        }
        else {
            var temp_ratio = random(0,1);
            if (temp_ratio < 0.15){
                this.duration = random([1,2,3,4]);
            }
        }
    }
    //check if user clicked the diglet
    this.inDiglet = function(click_x,click_y){
        if (((click_x > this.x-diglet_h/2) & (click_x < this.x-diglet_h/2) && (click_y > this.y - diglet_h) && (click_y < this.y)) || (dist(click_x,click_y,this.x,this.y-diglet_h) < diglet_h)){
            if (this.duration > 0){
                this.duration = 0;
                num_hit += 1; 
            }   
        }
    }
}

//check  if when the mouse is pressed if it hits any diglet
function mousePressed() {
    for (var i = 0; i < num_diglets; i++){
        diglets[i].inDiglet(mouseX,mouseY);
    }
}

//when the game is over and you press r reset the game
function keyTyped(){
    if ((key === 'r') & (ended == 1)){
        ended = 0;
        time_elapsed = 0;
        ended = 0;
        num_hit = 0;
    }
}

jiaxinw-Final Project

Interactive Music Media Installation

This is a project using Kinect connecting with a website which was developed by P5.js.  Therefore, this project cannot be run on WordPress. We recorded the video for our project and hope it can be a good demonstration of the whole concept.

For this project, Nayeon and I worked together to create a new media installation in which people can interact with music by hitting virtual buttons to generate sounds and visual effects. People can follow the music from the background and have fun with moving their body to play music.

I learned a lot and a lot and a lot from this final project and I am so proud that it finally has been done. For this project, I was responsible for the Kinect part,  which included making sure the connection between Kinect and the website (or we can say the Javascript files) work well and also create User Interface (the virtual buttons, particle effects, and sound effects) for the website.  So, the biggest challenge for me at the beginning was figuring out how to connect Kinect and Javascript. I did a lot of research and finally decided to use the Node-Kinect2 library to achieve what I needed.

(Information about Node-Kinect library: https://github.com/wouterverweirder/kinect2)

I followed the instructions of the library, installed all the modules and packages that I needed (which took me a long time to figure out how to properly install the node.js and all kinds of modules. 😉 ). After it, I looked into the sample files carefully, analyzed the logic inside to figure out how I can access the data of Kinect skeleton. I figured out, for using this library to access data, I needed to set up a local server and point it to my local index, uploading my resources and files to the server through the node.js. At last, I need to use the command prompt to open the js file by using node.js. Whoo… to be honest, it was not easy to figure out the whole process clearly, but once I understood the logic behind it, the whole thing went more fluently.

The next step I did was designing how the interface looks like. After communication with Nayeon, we decided to create a project with a Neon art style.  I created a mood board for myself to figured out the feelings of the visual part.

my mood board

I also looked into a very inspiring and amazing project which is The V Motion Project and decided to do a circling interface for people to play with.

(For more information about V Motion Project: https://vimeo.com/45417241)

The presentation of V Motion Project

I created 6 virtual buttons on the canvas, and when people hit any of them, a particle effect will be generated along with a sound effect. By standing in front of the Kinect, people can move their hands to touch the buttons and create their own music and visual effects.

One more thing I have learned from this project is about how to access JS file outside Node.js through Node.js. The trick is you need to follow a very strict syntax to get your directory of the file and upload your resources to it.

you need to follow a special syntax to access your file

Anyway, it is so excited that I have finished this project with Nayeon! We definitely went through some difficulties and I guess this is why I feel very fulfilled when I finished creating everything! Here are some screenshots of the project!  Hope you Enjoy 🙂

Capture of final project
Capture of final project
Capture of final project

Finally here is the source code (a zip file) we created, please feel free to check it. I was responsible for the Kinect and interface (jiaxin.js) part.

Final project(Jiaxin_Nayeon)

Instruction for opening our project:

  1. Go to https://github.com/wouterverweirder/kinect2   download the Kinect node.js library.
  2. Follow the instruction to install node.js
  3. Connect your Kinect to your PC and make sure it works 🙂
  4. Extract the project zip file, and open your Command Prompt (for windows), go to the directory that you put our project folder. (use “cd + the directory “)
  5. And then use node.js to open the kinect.js file. (simply type “node kinect”)
  6. Open a browser and go to the local server : http://localhost:8000
  7. Stand in front of your Kinect, and have fun with our project!

Final Project, odh

 

odhPFinal

//Owen D Haft
//15-104 Section D
//odh@andrew.cmu.edu
//Final Project

var wristJointX = 240; //X Position of the Wrist
var wristJointY = 240; //Y Position of the Wrist
var fingerJointRadius = 5; //Radius of the hand joints
var petalSize = 9; //Radius of the Petals
var petalHeight = 0; //Position of the Petals
//List of Translations
var Texts = ["Life is Beautiful", "La Vida es Bella",
                "La Vie est Belle", "La Vita è Bella", "A Vida é Bela", 
                "Das Leben ist Wunderschoen", "Życie jest Piękne",
                "החיים יפים", "لحياة جميلة", "삶은 아름답다", "生活是美好的", 
                "人生は素晴らしい", "ज़िन्दगी गुलज़ार है", "ชีวิตช่างสวยงาม",
                "Maisha ni Mazuri", "Жизнь прекрасна", "Vita Pulchrum est"];
var THeight = 30; //Height of the Text
var TColor = 0; //Fill color of the Text

function setup() {
    createCanvas(360, 360);
    background(141, 222, 255);
}

function draw() {
    stroke(0);
    strokeWeight(1);

//Draws the Shapes of the Skeleton Hand
    //Forearm
    line(239, 241, 479, 481);
    line(241, 239, 481, 479);
    
    //Carpels
    line(wristJointX, wristJointY, 210, 210);
    line(wristJointX, wristJointY, 126, 234);
    line(wristJointX, wristJointY, 124, 236);
    line(wristJointX, wristJointY, 122, 238);
    line(wristJointX, wristJointY, 120, 240);

    //Metacarpels
    line(210, 210, 185, 195);
    line(126, 234, 110, 210);
    line(124, 236, 95, 215);
    line(122, 238, 85, 225);
    line(122, 240, 80, 235);

    line(110, 210, 135, 190);
    line(95, 215, 80, 185);
    line(85, 225, 65, 200);
    line(80, 235, 55, 220);

    //Styles the joints
    fill(0);
    strokeWeight(1);
    stroke(250);
    
    //Elbow
    ellipse()

    //Wrist Joint
    ellipse(wristJointX, wristJointY, 10);
    
    //Finger Joints
    ellipse(126, 234, fingerJointRadius);
    ellipse(124, 236, fingerJointRadius);
    ellipse(122, 238, fingerJointRadius);
    ellipse(120, 240, fingerJointRadius);

    ellipse(80, 235, fingerJointRadius);
    ellipse(85, 225, fingerJointRadius);
    ellipse(95, 215, fingerJointRadius);
    ellipse(110, 210, fingerJointRadius);
    ellipse(210, 210, fingerJointRadius);

    ellipse(55, 220, fingerJointRadius);
    ellipse(65, 200, fingerJointRadius);
    ellipse(80, 185, fingerJointRadius);
    ellipse(135, 190, fingerJointRadius);
    ellipse(185, 195, fingerJointRadius);

    //Fingertips
    strokeWeight(0); //Removes the outline on the fingertips

    triangle(178, 193, 184, 190, 165, 185);
    triangle(141, 188, 134, 183, 165, 185);
    triangle(81, 179, 75, 181, 86, 155);
    triangle(65, 194, 60, 197, 62, 172);
    triangle(52, 214, 50, 220, 40, 202);

//Flower
    //Stem
    noFill();
    strokeWeight(2); //Gives the Stem thickness
    stroke(84, 157, 26); //Stem Color
    
    curve(226, 154, 173, 156, 168, 195, 226, 191);

    //Pod
    fill(99, 47, 24);

    ellipse(177, 153, 13);

    //Petals
    fill(255, 232, 19);
    strokeWeight(0)
    stroke(0);

    //The Main text
    push();
    fill(TColor);
    textSize(30);
    text(Texts[0], 7, THeight); // Prints only "Life is Beautiful" from Texts 
    pop();

    push();
    translate(177, 153);
    for (var i = 0; i < 6; i++) { //Creates the petals of the flower
        rotate(PI/3);
        ellipse(10, petalHeight, petalSize);
            
        if (mouseIsPressed) { //Exapnds and moves the petals to
            petalHeight -= 1; //encompass the Canvas in Yellow
            petalSize += 1;   //adding a new "background" color

            if (petalSize > 500) { //Limits the growth of
                petalHeight = 500; //the petals and prompts 
                petalSize = 500;   //the Texts to be printed

                //Prints Texts with offset heights
                for (var j = 1; j < 18; j++) {
                    push();
                    translate(-180, -180);
                    fill(TColor + 255); //changes text color to white
                    textSize(16); //changes text size
                    text(Texts[j], random(10, 150), (THeight*2/3)*j+56);
                    pop(); 
                };
            };
        };
    };
    pop();

    //Draws pink petals once the yellow petals grow into the background
    if (mouseIsPressed) {
        translate(177, 153);
        for (var i = 0; i < 6; i++) {
            fill(219, 164, 164);
            rotate(PI/3);
            ellipse(10, 0, 9);
        };
    };
}

I chose to create an interactive art piece for my final project. The work features a skeleton-like hand gently holding a small flower with the words above, “Life is Beautiful”. As the viewer holds down the mouse, the petals grow and replace the background color, as new petals appear in their place. Once the growing petals completely eclipse the background, the phrase “life is beautiful” appears randomly on the screen in different languages.

I was inspired by a sketch I made earlier in the year (below) and the beautiful juxtaposition of the subjects.

amui1-Final-Project

amui1-final

//Allison Mui
//15-104 Section A
//amui1@andrew.cmu.edu
//Final Project

//variables for image
var monty = [];
var flyingMonty;
var swimmingMonty;
var evilOcty;
var bubble;
var bubbleX = [];
var bubbleY = [];
var punchMonty = [];
var monster;
var monstFall = [];
var homeMonty;

//variables for mouse movement
var targetX;
var targetY;

//variables for different states
var begin = true;
var home = false;
var world1 = false;
var world2 = false;
var world3 = false;
var over = false;

//variables for begin state
var playX;
var playY;

//variables for fire world1
var fires = [];
var fireCounter = 0;
var waterArray = [];

//variables for sea world
var octyY = 10;
var octySpeed = 4;
var inkSpeed;
var inkX = 280;
var inks = [];
var inkCounter = 0;

//variables for fight world
var fightmontyX = 130;
var fightmontyY = 350;
var fighttargetX = 130;
var fighttargetY = 350;
var monstX = 300;
var monstY = 280;
var monstSpeed = 5;
var level =  1;


//loads images
function preload() {
  //image for home monty
  homeMonty = loadImage("https://i.imgur.com/LudAnMM.png");
  //images for walking monty
  var montyfile = [];
  montyfile[0] = "https://i.imgur.com/jF4qiIL.png";
  montyfile[1] = "https://i.imgur.com/Q2Y2NMk.png";
  montyfile[2] = "https://i.imgur.com/Bhzuxet.png";
  montyfile[3] = "https://i.imgur.com/NXGRLMb.png";
  //loads monty
  for (var i = 0; i < 4; i++) {
    monty[i] = loadImage(montyfile[i]);
  }
  //image for fire world
  flyingMonty = loadImage("https://i.imgur.com/uogV1b7.png");
  //images for sea world
  bubble = loadImage("https://i.imgur.com/ZzkbRgi.png")
  swimmingMonty = loadImage("https://i.imgur.com/FwBvECT.png");
  evilOcty = loadImage("https://i.imgur.com/gYrnKp2.png");
  //images for fight world
  kickmonty = loadImage("https://i.imgur.com/ZpfaJlx.png")
  punchMonty[0] = loadImage("https://i.imgur.com/jF4qiIL.png");
  punchMonty[1] = loadImage("https://i.imgur.com/Q2Y2NMk.png");
  punchMonty[2] = loadImage("https://i.imgur.com/wCvUx2R.png");
  punchMonty[3] = loadImage("https://i.imgur.com/NXGRLMb.png");
  monster = loadImage("https://i.imgur.com/E0lKepM.png")
  monstFall[0] = loadImage("https://i.imgur.com/E0lKepM.png")
  monstFall[1] = loadImage("https://i.imgur.com/FX8hPMk.png");
}


function setup() {
    createCanvas(480,450);
    imageMode(CENTER);
    frameRate(4);
    // Initialize the character and target positions
    characterX = width/2;
    characterY = height/2;
    targetX = characterX;
    targetY = characterY;
    //fire world1
    dif = 0;
    for (var i = 0; i < 6; i++) {
        fires[i] = makeFire(width/4 + dif);
        dif += random(50,80);
    }
    //randomizing location for bubbles for sea world
    for (b = 0; b < 15; b++) {
      bubbleX.push(random(width));
      bubbleY.push(random(height));
    }
    //load bubble picture
    bubble.loadPixels();
    //loads home monty picture
    homeMonty.loadPixels();

}

function draw(){
    if (begin == true) {
      drawBegin();
    }
    if (home == true) {
      drawHome();
    }
    //calculates distance from monty to the world 1 icon
    var distWorld1 = dist(characterX,characterY,width/4,height/4);
    //if close enough, change the booleans to show a new screen
    if (distWorld1 < 10) {
      home = false;
      world1 = true;
      drawworld1();
    }
    //calulate distance from monty to world 2 icon
    var distWorld2 = dist(characterX,characterY,width/2+width/4,height/4);
    //if close enough, change booleans and show new screen
    if (distWorld2 < 10) {
      home = false;
      world2 = true;
      drawworld2();
    }
    //calculates distance from monty to world 3 icon
    var distWorld3 = dist(characterX,characterY,width/2,height/2+width/4+20);
    //if close enough, change booleans and show new screen
    if (distWorld3 < 10) {
      home = false;
      world3 = true;
      drawworld3();
    }
    //if too many points were lost (parameters in specific world), change screen
    if (over == true) {
      gameOver();
    }
}

function drawBegin() {
    background(0);
    image(homeMonty,width/2,height/2-20);
    textSize(24);
    fill(255);
    text("Lonnie's World",160,80);
    textSize(16);
    text("Lonnie travels from fire to sea, avoiding danger",80,110);
    textSize(20);
    text("Press play to begin", 160,350);
    var dPlay = dist(playX,playY,160,350);
    print(dPlay);
    if (dPlay < 80) {
      begin = false;
      home = true;
    }
}

function drawHome() {
    textSize(14);
    background(0);
    frameRate(4);
    //world 1
    strokeWeight(0);
    fill(229,115,115);
    ellipse(width/4,height/4,50,50);
    fill(240,171,171);
    ellipse(width/4,height/4,35,35);
    fill(255);
    text("Flames of Fury", width/4-40,height/4-35);
    //world 2
    fill(109,181,255);
    ellipse(width/2+width/4,height/4,50,50);
    fill(167,211,255);
    ellipse(width/2+width/4,height/4,35,35);
    fill(255);
    text("Waves of Fear", width/2+width/4-35,height/4-35);
    //fight world
    fill(255,253,41);
    ellipse(width/2,height/2+width/4+20,50,50);
    fill(255,254,127);
    ellipse(width/2,height/2+width/4+20,35,35);
    fill(255);
    text("Fight Club",width/2-25,height/2+width/4-15);
    //move monty according to where user clicks
    var dx = targetX - characterX;
    var dy = targetY - characterY;
    //cycles through all image files to walk
    image(monty[frameCount%4], characterX, characterY);
    characterX = characterX + dx/10;
    characterY = characterY + dy/10;
}

function mousePressed() {
    //sets new target for play button
    playX = mouseX;
    playY = mouseY;
    //set boundaries for user's mouse
    targetX = mouseX;
    targetY = mouseY;
    targetX = constrain(mouseX,0,width-50);
    targetY = constrain(mouseY,0,height-50);
    //sets new target for the fight world
    fighttargetX = mouseX;
    fighttargetY = mouseY;
}

function drawworld1() {
    background(0);
    frameRate(12);
    //sets the monster's position
    var flyingmontyX = mouseX;
    var flyingmontyY = mouseY;
    //constrains the monsters position to not move past the middle and canvase
    var flyingmontyY = constrain(flyingmontyY,40,height-90);
    var flyingmontyX = constrain(flyingmontyX,45,height/2);
    //displays image
    image(flyingMonty,flyingmontyX,flyingmontyY);
    strokeWeight(0);
    //displays fire
    showFire();
    //instructions
    noFill();
    stroke(255);
    strokeWeight(1);
    rect(0,height-50,width,50);
    strokeWeight(0);
    fill(255);
    text("Avoid the fire or you'll get burned!", 10,height-28);
    text("Points: " + fireCounter, width-70,height-30);
    //if mouse over "go home" returns to the home screen
    text("Go Home", width-70, height-10);
    var distHome = dist(mouseX,mouseY,width-70,height-10);
    if (distHome < 15) {
      home = true;
    }
    //ends game if points too low
    if (fireCounter < -100) {
      over = true;
    }
}

function drawworld2() {
    frameRate(15);
    background(175,246,249);
    //draw bubbles
    for (bub = 0; bub < 15; bub++) {
      image(bubble,bubbleX[bub],bubbleY[bub]);
    }
    //changes speed by a random amount(speedif) as time goes on
    if (frameCount % 60 == 0) {
      speeddif = random(1,3);
      octySpeed = octySpeed + speeddif;
    }
    //make new ink blots at different times
    if (frameCount % 60 == 0) {
      inks.push(makeInk(inkX,octyY));
    }
    //displays ink
    showInk();
    //monty moves with mouse
    swimX = mouseX;
    swimY = mouseY;
    //sets boundaries so monty doesn't go off the page
    var swimY = constrain(swimY,30,height-90);
    var swimX = constrain(swimX,0,width/4);
    //display monty
    image(swimmingMonty,swimX,swimY);
    //displays the octopus monster
    image(evilOcty,width-120,octyY);
    //moves octy
    octyY += octySpeed;
    //sets actions so octy doesn't move off the page
    if (octyY > height-90) {
      octySpeed = -octySpeed;
    }
    if (octyY < 10) {
      octySpeed = -octySpeed;
    }
    //instructions
    rectMode(CORNER);
    fill(40,40,57);
    stroke(255);
    strokeWeight(1);
    rect(0,height-50,width,50);
    strokeWeight(0);
    fill(255);
    text("The evil octopus is squirting ink!", 10,height-28);
    text("Avoid the head of the ink!", 10, height-10);
    text("Points: " + inkCounter, width-70,height-30);
    text("Go Home", width-70, height-10);
    //calculates where mouse is, if over home button, draw home state
    var distHome = dist(mouseX,mouseY,width-65,height-10);
    if (distHome < 15) {
      home = true;
    }
    //only go through this only if inks array is populated
    //add points if monster successfully avoids the ink
    if (inks.length > 0) {
      //if monster hits the ink, deduct 5 points
      if ((swimX > inks[0].x-100 & swimX < inks[0].x+100) &&
          (swimY > inks[0].y-5 && swimY < inks[0].y+30)) {
        inkCounter -= 1;
      }
      //remove ink blots after it moves off the page
      if (inks[0].x < 0) {
        inkCounter += 1;
        inks.shift(1);
      }
    }
    //end game if too many points lost
    if (inkCounter < -100) {
      over = true;
    }
}

function drawworld3() {
    background(47,100,145);
    //draw boxing design
    drawBoxingRing();
    //calculates distance between monster fighting and monty
    var dFight = dist(fightmontyX,fightmontyY,monstX,monstY);
    //if monty runs into monster, then game is over
    if (dFight < 90) {
      over = true;
    }
    //fight monster
    //punches monster if monty is close enough
    if(dFight < 98 & keyIsDown(80)) {
      //if monster is punched, monster "falls down"
      //cycles through image array
      image(monstFall[frameCount%2],monstX,monstY);
    }
    //if monster is not punched, move monster from right to left
    else {
      image(monster,monstX,monstY);
      monstX -= monstSpeed;
      //sets boundary for the monster
      if (monstX < 150) {
        monstSpeed = -monstSpeed;
      }
      if (monstX > 300) {
        monstSpeed = -monstSpeed;
      }
    }
    //image of the fighting monty
    //calculates distance for movement of monty
    var dx = fighttargetX - fightmontyX;
    var dy = fighttargetY - fightmontyY;
    //constrains the boundary of monty
    fightmontyX = constrain(fightmontyX,30,300);
    fightmontyY = constrain(fightmontyY,height-150,height-80);
    //moves monty
    fightmontyX = fightmontyX + dx/10;
    fightmontyY = fightmontyY + dy/10;
    //if user doesn't call monty to move, monty is still
    if (fightmontyX == fighttargetX & fightmontyY == fighttargetY) {
      image(monty[0], fightmontyX, fightmontyY);
    }
    //if monty is punching, restrict image so punch monty will match
    if (keyIsDown(80) & (frameCount%4 == 0 || (frameCount%4 == 2))) {
      image(punchMonty[2],fightmontyX,fightmontyY);
    }
    //if user calls monty to move, monty moves and cycles through all image files
    if (fightmontyX != fighttargetX || fightmontyY != fighttargetY) {
      image(monty[frameCount%4],fightmontyX,fightmontyY);
    }
    //instructions
    fill(35,75,109);
    stroke(255);
    strokeWeight(1);
    rect(0,height-50,width,50);
    strokeWeight(0);
    fill(255);
    textSize(13);
    text("Battle the hungry bear!", 10,height-28);
    text("Click to move and hold 'p' to punch!", 10, height-10);
    text("Level: " + level, width-70,height-30);
    text("Go Home", width-70, height-10);
    //calculates distance from user's mouse to the go home button
    var distHome = dist(mouseX,mouseY,width-65,height-10);
    //if user's mouse is on the go home button, draw home state
    if (distHome < 15) {
      home = true;
    }
    //increases level after some time passed
    if (frameCount%2000 == 0) {
      level += 1;
    }
}

function drawBoxingRing() {
    //background design to make look like boxing setting
    strokeWeight(0);
    fill(35,79,109);
    rect(0,height-120,width,100);
    stroke(35,79,109);
    strokeWeight(15);
    line(10,height-50,width/4-20,130);
    line(250,height-50,width/2+80,130);
    line(250,height-50,width/4+30,130);
    line(480,height-50,380,130);
    strokeWeight(0);
    fill(35,75,109);
    rect(0,0,width,130);
    //lights
    stroke(255);
    strokeWeight(5);
    line(150,145,160,145);
    line(155,140,155,150);
    line(300,170,310,170);
    line(305,165,305,175);
    //banner
    fill(189,57,51);
    strokeWeight(5);
    rect(width-180,30,140,40);
    strokeWeight(0);
    fill(255);
    textSize(15);
    text("Fight! Train! Win!",width-165,55);
    //boxing ring
    fill(255);
    strokeWeight(0);
    triangle(20,height-50,100,height-160,100,height-50);
    rect(100,height-160,280,150);
    triangle(380,height-50,380,height-160,460,height-50);
    fill(189,57,51);
    triangle(30,height-50,100,height-150,100,height-50);
    rect(100,height-150,280,150);
    triangle(380,height-50,380,height-150,450,height-50);
    //boxing horizontal lines - "strings around the ring"
    stroke(255);
    strokeWeight(3);
    //left
    line(30,height-140,125,height-248);
    line(30,height-120,125,height-230);
    line(30,height-100,125,height-210);
    //mid
    line(125,height-230,360,height-230);
    line(125,height-210,360,height-210);
    line(125,height-190,360,height-190);
    //right
    line(360,height-248,450,height-140);
    line(360,height-230,450,height-120);
    line(360,height-210,450,height-100);
    //boxing columns
    fill(142,43,38);
    strokeWeight(0);
    rect(20,height-200,40,200,5);
    rect(100,height-250,40,100,5);
    rect(340,height-250,40,100,5);
    rect(height-30,height-200,40,200,5);
}

function gameOver() {
    background(0);
    textSize(50);
    text("Game Over",15,height/2);
    textSize(14);
    text("Please refresh to start over :)",20,height/2+50);
}

function showInk() {
    //moves and draws inks in the ink array
    for (var i = 0; i < inks.length; i++) {
      inks[i].draw();
      inks[i].move();
    }
}

function moveInk() {
    this.x -= this.speed;
}

function drawInk() {
    //draw ink
    strokeWeight(0);
    fill(40,40,57);
    rectMode(CENTER);
    rect(this.x,this.y,200,20,10);
    rect(this.x,this.y+25,180,20,10);
}

function makeInk(x,y) {
    m = {x:x,
         y:y,
         speed: random(5,8),
         draw: drawInk,
         move: moveInk}
    return m;
}

function showFire() {
    //go through fire Array
    for (var fiyah = 0; fiyah < fires.length; fiyah++) {
      //alternate fire design
      //if even number, show fire coming from the bottom of the canvas
      if (fiyah % 2 == 0) {
        fires[fiyah].drawup();
        fires[fiyah].move();
      }
      //if odd number, show fire coming from the top
      if (fiyah % 2 != 0) {
        fires[fiyah].drawdown();
        fires[fiyah].move();
      }
    }
}

function moveFire() {
    //sets the monster's position
    var flyingmontyX = mouseX;
    var flyingmontyY = mouseY;
    //constrains the monsters position to not move past the middle and canvase
    var flyingmontyY = constrain(flyingmontyY,40,height-90);
    var flyingmontyX = constrain(flyingmontyX,45,height/2);
    //moves fire
    this.x -= this.speed;
    //if fire moves off page, points go up
    if (this.x < 0-30) {
      this.x = width;
      fireCounter += 1;
    }
    //calculates distance from monty to fire
    if (flyingmontyY < height/2) {
      var dFire = dist(flyingmontyX,flyingmontyY,this.x,this.h);
    }
    if (flyingmontyY > height/2) {
      var dFire = dist(flyingmontyX,flyingmontyY,this.x,height-this.h);
    }
    //if monty too close to fire, deduct points
    if (dFire < 20) {
      fireCounter -= 5;
    }
}

//if fire is coming from the floor
function drawupFire(){
    //draws redish flame
    fill(216,82,42);
    triangle(this.x-20,height-50,this.x-5-random(1,10),height-50-(this.h+60)-random(1,50),
              this.x+50+random(1,10),height-50);
    triangle(this.x,height-50,this.x+10+random(-1,5),height-50-(this.h+60)-random(1,60),
              this.x+50+random(1,10),height-50);
    triangle(this.x,height-50,this.x+20+random(1,10),height-50-(this.h+60)-random(1,50),
              this.x+55+random(1,10),height-50);
    //draws orange flame
    fill(221,144,44);
    triangle(this.x-15,height-50,this.x-5-random(1,10),height-50-(this.h+40)-random(1,40),
              this.x+40+random(1,10),height-50);
    triangle(this.x,height-50,this.x+10+random(-1,5),height-50-(this.h+40)-random(1,50),
              this.x+40+random(1,10),height-50);
    triangle(this.x,height-50,this.x+20+random(1,10),height-50-(this.h+40)-random(1,40),
              this.x+45+random(1,10),height-50);
    //draws dark yellow flame
    fill(233,219,47);
    triangle(this.x-10,height-50,this.x-5-random(1,10),height-50-(this.h+20)-random(1,30),
              this.x+30+random(1,10),height-50);
    triangle(this.x,height-50,this.x+10+random(-1,5),height-50-(this.h+20)-random(1,40),
              this.x+30+random(1,10),height-50);
    triangle(this.x,height-50,this.x+20+random(1,10),height-50-(this.h+20)-random(1,30),
              this.x+35+random(1,10),height-50);
    //draws light yellow frame
    fill(255,250,163);
    triangle(this.x-5,height-50,this.x-5-random(1,10),height-50-this.h-random(1,20),
              this.x+20+random(1,10),height-50);
    triangle(this.x,height-50,this.x+10+random(-1,5),height-50-this.h-random(1,30),
              this.x+20+random(1,10),height-50);
    triangle(this.x,height-50,this.x+20+random(1,10),height-50-this.h-random(1,20),
              this.x+25+random(1,10),height-50);
}

//if fire coming from ceiling
function drawdownFire(){
    //draws redish flame
    fill(216,82,42);
    triangle(this.x-20,0,this.x-5-random(1,10),0+(this.h+60)-random(1,50),
              this.x+50+random(1,10),0);
    triangle(this.x,0,this.x+10+random(-1,5),0+(this.h+60)-random(1,60),
              this.x+50+random(1,10),0);
    triangle(this.x,0,this.x+20+random(1,10),0+(this.h+60)-random(1,50),
              this.x+55+random(1,10),0);
    //draws orange flame
    fill(221,144,44);
    triangle(this.x-15,0,this.x-5-random(1,10),0+(this.h+40)-random(1,40),
              this.x+40+random(1,10),0);
    triangle(this.x,0,this.x+10+random(-1,5),0+(this.h+40)-random(1,50),
              this.x+40+random(1,10),0);
    triangle(this.x,0,this.x+20+random(1,10),0+(this.h+40)-random(1,40),
              this.x+45+random(1,10),0);
    //draws dark yellow flame
    fill(233,219,47);
    triangle(this.x-10,0,this.x-5-random(1,10),0+(this.h+20)-random(1,30),
              this.x+30+random(1,10),0);
    triangle(this.x,0,this.x+10+random(-1,5),0+(this.h+20)-random(1,40),
              this.x+30+random(1,10),0);
    triangle(this.x,0,this.x+20+random(1,10),0+(this.h+20)-random(1,30),
              this.x+35+random(1,10),0);
    //draws light yellow frame
    fill(255,250,163);
    triangle(this.x-5,0,this.x-5-random(1,10),0+this.h-random(1,20),
              this.x+20+random(1,10),0);
    triangle(this.x,0,this.x+10+random(-1,5),0+this.h-random(1,30),
              this.x+20+random(1,10),0);
    triangle(this.x,0,this.x+20+random(1,10),0+this.h-random(1,20),
              this.x+25+random(1,10),0);
}

function makeFire(x){
    f = {x:x,
         h: random(20,130),
         speed: random(1,8),
         drawup: drawupFire,
         drawdown: drawdownFire,
         move: moveFire}

    return f;
}

Features

  • Click to move or “hit” buttons such as play or go home
  • In different worlds, character moves along with the user’s mouse movements to avoid obstacles.
  • In the fight world, user can click p for added interaction.

Reflection

I enjoyed this project a lot because it was so challenging, but fun and rewarding. I really felt like I put what I learned in this class to test. Trying to incorporate something I learned from each week, I saw the vast power creative computing has. The most enjoyable part was seeing how far this project has come: from storyboard to now. The most challenging part was trying to fix, adjust, and adapt my game when a programming difficulty came up (which was often). In addition, I had a lot of fun creating the visuals in this project and then adding motion to them. All in all, I am happy with my project’s final outcome.

Caption: Above is my first storyboard of my game. As you can see, my idea has changed quite a bit from beginning to end. However, my main concept of moving a character through different worlds or states remained the same.

Caption: Above are the 3 worlds my character travels through.

nahyunk1 & yugyeonl Final



How to open up and run the file:

  1. download and unzip the files below.
  2. nahyunk1-yugyeonl-final project
  3. songs
  4. extract “sound1”, “sound2”, and “sound3” music files from the songs folder and put them into the “assets” folder inside the final project folder.
  5. turn on terminal or node and run local server.
  6. access the sketch.js inside the final project folder.
  7. play and enjoy the songs by entering either 1, 2, 3 on your keyboard.

The project file was too large so we had to upload the songs separately in another folder along with the zip file of our code. Our project was based on the idea of generating animation with the kiwi bird and creating its walkthrough with the incorporation of music affecting the background of the landscape. There are three parts to the scenes: pressing 1 on your keyboard will affect your current scene to an urban landscape. Similarly, when either 2 or 3 is pressed, different scenes and music replace the current scene with different parts of the landscape responding to the beat, frequency, and the amplitude of the music assigned. The parts of the landscapes were drawn with the incorporation of the FFT(); function and the p5.Amplitude(); function which analyzes the frequency and the volume of the music when it is played. Some of the interesting factors that our animation consisted was the sun beam which would draw itself in an ellipse in a form of measured frequency and the stars and the moon which brightens and glistens depending on the beat of the music played at night. Throughout, we put a lot of effort learning and incorporating the p5.sound materials, creating a variety of landscapes with music chosen according to the mood of our scenes, and generally coding different functions and figuring out ways for our code to understand the switching of the scenes and the play of different music files.

**scene 2 consists of a song that is relatively louder than the other scenes that contain music files. We’ve put code for the sound of the song to be reduced, but the song still plays comparatively loud. Please be careful with the volume of your headphones.

 

sketch

var kiwi;             
var kiwiX = 200;        //kiwi locationX
var kiwiY = 310;        //kiwi locationY
var tree = [];          //array of trees
var treeAssets = [];
var shell = [];         //array of shells
var shellAssets = [];
var coin = [];          //array of coins
var coinAssets = [];
var gem = [];           //array of gems
var gemAssets = [];
var buildings = [];     //array of buildings
var ocean = [];         //array of mountain
var mountain = [];      //array of ocean
var stars = [];         //array of stars
var clouds = [];        //array of clouds
var sound1;
var sound2;
var sound3;
var amplitude; 
var volArray = [];      //array that stores volume
var timeState = "morning";    //determines initial state of time

function preload() {
    sound1 = loadSound("assets/sound1.mp3");
    sound2 = loadSound("assets/sound2.mp3");
    sound3 = loadSound("assets/sound3.mp4");
    var treeLinks = ["assets/palmtree0.png", "assets/palmtree1.png", 
                    "assets/palmtree2.png", "assets/palmtree3.png"];
    //load tree images
    for (var t = 0; t < treeLinks.length; t++) {
        treeAssets[t] = loadImage(treeLinks[t]);
    }
    //load shell images
    for (var i = 0; i < 1; i++){
        shellAssets[i] = loadImage("assets/shell.png");
    }
    //load coin images
    for (var i = 0; i < 1; i++){
        coinAssets[i] = loadImage("assets/coin.png");
    }
    //load gem images
    for (var i = 0; i < 1; i++){
        gemAssets[i] = loadImage("assets/gem.png");
    }
}

function setup() {
    createCanvas(1000, 700);
    imageMode(CENTER);
    //load amplitude
    amplitude = new p5.Amplitude();
    //load fft 
    fft = new p5.FFT();
    sound1.setVolume(1);
    sound2.setVolume(0.00000001);
    sound3.setVolume(1);
    //create initial set of trees
    for (var i = 0; i < 4; i ++) {
        var treeX = random(width);
        tree[i] = makeTrees(treeX);
    }
    //create initial set of shells
    for (var i = 0; i < 5; i ++) {
        var shellX = random(360, width);
        shell[i] = makeShells(shellX);
    }
    //create initial set of coins
    for (var i = 0; i < 5; i ++) {
        var coinX = random(360, width);
        coin[i] = makeCoins(coinX);
    }
    //create initial set of gems
    for (var i = 0; i < 5; i ++) {
        var gemX = random(360, width);
        gem[i] = makeGems(gemX);
    }
    //create initial set of buildings
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    //create initial set of clouds
    for (var i = 0; i < 10; i++) {
      var cloudX = random(width);
      var cloudY = random(height/2);
      clouds[i] = makeClouds(cloudX, cloudY);
    }
    //create kiwi animation
    createKiwi(kiwiX, kiwiY);  
    //ocean
    makeOcean(height - 220, 30, 0.00005, 0.0005, color(197, 227, 234));
    makeOcean(height - 180, 80, 0.00005, 0.001, color(225, 211, 185));  
    //mountain
    makeMountain(height - 400, 200, 0.00005, 0.0025, color(15));
    makeMountain(height - 350, 300, 0.00015, 0.006, color(0));
}

function draw() {
    if (timeState == "morning") {
        morning();
        if (sound1.isPlaying() == false){
          sound1.play();
        }  else if (sound2.isPlaying() ==  true){
          sound2.stop();
        }  else if (sound3.isPlaying() ==  true){
          sound3.stop();
        }
    } if (timeState == "afternoon") {
        afternoon();
        if (sound2.isPlaying() == false){
          sound2.play();
        }
        else if (sound1.isPlaying() ==  true){
          sound1.stop();
        } else if (sound3.isPlaying() ==  true){
          sound3.stop();
        }
    } if (timeState == "night") {
        night();
        if (sound3.isPlaying() == false){
          sound3.play();
        }  if (sound1.isPlaying() == true){
          sound1.stop();
        }  else if (sound2.isPlaying() ==  true){
          sound2.stop();
        }
    } 
}

function keyPressed() {
    if (key == '1') {
        timeState = "morning";
    } if (key == '2') {
        timeState = "afternoon";
    } else if (key == '3') {
        timeState = "night";
    }
}

function morning() {
    //gradient background color
    var from = color(125, 133, 216);
    var to = color(220, 224, 251);
    setGradient(0, from, to, 3.5 * height / 5);
    //lines in the background showing frequency
    skyFreq(0, 125);
    //sun
    makeSun(width / 4 - 100, 550, 236, 191, 113, 300);
    //ground
    noStroke();
    fill(96, 91, 103);
    rect(0, 3.5 * height / 5 - 10, width, 0.5 * height / 5);
    fill(127, 109, 123);
    rect(0, 4 * height / 5 - 10, width, height / 4);
    //clouds
    updateAndDisplayClouds();
    addClouds();
    //buildings
    updateAndDisplayBuildings();
    addBuildings();
    //kiwi
    drawKiwi();
    //coins
    updateAndDisplayCoins();
    addCoins();
}

function afternoon() {
    //gradient background color
    var from = color(20, 140, 172);
    var to = color(209, 255, 249);
    setGradient(0, from, to, 3.5 * height / 5);
    //lines in the background showing frequency
    skyFreq(100, 48);
    //ocean & sand
    noStroke();
    moveOcean();
    //sun
    makeSun(3 * width / 4, 90, 243, 229, 202, 150);  
    //sun outline based on frequency
    sunFreq();     
    //trees
    updateAndDisplayTrees();
    addTrees(); 
    //kiwi
    drawKiwi();     
    //shells
    updateAndDisplayShells();
    addShells();
}

function night() {
    //gradient background color
    var from = color(25, 0, 51);
    var to = color(51, 0, 102);
    setGradient(0, from, to, 3.5 * height / 5);
    //stars
    updateAndDisplayStars();
    removeStars();
    addStars();
    drawStars();
    //moon
    makeMoon();
    //mountain
    strokeWeight(random(0.2, 0.4));
    stroke(random(0,255), random(0,255), random(0,255));
    moveMountain();
    //ground
    noStroke();
    fill(18, 13, 17);
    rect(0, 3.5 * height / 5, width, 1.5 * height / 5);
    //kiwi
    drawKiwi();
    //gems
    updateAndDisplayGems();
    addGems();
    //sound
}

function setGradient (y, from, to, length) {
    //top to bottom gradient (background)
    for (var i = y; i <= length; i++) {
        var inter = map(i, y, width, 0, 1);
        var c = lerpColor(from, to, inter);
        stroke(c);
        strokeWeight(2);
        line(0, i, width, i);
    }
}

function makeSun(sunX, sunY, r, g, b, diam) {
    noStroke();
    //glowing gradient sunlight
    for (var i = 0; i < 30; i++) {
        var value = random(7, 8);
        var transparency = 100 - value * i;
        fill(r + 2 * i / 3, g + 7 * i / 3, b + i, transparency);
        ellipse(sunX, sunY, diam + 20 * i, diam + 20 * i);
    }
    //sun
    fill(r, g, b, 100);
    ellipse(sunX, sunY, diam, diam);
}

function sunFreq() {    //sun outline
    angleMode(DEGREES);
    //analyze level of the amplitude
    var vol = amplitude.getLevel();
    //array that pushes the volume in the array
    volArray.push(vol);
    stroke(255);
    strokeWeight(.5);
    noFill();
    push();
    translate(width - 240, 90);
    scale(2.5);
    //shape that represent the range of the frequency
    beginShape();
    for (var i = 0; i < 360; i ++){
        var r = map(volArray[i], 0, 1, 10, 100);
        var x = r * cos(i);
        var y = r * sin(i);
        vertex(x ,y);
    }
    endShape();
    pop();
    //360 because the reperesentation draws in an ellipse
    if (volArray.length > 360){
        volArray.splice(0, 1);
    }  
}

function skyFreq(offset, spacingX) {    //background lines
    var w = width / spacingX;
    //anaylze the fft
    var spectrum = fft.analyze();
    push();
    translate(0, offset);
    beginShape();
    //draws the frequency level as lines behind the ocean
    for (var i = 0; i < spectrum.length; i++){
        var angle = map(i, 0, spectrum.length, 0, 360);
        var amp = spectrum[i];
        var r = map(amp, 0, 256, 40, 200);
        var y = map(amp, 0, 256, height, 0);
        stroke(255);
        strokeWeight(0.5);
        line(i * w, height, i * w, y);
    }
    endShape();
    pop();
}

function cityFreq() {

}

function makeMoon() {
    //size of moonlight depends on the amplitude
    for (var c = 0; c < 30; c++){
        var level = amplitude.getLevel();
        noStroke();
        fill(217, 154, 100, (10 - c) * level * 50);
        ellipse(850, 150, 90 + (10 * c) + level, 90 + (10 * c) +  level);
        stroke(255, 223, 181);
        fill(255, 223, 181);
        ellipse(850, 150, 100, 100);
        fill(252, 240, 224);
        ellipse(858, 150, 85, 85);
    }
}

function drawKiwi() {  //create kiwi   
    push();
    translate(kiwiX, kiwiY);
    scale(0.6, 0.6);
    drawSprites();
    pop();
}

function createKiwi(x, y) {  //create sprite at a random position
    kiwi = createSprite(x, y);
    kiwi.addAnimation("assets/kiwi0.png","assets/kiwi1.png",
                  "assets/kiwi2.png","assets/kiwi3.png","assets/kiwi4.png","assets/kiwi5.png","assets/kiwi6.png",
                  "assets/kiwi7.png","assets/kiwi8.png","assets/kiwi9.png","assets/kiwi10.png",
                  "assets/kiwi11.png","assets/kiwi12.png","assets/kiwi13.png","assets/kiwi14.png");
}

function makeOcean(landscapeY, landscapeR, landscapeS, landscapeD, landscapeC) {
    var landscape = {ly: landscapeY,     //locationY
                range: landscapeR,      //range of how far landscape goes up
                speed: landscapeS,      //speed of the landscape
                detail: landscapeD,     //detail (how round/sharp)
                color: landscapeC,      //color of the landscape
                draw: drawLandscape}
    ocean.push(landscape);
}

function makeMountain(landscapeY, landscapeR, landscapeS, landscapeD, landscapeC) {
    var landscape = {ly: landscapeY,     //locationY
                range: landscapeR,      //range of how far landscape goes up
                speed: landscapeS,      //speed of the landscape
                detail: landscapeD,     //detail (how round/sharp)
                color: landscapeC,      //color of the landscape
                draw: drawLandscape}
    mountain.push(landscape);
}

function drawLandscape() {  //generating landscape from code provided
    fill(this.color);
    beginShape();
    vertex(0, height);
    for (var i = 0; i < width; i++) {
        var t = (i * this.detail) + (millis() * this.speed);
        var y = map(noise(t), 0, 1, this.ly - this.range / 2, this.ly + this.range / 2);
        vertex(i, y); 
    }
    vertex(width, height);
    endShape(CLOSE);
}

function moveOcean() { //move the landscape
    for (var i = 0; i < ocean.length; i++) 
        ocean[i].draw();
}

function moveMountain() { //move the landscape
    for (var i = 0; i < mountain.length; i++) 
        mountain[i].draw();
}

//palm trees
function updateAndDisplayTrees() {
    //keeps the trees moving along the x-axis
    for (var i = 0; i < tree.length; i++) {
        tree[i].moveTree();
        tree[i].drawTree();
   }
}

function drawTrees() { //draws the trees
    image(treeAssets[this.nFloor], this.x + 200, this.y - 100);
}

function moveTrees() { //move the trees
    this.x -= this.speed;
}

function addTrees() { //places in more trees into the array
    var newTreesProbability = 0.0015;
    if (random(0, 1) < newTreesProbability) {
        tree.push(makeTrees(width));
   }
}

function makeTrees(originX) {
    var palmtrees = {
        x: originX,
        y: random(400, 420),
        speed: 0.55,
        nFloor: floor(random(0, 3)),
        moveTree: moveTrees,
        drawTree: drawTrees}
    return palmtrees;
}

//shells
function updateAndDisplayShells() {
    //keeps the shells moving along the x-axis
    for (var i = 0; i < shell.length; i++) {
        shell[i].moveShell();
        shell[i].drawShell();
    }
}

function drawShells() { //draws the shells
    push();
    translate(this.x + 100, this.y);
    scale(0.25, 0.25);
    image(shellAssets[0], 0, 0);
    pop();
}

function moveShells() { //move the shells
    this.x -= this.speed;
}

function addShells() {  //places in more trees into the array
    var newTreesProbability = 0.0035; 
    if (random(0, 1) < newTreesProbability) {
        shell.push(makeShells(width));
    }
}

function makeShells(shellX) {
    var shells = {
        x: shellX,
        y: 610,
        speed: 1,
        moveShell: moveShells,
        drawShell: drawShells}
    return shells;
}

//budilings
function updateAndDisplayBuildings(){
    //keeps the buildings moving along the x-axis
    for (var i = 0; i < buildings.length; i++) {
        buildings[i].move();
        buildings[i].display();
    }
}

function addBuildings() {  //places in more buildings into the array
    var newBuilding = 0.006; 
    if (random(0,1) < newBuilding) {
        buildings.push(makeBuilding(width));
    }
}

function moveBuildings() { //move the buildings
    this.x -= this.speed;
}

function drawBuildings() { //draws the buildings
    var floorHeight = 45;
    var bHeight = this.nFloors * floorHeight; 
    push();
    noStroke();
    fill(this.buildingC); 
    translate(this.x, height - 180);
    rect(0, -bHeight, this.breadth, bHeight);
    for (var y = 0; y < this.nFloors; y++) {
        for (var x = 0; x < 6; x++){
            noStroke();
            fill(255, 221, random(100, 150));
            rect(x * (this.breadth / 7) + 10, -25 - (y * floorHeight), this.breadth / 12, 20);
        }
    }
    pop();
}

function makeBuilding(buildingX) {
    var building = {x: buildingX,
        breadth: random(100, 125),
        speed: 0.55,
        buildingC: color(random(150, 225), random(100, 175), random(100, 175)),
        nFloors: round(random(4, 10)),
        move: moveBuildings,
        display: drawBuildings}
    return building;
}

//coins
function updateAndDisplayCoins() {
    //keeps the coins moving along the x-axis
    for (var i = 0; i < coin.length; i++) {
        coin[i].moveCoins();
        coin[i].drawCoins();
    }
}

function drawCoins() { //draws the coins
    push();
    translate(this.x + 100, this.y);
    scale(0.3, 0.3);
    image(coinAssets[0], 0, 0);
    pop();
}

function moveCoins() { //move the coins
    this.x -= this.speed;
}

function addCoins() { //places in more coins into the array
    var newTreesProbability = 0.0035;
    if (random(0, 1) < newTreesProbability) {
        coin.push(makeCoins(width));
   }
}

function makeCoins(coinX) {
    var coins = {
        x: coinX,
        y: 610,
        speed: 1,
        moveCoins: moveCoins,
        drawCoins: drawCoins}
    return coins;
}

//gems
function updateAndDisplayGems() {
    //keeps the gems moving along the x-axis
    for (var i = 0; i < gem.length; i++) {
        gem[i].moveGems();
        gem[i].drawGems();
    }
}

function drawGems() { //draws the gems
    push();
    translate(this.x + 100, this.y);
    scale(0.3, 0.3);
    image(gemAssets[0], 0, 0);
    pop();
}

function moveGems() { //move the gems
    this.x -= this.speed;
}

function addGems() { //places in more gems into the array
    var newTreesProbability = 0.0035;
    if (random(0, 1) < newTreesProbability) {
        gem.push(makeGems(width));
   }
}

function makeGems(gemX) {
    var gems = {
        x: gemX,
        y: 610,
        speed: 1,
        moveGems: moveGems,
        drawGems: drawGems}
    return gems;
}

//stars
function updateAndDisplayStars() {
    //keeps the stars moving along the x-axis
    for (var i = 0; i < stars.length; i++){
        stars[i].move();
        stars[i].display();
    }
}

function removeStars() {  //remove stars out of canvas
    var starsKeep = [];
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x + stars[i].breadth > 0) {
            starsKeep.push(stars[i]);
            }
    }
    stars = starsKeep; //remaining stars
}

function addStars() { //places in more trees into the array
    var newTreesProbability = 0.0075;
    if (random(0,1) < newTreesProbability) {
        stars.push(makeStars(width));
    }
}

function moveStars() {  //move the stars
    this.x -= this.speed;
}

function drawStars() { //draws the coins
    strokeWeight(random(0.5, 3));
    stroke(random(0, 255), (0, 255), (0, 255));
    push();
    translate(this.x, 20);
    // the size of the stars depends on the amplitude 
    for (var i = 0; i < stars.length; i++) {
        var level = amplitude.getLevel();
        var size = map(level, 0, 1, 0, 1);
        fill(random(0, size), (0, size), (0, size));
        ellipse(random(10, 3.5 * height / 5), random(10, 3.5 * height / 5), size, size);
    }
    pop();
   }

function makeStars(birthLocationX) {
    var star = {
        x: birthLocationX,
        breadth: 50,
        speed: 1,
        move: moveStars,
        display: drawStars}
    return star;
 }

 //clouds
function updateAndDisplayClouds() {
    //update the clouds' position & draw them
    for (var i = 0; i < clouds.length; i++) {
        clouds[i].move();
        clouds[i].draw();
    }
}

function makeClouds(cloudX, cloudY) {
    var cloud = {x: cloudX,             //locationX of cloud
        y: cloudY,                      //locationY of the cloud
        offsetX: random(30, 100),
        offsetY: random(100, 175),
        breadth: random(300, 400),      //width of the cloud
        speedC: -random(1, 2),          //speed of the cloud
        nFloors: round(random(2, 8)),   //multiplier that determines the height of the cloud
        transparency: random(20, 60),   //transparency of the cloud
        move: moveClouds,
        draw: drawClouds}
    return cloud;
}

function drawClouds() {
    var multiplier = 5; //multiplier that determines the height of the cloud
    var cloudHeight = this.nFloors * multiplier;
    ellipseMode(CENTER);
    noStroke();
    fill(255, this.transparency);
    //cloud height reacts to the amplitude
    var level = amplitude.getLevel();
    push();
    translate(this.x, height / 2 - this.offsetY);
    ellipse(this.breadth/2, -cloudHeight, this.breadth, cloudHeight + 500 * level);
    pop();
    push();
    translate(this.x, height / 2 - this.offsetY - 50);
    ellipse(this.breadth/2 + this.offsetX, -cloudHeight, this.breadth, cloudHeight + 500 * level);
    pop();
}

function moveClouds() {
    //move clouds by updating its x position
    this.x += this.speedC;
}

function addClouds() {
    //new clouds from the right edge of the canvas
    var newCloudsProbability = 0.0075;
    //likliness of new clouds
    if (random(0, 1) < newCloudsProbability) {
        var cloudX = width;
        var cloudY = random(height / 2);
        clouds.push(makeClouds(cloudX, cloudY));
    } 
}

abradbur – Final Project – Section C

sketch


var aSlider;
var frames = [];//stores crow images

function preload(){
  //crow cycle images uploaded to imgur
  var crowCycles = [];
  crowCycles[0] = "https://i.imgur.com/kFSBiWN.png"
  crowCycles[1] = "https://i.imgur.com/WLXwnwq.png"
  crowCycles[2] = "https://i.imgur.com/PGafnLp.png"
  crowCycles[3] = "https://i.imgur.com/kFSBiWN.png"
  crowCycles[4] = "https://i.imgur.com/WLXwnwq.png"
  crowCycles[5] = "https://i.imgur.com/PGafnLp.png"
  crowCycles[6] = "https://i.imgur.com/kFSBiWN.png"
  crowCycles[7] = "https://i.imgur.com/PrhO9gc.png"
  crowCycles[8] = "https://i.imgur.com/wIi9Q1O.png"
  crowCycles[9] = "https://i.imgur.com/ddJaFA1.png"
  crowCycles[10] = "https://i.imgur.com/PrhO9gc.png"
  crowCycles[11] = "https://i.imgur.com/wIi9Q1O.png"
  crowCycles[12] = "https://i.imgur.com/ddJaFA1.png"
  crowCycles[13] = "https://i.imgur.com/PrhO9gc.png"

  //load images into the frames array
  for (i = 0; i < crowCycles.length; i ++){
    frames[i] = loadImage(crowCycles[i]);
  }
}

function setup(){
  createCanvas(480, 480);
  //slider controls the height of the grass
  aSlider = createSlider(0, 400, 400, 0);
  aSlider.position(200, 440);
  frameRate(5);
}

function draw(){

  //the sky will change color depending on the seconds
  var s = second();
  var skyR = map(s, 0, 60, 110, 248);
  var skyG = map(s, 0, 60, 210, 105);
  var skyB = map(s, 0, 60, 230, 32);
  background(skyR, skyG, skyB);

  //create the text box + slider-button area
  var v = aSlider.value()
  fill(255);
  rect(0, 400, 479, 79);
  line(160, 400, 160, 480);
  fill(0);
  textSize(15);
  text("The time flows differently here.", 10, 410, 150, 75);
  
  //button
  fill(206, 78, 58);
  ellipse(440, 440, 70);
  fill(237, 89, 81);
  ellipse(440, 440, 60);
  
  //hills
  fill(167, 118, 59);
  arc(448, 128, 208, 84, PI, TWO_PI);
  fill(211, 164, 98);
  arc(384, 240, 416, 264, PI, TWO_PI);
  arc(72, 240, 416, 200, PI, TWO_PI);

  //farmhouse
  fill(111, 16, 29);
  rect(152, 144, 176, 96);
  fill(38, 0, 2); 
  triangle(152, 144, 240, 64, 328, 144);
  for (var i = 0; i < 4; i ++){
    line(152, 168 + (i * 12), 328, 168 + (i *12));
    i += 1;
  }
  line(152, 144 + (24 *3), 328, 144 + (24 *3));
  rect(230, 200, 20, 40);
  fill(255);
  rect(170, 200, 30, 20);
  rect(278, 200, 30, 20);
  fill(0);

  //first window crack
  beginShape();
  vertex(171, 200);
  vertex(180, 210);
  vertex(200, 210);
  vertex(190, 220);
  vertex(171, 205);
  endShape();

  //second window crack
  beginShape();
  vertex(278, 220);
  vertex(308, 210);
  vertex(298, 210);
  vertex(290, 203);
  vertex(300, 220);
  vertex(284, 200);
  endShape();

  //field
  fill(242, 224, 159);
  rect(0, 240, 480, 160);

  //tree with tire swing
  push();
  translate(448, 100);
  drawBranch(0, 10);
  pop();
  line(430, 51, 430, 80);
  noFill();
  ellipse(430, 85, 10);

  //the well
  fill(138);
  rect(364, 100, 25, 25);
  line(364, 100, 364, 80);
  line(389, 100, 389, 80);
  line(377, 90, 377, 80);
  line(377, 100, 377, 125);
  line(364, 106, 389, 106);
  line(364, 115, 389, 115);
  fill(80, 40, 50);
  beginShape();
  vertex(373, 90);
  vertex(381, 90);
  vertex(379, 95);
  vertex(375, 95);
  vertex(373, 90);
  endShape();
  triangle(364, 80, 377, 75, 389, 80);

  //grave
  fill(138);
  rect(72, 125, 12, 15, 15, 15, 2, 2);
  
  //border trees
  push();
  translate(20, 240);
  drawBranch(0, 15);
  pop();
  push();
  translate(120, 240);
  drawBranch(0, 15);
  pop();
  push();
  translate(70, 245);
  drawBranch(0, 10);
  pop();
  push();
  translate(448, 240);
  drawBranch(0, 10);
  pop();
  push();
  translate(468, 240);
  drawBranch(0, 15);
  pop();
  push();
  translate(418, 245);
  drawBranch(0, 13);
  pop();
  push();
  translate(358, 240);
  drawBranch(0, 15);
  pop();

  //path
  fill(187, 113, 59);
  rect(230, 240, 20, 160);

  //log 
  fill(112, 68, 38);
  rect(50, 246, 40, 27, 10);
  ellipse(70, 250, 40, 10);
  fill(171, 117, 79);
  ellipse(70, 250, 35, 8);
  fill(220, 182, 151);
  ellipse(70, 250, 25, 6);
  fill(112, 68, 38);
  ellipse(70, 250, 10, 3);
  
  //fence
  fill(112, 68, 38);
  rect(0, 260, 30, 140);
  rect(450, 260, 30, 140);
  rect(0, 300, 480, 30);

  //crow animation
  image(frames[frameCount % 13],320, 228, 80, 80);
  
  //overgrowth
  fill(243, 205, 127);
  var val = aSlider.value();
  for (i = 0; i < 160; i ++){
    rect(i * 10, 400, 10, -val);
    i += 1;
  }
  
}

//create trees
function drawBranch(depth, len) {
    line(0, 0, 0, -len);
    push();
    translate(0, -len);
    drawTree(depth + 1, len);
    pop();
}

function drawTree(depth, len) {
    if (depth < 8) {
        rotate(radians(-10));
        drawBranch(depth, len);
        rotate(radians(20));
        drawBranch(depth, len);
    }
}

//if you push the red button
function mouseInsideRedButton(){
  return mouseX > 410 & mouseX < x + 60 && mouseY > 410 && mouseY < 470;
}
function mousePressed(){
  if (mouseInsideRedButton){
    fill(205, 90, 85);
    ellipse(440, 440, 60);
    text("Congrats you found the button.", 310, 350, 150, 75);
  }

}

For my project I ended up focusing on the feeling of finding an abandoned place (in this case an old barn). You push aside the overgrown weeds and use the odds and ends in that location to construct a story of your own. I drew the little crow myself, and the sky changes with every second in a way that I intended to be a little unsettling.

afukuda-FinalProject

sketch

/*  Name | Ai Fukuda 
 * Course Section | C 
 * Email | afukuda@andrew.cmu.edu
 * Project | Final Project
 */ 


// ---- VARIABLES FOR FERRIS WHEEL ---- 
  // ferris wheel color
  var structureColor = 255;  // white
  var supportColor = 90;     // grey 
  
  // speed
  var speed = 160;
  
  // ferris wheel dimensions
  // note: counting circles from most inner to outermost 
  var centerX;        // center of ferris wheel (x-coordinate)
  var centerY;        // center of ferris wheel (y-coordinate)
  var radiusC1;       // radius of circle 1  
  var radiusC2;       // radius of circle 2 
  var radiusC3;       // radius of circle 3 (carrying the passenger cars)
  var radiusC3R;      // radius of circle 3 (passenger cars rotate on it)
  var radiusCar;      // radius of passenger car 
  var radiusBolt;     // radius of bolt on passenger car (detail)
  
  var base;           // base of ferris wheel 
  var baseW;          // width of base of ferris wheel 
  var baseH;          // height of base of ferris wheel 

// ---- END OF VARIABLES FOR FERRIS WHEEL ---- 

// ---- VARIABLES FOR FIREWORK ---- 
var fireworks = []; 
var particles = [];
var gravity = 0.7;
// ---- END OF VARIABLES FOR FIREWORK ---- 


function setup() {
	createCanvas(480, 480); 
  	frameRate(10);
	strokeWeight(1);
	stroke(255);

    // ---- FERRIS WHEEL ---- 
    // define ferris wheel dimensions
  
    var h = height/1.75;   // scaling ferris wheel (overall)

    centerX = h/2.2;  
    centerY = h - h/10; 
    radiusC1 = h/11; 
    radiusC2 = h/2.8; 
    radiusC3 = h/1.3; 
    radiusC3R = h/1.4; 
    radiusCar = h/10;
    radiusBolt = h/60;

    base = h/90;
    baseW = h/6.5;
    baseH = 1.35*h;

    // ---- FIREWORK ---- 
	fireworks.push(new Firework());
}

function draw() {
    background(36, 69, 140);
	background('rgba(0,0,0, 0.1)');

    // ---- FERRIS WHEEL ---- 
    
    // ---- ROTATIONAL ----
    // draw grey beam
    push();
    strokeWeight(1.1);
    stroke(supportColor);
    noFill();
    translate(centerX,centerY);
    rotate(frameCount/speed);
    for (k = PI/8; k < 2*PI; k += PI/4) {
      arc(0, 0, radiusC3, radiusC3, k, k + PI/4, PIE);
    } 
    pop();

    // draw white beam & circle 
    push();
    strokeWeight(1);
    stroke(structureColor);
    noFill();
    translate(centerX,centerY);
    rotate(frameCount/speed);
    for( i=0; i < 2*PI; i += PI/4) {
      arc(0, 0, radiusC3, radiusC3, i, i + PI/4, PIE);
    }
    pop();
  
    // draw passenger car 
    push();
    for (k=0; k<8; k++) {
        fill(72,157,206);
        arc(radiusC3R/1.85*cos(frameCount/speed + (PI/4*k)) + centerX, radiusC3R/1.85*sin(frameCount/speed + (PI/4*k)) + centerY, radiusCar, radiusCar, 0, PI);
    }
    fill(supportColor);
    translate(centerX,centerY);
    rotate(frameCount/speed);
    for (j=0; j < 2*PI; j += PI/4) {
        ellipse(radiusC3R/1.85*cos(j), radiusC3R/1.85*sin(j), radiusBolt, radiusBolt);
    }
    pop();
  
    // ---- STATIONARY ---- 
    // circle 1 
    push();
    strokeWeight(1.2);
    stroke(structureColor);
    fill(supportColor);         
    ellipse(centerX,centerY,radiusC1,radiusC1);
    pop();

    // circle 2 
    push();
    strokeWeight(1.2); 
    stroke(structureColor);     
    noFill();
    ellipse(centerX,centerY,radiusC2,radiusC2);
    pop();
  
    // support beam (base & passenger car)
    push();
    strokeWeight(1);
    stroke(structureColor);
    fill(0,0,0,0);
    for(a=0; a<base; a++) {
    triangle(centerX, centerY + a, centerX - baseW + a, baseH, centerX + baseW - a, baseH);
    } 
    pop();

    // ---- PIER ---- 
    push();
    strokeWeight(5);
    stroke(102,51,0);
    line(0,baseH, centerX*1.5, baseH);
    line(centerX*1.5-10, baseH, centerX*1.5-10, height);
    line((centerX*1.5-10)*2/3, baseH, (centerX*1.5-10)*2/3, height);
    line((centerX*1.5-10)/3, baseH, (centerX*1.5-10)/3, height);
    line(10, baseH, 10, height);
    pop();

    // ---- OCEAN ---- 
    push();
    drawWaveDistant(); // calling wave draw function    (foreground)
    drawWaveClose();   // calling wave draw function    (foreground)
    pop();

    // ---- FIREWORK ---- 
    push();
    translate(width / 2, height);

    if (random(1) < 0.10) {            // probability of firework release
        fireworks.push(new Firework())
    }

    for (var i = fireworks.length - 1; i >= 0; i--) {
        if(fireworks[i].type == "Exploded") {
            fireworks.splice(i,1);
            }
        else {
        fireworks[i].draw();
        }
    }

    for (var i = particles.length - 1; i >= 0; i--) { 
        if(particles[i].position.y > 0 || particles[i].brt <= 0) {
            particles.splice(i,1);
        }
    else {
        particles[i].draw();
    }
    }
    pop();

}   // ---- END OF DRAW FUNCTION ------- 

function Firework() {
    push();
    this.position = createVector(int(random(0, 0+width/3)), 0);
    this.speed = createVector(random(-1,1), -random(20,24));
    this.sparkler = round(random(0,1)) == 0;
    this.fuse = random(-1,1);
    fireworkType = int(random (0,6));
    
    switch (fireworkType) {
        case 0:
        this.type = "simple";
        break;
        case 1:
        this.type = "simple"; // used to be crackle but transformation was messing up geometry
        break;
        case 2:
        this.type = "sparkle";
        break;
        case 3:
        this.type = "double";
        break;
        case 4:
        this.type = "finale";
        break;
        case 5:
        this.type = "shooter";
        break;
    }

    this.draw = function() {      // FUNCTION 1 
        stroke(255);
        
        if (this.fuse < this.speed.y) {
            this.explode();
        }

        if (this.sparkler) {
            sparkleDir = random(0, TWO_PI);
            sparkleVel = random(0,1);
            sparkleSpd = createVector(sparkleVel * cos(sparkleDir), sparkleVel * sin(sparkleDir))
            thisSparkle = new Particle(createVector(this.position.x+sparkleSpd.x, this.position.y+sparkleSpd.y), sparkleSpd.copy(),random(3,8), random(255), random(255), random(255));
            particles.push(thisSparkle);
        }
        strokeWeight(2);
        stroke(random(255), random(255), random(255));
        point(this.position.x,this.position.y);

        this.position.add(this.speed);
        this.speed.y = this.speed.y + gravity;
    }                            // END OF FUNCTION 1 

    this.explode = function() {  // FUNCTION 2 
        switch (this.type) {
        case "sparkle":
        if (this.type == "sparkle") {
            for (var i = 0; i < 60; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,3) + random(0,3);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(3,8), random(255), random(255), random(255), "sparkle");
                particles.push(thisSparkle);
            }
                this.type = "Exploded";
        }

        break;

        case "double": {
            for (var i = 0; i < 90; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(3,5);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(2,4), random(255), random(255), random(255));
                particles.push(thisSparkle);
            }
            for (var i = 0; i < 10; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,.5);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(2,4), random(255), random(255), random(255));
                particles.push(thisSparkle);
            }
                this.type = "Exploded";
        }
        
        break;

        case "finale": {
            for (var i = 0; i < 500; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,4)+random(0,4);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(3,6), random(255), random(255), random(255));
                particles.push(thisSparkle);
            }
            this.type = "Exploded";
        }
        
        break;

        case "shooter": {
            for (var i = 0; i < 100; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,2)+random(0,3);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(1,3), random(255), random(255), random(255),"shooter");
                particles.push(thisSparkle);
            }
            this.type = "Exploded";
        }
        
        break;

        case "crackle": {
            for (var i = 0; i < 60; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,3) + random(0,3);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(7,10), random(255), random(255), random(255),"crackle");
                    particles.push(thisSparkle);
            }
            this.type = "Exploded";

        }
        
        break;

        default: {
            for (var i = 0; i < 100; i++) {
                sparkleDir = random(0, TWO_PI);
                sparkleVel = random(0,5);
                sparkleSpd = createVector(this.speed.x + sparkleVel * cos(sparkleDir), this.speed.y + sparkleVel * sin(sparkleDir))
                thisSparkle = new Particle(this.position.copy(), sparkleSpd.copy(), random(1,3), random(255), random(255), random(255));
                particles.push(thisSparkle);
            }
            this.type = "Exploded";
        }
        }
    }            // ---- END OF FUNCTION 2 
    pop();
}  


function Particle(position, speed, fade, r, g, b, type) { 
	this.position = position.copy();
	this.speed = speed.copy(); 
	this.fade = (fade == undefined ? 5 : fade);
	this.r = r
    this.g = g
    this.b = b
    this.type = type;

	this.brt = 70;

	this.burntime=0;

	this.draw = function() {
		stroke(this.r, this.g, this.b);
		newPositionX = this.position.x + log(this.burntime) * 8 * this.speed.x;
		newPositionY = this.position.y + log(this.burntime) * 8 * this.speed.y + this.burntime * gravity;

		point(newPositionX, newPositionY);

		if (this.type == "shooter" & this.burntime > 1) {
			line(newPositionX, newPositionY, this.position.x + log(this.burntime-2) * 8 * this.speed.x, this.position.y + log(this.burntime-2) * 8 * this.speed.y + this.burntime * gravity);

(note: I uploaded my final project before the midnight deadline on Friday, however, I noticed that the visuals was not showing up on my post so I tried editing it. It is still not showing up on WordPress when it was originally.)

I changed my idea from my Final Project proposal; initially I wanted to create a storyboard that incorporated fireworks as the final landscape. But I thought a storyboard wasn’t “computational” enough and I wanted to incorporate more concepts learned in class. So that’s why I maintained creating a code for fireworks and incorporated a generative landscape of a ferris wheel. I wrote the fireworks to be multi-colored, and at random fire different styles of fireworks. One thing I struggled with is putting the ferris wheel code and the fireworks code together; the codes would affect the other and therefore I had to use push() and pop() to maintain the stylistic elements of the two components of my final project.

hqq – rsp1 – final_project – sections _ e+b

PSA: THIS IS A TWO-PART ENDEAVOR, SO BE SURE TO SCROLL DOWN FOR PART 2!

Hi guys! This is a game we made called “Carl Cooks a Meal” that exists in two parts. Under the premise, our friend Carl is trying to make a lovely meal for his girlfriend Carla. However, he has absolutely no idea how to start! The first part is a clickventure where people help Carl gather ingredients. People have the option to either check in the refrigerator to see what’s inside OR take a trip to a distant country to get some more exotic ingredients. In travelling, users can learn about the histories behind these ingredients, adding an educational aspect to this part. Users can then return home to begin the second part. In the second part, people help Carl “cook” the meal. This is in the form of a game where users have to catch these ingredients in a pan to reach the final score. However, after each time an ingredient is caught in the pan, they begin to fall faster, making it more difficult as time passes. Once thirty ingredients have been caught, the meal is done, and Carla is very happy! Thanks for helping Carl make the meal!

part 1

/*15-104 final projec
team members: rachel park (rsp1) and hamza qureshi (hqq)
section: b; e


CARL COOKS A MEAL*/

var button1, button2, button3, button4, button5; //these variables create buttons, which are defined
                                                //locally to avoid having to create dozens of em
var home, meetCarl, where2go, worldMap, fridge, //these variables will hold the images that form each slide
    turmeric, miso, acai, foieGras, uSure,
    startup;
var col;                                       //sets color
//---------------------------------------------------
function setup() {
    createCanvas(480,480);
    background(0);
    noLoop();                                //allows the slides to remain static (prevents flickering!)
}
//---------------------------------------------------
function draw() { //will only comment once in detail because it can get redundant
  home = createImg("https://i.imgur.com/aI9WG89.jpg"); //creates slide
  home.position(-760,-760); //position and scales are used to fit the images on the canvas
  home.style("transform", "scale(0.25)");
  button1 = createButton('Play Game!'); //creates a button
  button1.position(300,200);
  col = color(129,178,154);
  button1.style("background-color", col);
  button1.style("color", "white");
  button1.mousePressed(PromptPage); //allows the button to load the next screen
}
//---------------------------------------------------

//functions for each page

function PromptPage() {
  //prompts with info on what to do
    meetCarl = createImg("https://i.imgur.com/HAX6uEa.jpg");
    meetCarl.position(-760, -760);
    meetCarl.style("transform", "scale(0.25)");
    button1 = createButton('Help me out →');
    col = color(129,178,154);
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(350,200);
    button1.mousePressed(ScenePage);
}
//---------------------------------------------------
function ScenePage() {
  //loads scene where users have option of gathering ingredients
    where2go = createImg("https://i.imgur.com/7F5M1iF.jpg");
    where2go.position(-760,-760);
    where2go.style("transform", "scale(0.25)");
    button1 = createButton('Open the fridge');
    col = color(129,178,154);
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(20,220);
    button1.mousePressed(FridgeFoodPage);
    button2 = createButton('Take a trip');
    col = color(129,178,154);
    button2.style("background-color", col);
    button2.style("color", "white");
    button2.position(140,460);
    button2.mousePressed(WorldFoodPage);
    button3 = createButton('Time to cook!');
    col = color(129,178,154);
    button3.style("background-color", col);
    button3.style("color", "white");
    button3.position(300,180);
    button3.mousePressed(gameLandingPage);
}
//---------------------------------------------------
function WorldFoodPage() {
  //loads international map screen, with buttons for diff locations
    worldMap = createImg("https://i.imgur.com/aNsxfi1.jpg");
    worldMap.position(-760,-760);
    worldMap.style("transform", "scale(0.25)");
    button1 = createButton('Brazil');
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(130,230);
    button1.mousePressed(brazil);
    button2 = createButton('France');
    button2.style("background-color", col);
    button2.style("color", "white");
    button2.position(150,80);
    button2.mousePressed(france);
    button3 = createButton('India');
    button3.style("background-color", col);
    button3.style("color", "white");
    button3.position(320,160);
    button3.mousePressed(india);
    button4 = createButton('Japan');
    button4.style("background-color", col);
    button4.style("color", "white");
    button4.position(420,120);
    button4.mousePressed(japan);
    button5 = createButton('Go back home!');
    button5.style("background-color", col);
    button5.style("color", "white");
    button5.position(190,450);
    button5.mousePressed(ScenePage);
}
//---------------------------------------------------
function FridgeFoodPage() {
  //loads fridge screen with items available in the fridge
    fridge = createImg("https://i.imgur.com/jPanqPC.jpg");
    fridge.position(-760,-760);
    fridge.style("transform", "scale(0.25)");
    button1 = createButton('Grab the items!');
    col = color(129,178,154);
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(320,220);
    button1.mousePressed(FridgeGrab);
    button2 = createButton('No thanks!');
    col = color(129,178,154);
    button2.style("background-color", col);
    button2.style("color", "white");
    button2.position(320,260);
    button2.mousePressed(ScenePage);
}
//---------------------------------------------------
function FridgeGrab(){
  //simulates "grabbing" items from the fridge
    fridge = createImg("https://i.imgur.com/zlj1DaE.jpg");
    fridge.position(-760,-760);
    fridge.style("transform", "scale(0.25)");
    button1 = createButton('Back to the kitchen!');
    col = color(129,178,154);
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(320,220);
    button1.mousePressed(ScenePage);
}
//---------------------------------------------------
function india() {
  //loads turmeric screen
    turmeric = createImg("https://i.imgur.com/tj04pYa.jpg")
    turmeric.position(-760,-760);
    turmeric.style("transform", "scale(0.25)");
    countryButtons();
}
//---------------------------------------------------
function japan(){
  //loads miso screen
    miso = createImg("https://i.imgur.com/A0mow9a.jpg")
    miso.position(-760,-760);
    miso.style("transform", "scale(0.25)");
    countryButtons();
}
//---------------------------------------------------
function france(){
  //loads france screen
    foieGras = createImg("https://i.imgur.com/4OLHPzQ.jpg")
    foieGras.position(-760,-760);
    foieGras.style("transform", "scale(0.25)");
    countryButtons();
}
//---------------------------------------------------
function brazil(){
  //loads brazil screen
    acai = createImg("https://i.imgur.com/H4gDOUD.jpg")
    acai.position(-760,-760);
    acai.style("transform", "scale(0.25)");
    countryButtons();
}
//---------------------------------------------------
function countryButtons(){
  //creates two sets of buttons on country screen to
  //allow for less code to be used in each of the country slides.
    button1 = createButton('Take home!');
    button1.style("transform", "scale(0.8)");
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(170,310);
    button1.mousePressed(WorldFoodPage);
    button2 = createButton('All done!');
    button2.style("transform", "scale(0.8)");
    button2.style("background-color", col);
    button2.style("color", "white");
    button2.position(178, 370);
    button2.mousePressed(gameLandingPage);
}
//---------------------------------------------------
function gameLandingPage(){
  //makes sure the user is ready (lol)
    uSure = createImg("https://i.imgur.com/9RFTHko.jpg");
    uSure.position(-760,-760);
    uSure.style("transform", "scale(0.25)");
    button1 = createButton('Yes, I am ready!');
    button1.style("background-color", col);
    button1.style("color", "white");
    button1.position(190,250);
    button1.mousePressed(gameStartScreen);
    button2 = createButton('No, not yet!');
    button2.style("background-color", col);
    button2.style("color", "white");
    button2.position(200, 300);
    button2.mousePressed(ScenePage);
}
//---------------------------------------------------
function gameStartScreen(){
  //loads final screen of this part, instructing users to scroll
    startup = createImg("https://i.imgur.com/duuVdOZ.jpg");
    startup.position(-760,-760);
    startup.style("transform", "scale(0.25)");
}
//---------------------------------------------------

part 2

/*15-104 final project
team members: rachel park (rsp1) and hamza qureshi (hqq)
section: b; e


CARL COOKS A MEAL*/

//setting global variables to use throughout the code

//for score
var score = 0;
//for falling objects
var speed = 10;
var canHit = true;
var x = 0;
var y = 0;
var s = 5;
//for key functions
var keyRIGHT= false;
var keyLEFT= false;
var moveRight = false;
var moveLeft = false;
//for frypan options
var onBasket = false;
//setting modes to use to run the functions
var beforeGame;
var endGame;
var beginning;
var ending;
//for arrays used in code
var fridge = [];
var ixs = [50,-50,350];
var iys = [-500, 0, -1000];
//to load frypan image
var frypan;
//---------------------------------------------------

//preloading images of foods and pushing into new array
function preload() {
    var Foods = [
      "https://i.imgur.com/WrAqBJF.png",
      "https://i.imgur.com/F6VoqQ8.png",
      "https://i.imgur.com/6Piz1HF.png",
      "https://i.imgur.com/Qltr0uK.png"];
    for (var i = 0; i < Foods.length; i++){
      fridge.push(loadImage(Foods[i]));
    }
}
//---------------------------------------------------
//setting up canvas and using modes
function setup () {
  createCanvas(480, 480);
  background(129,178,154);
  beforeGame = true;
  endGame = false;
  frypan = loadImage("https://i.imgur.com/UdaokKr.png");
  ending = loadImage("https://i.imgur.com/0EdDOXJ.jpg");
  beginning = loadImage("https://i.imgur.com/crhULDP.jpg");
}
//---------------------------------------------------
//function to start game when any key is pressed
function keyPressed() {
    beforeGame = false;
}
//---------------------------------------------------
//function to make frypan move as a gathering platform
function keyTyped() {
   if (keyCode === LEFT_ARROW) {
      keyLEFT = true;
   } else if (keyCode === RIGHT_ARROW) {
      keyRIGHT = true;
     }
}
//---------------------------------------------------
//drawing the game by calling the other functions which make the visuals of the objects
function draw() {
    if (beforeGame == true) {
      push();
      scale(0.24);
      imageMode(CORNER);
      image(beginning,0,0);
      pop();
    } else {
      background(129,178,154);
      BasketDraw();//drawing the frypan
      foodDraw();//drawing the falling food objects
      update();//updating the so that frypan moves with keys and food continuously falls onto canvas
      displayScore();//displaying number of foods caught
    }
  if (endGame == true) {//displaying ending page when game is finished
    push();
    scale(0.24);
    imageMode(CORNER);
    image(ending,0,0);
    pop();
  }
}
//---------------------------------------------------
function reachBottom() {//ending the game when food hits limit
    endGame = true;
}
//---------------------------------------------------
function displayScore() {//function to create the score
  fill(0);
  textSize(20);
  text(("Score: " + this.score + " out of 30!"), 80, 23);
}

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

function makeFood(length, xpos, ypos, space) {//class to draw the food objects

  var food = {"l": length, "ix": xpos, "iy": ypos, "s": space}
  food.draw = foodDraw;
  return food;
}

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

function foodDraw() {//drawing the foods

    for (var i = 0; i < ixs.length; i++){
    imageMode(CORNER);
    canHit = true;
    fill(255);
    stroke(4);
      image(fridge[i], this.ixs[i], this.iys[i]);
    }
    for (var i = 0; i < iys.length; i++) {

      this.iys[i] += this.s/2
    }

}

//---------------------------------------------------
function makeBasket(xpos,ypos,moveBasket) {//class to make the frypan (aka basket)
  var Basket = {"x": xpos, "y": ypos}
  Basket.draw = BasketDraw;
  return Basket;
}
//---------------------------------------------------
function BasketDraw() {//drawing the basket
  noStroke();
  fill("#FFD581");
  image(frypan,this.x, this.y + height-50);
}
//---------------------------------------------------
function update() {//function to update the objects and have them restart at top to be continuously moving
  //for basket
  if(keyIsDown(RIGHT_ARROW) & this.x < width-20){
     this.x += speed;
     print(x);
   }
 if (keyIsDown(LEFT_ARROW) & this.x > -20){
     this.x -= speed;
     print(x);
  }
  print(width)
//for food
  for(var i = 0; i < iys.length; i++){
    if (this.iys[i] >= height-80) {
      if(this.ixs[i] >  this.x - 100 & this.ixs[i] < this.x + 100) {
         this.score++;
         this.s ++;
         if( this.score == 30) {
           reachBottom();
         }
      }
      this.iys[i] = random(-1000, -300);
      this.ixs[i] = random(-300 ,width-40);
    }
  }
}
//---------------------------------------------------

As one might expect with almost 400 lines of code, there were a couple of roadblocks on the way. The biggest one was probably the marrying of the two parts to create one code, which we weren’t able to do. This is primarily because the first part uses the DOC library via buttons and commands like createImg, while the second part relies solely on p5. This caused difficulties in combining the two sets of code because they required a change in the HTML template to allow them to be combined. Once we were able to, the code wasn’t running as smoothly as we had intended. However, despite dividing them into these two parts, we were able to successfully create a unified game experience that uses two modes to reach a greater goal. For us, that’s a win! 🙂

ikrsek– Final Project – Section C

 

Instructions:
You can click your mouse to move your character, (which changes from dream to dream) – and you change dreams by pressing 1,2,3,4 or 5 on your keyboard. When you’re in dreams you can hover over certain notes to see what that dream is about – (for the green woman you hover over her mouth since there is no note).

sketch

//Isadora Krsek 
//Ikrsek@andrew.cmu.edu
//Section C
//Final Project(Project 12): "Dreamscape"

var DreamTracker = (0);

//vars scenery 
var morningStars = [];

//dream5
var clouds;
var daSky;
var daGround;
var stillMan;
var message5;
var message5X = (145.5);
var message5Y = (298);

//dream4
var bed;
var woman;
var message4;
var message4X = (401);
var message4Y = (75);

//dream3
var building;
var tree;
var moon; 
var dirt;
var groundRipples;
var message3;
var message3X = (453);
var message3Y = (330);

//dream2
var spinnyThing;
var lamp;
var touchyGuy;
var LadyWithEyes;
var weirdKid; 
var note;
var message2;
var message2X = (405);
var message2Y = (311);

//dream1
var ripples;
var girl;
var papers;
var trees;
var message1;
var message1X = (155);
var message1Y = (252);

//vars for moveable character in dream 5
var kidFramez = []; // An array to store the images
var kidPreX; // The last X location of the character
var kidPreY; // The last Y location of the character
var kidTrack = (0); //to keep kidTrack fo index in array "kidFramez"
var kidX; //the current x location of character
var kidY = 360; //the current y location of character

//vars for moveable fly
var flyFramez = []; // An array to store the images
var flyPreX; // The last X location of the character
var flyPreY; // The last Y location of the character
var flyTrack = (0); //to keep flyTrack fo index in array "flyFramez"
var flyX; //the current x location of character
var flyY; //the current y location of character

//vars for main character
var mainCharFramez = []; // An array to store the images
var mainCharPreX; // The last X location of the character
var mainCharPreY; // The last Y location of the character
var trackMain = (0); //to keep trackMain fo index in array "mainCharFramez"
var mainCharX; //the current x location of character
var mainCharY = 300; //the current y location of character

var targetX; // The X goal, from the user's click
var targetY; // The Y goal, from the user's click 

//------let the code begin------------------------------------------

function preload(){
    //These URLs are for main character's walk cycle images
    var filenames = [];
    filenames[0] = "https://i.imgur.com/hi7fjid.png" 
    filenames[1] = "https://i.imgur.com/DlkJlK6.png" 
    filenames[2] = "https://i.imgur.com/KQcAqSF.png" 
    filenames[3] = "https://i.imgur.com/PgWS8Ek.png" 
    filenames[4] = "https://i.imgur.com/S7T2PoJ.png"  
    filenames[5] = "https://i.imgur.com/lNmB0Sh.png" 
    filenames[6] = "https://i.imgur.com/6rRh9JS.png" 
    filenames[7] = "https://i.imgur.com/lNmB0Sh.png" 
    //array for the walking cycle
    for(var i=0; i < filenames.length; i++) {
        mainCharFramez.push(loadImage(filenames[i]));
    }
    
    //dream 5 load-ins
    clouds = loadImage("https://i.imgur.com/K0WuYlD.png");
    daSky = loadImage("https://i.imgur.com/xtFA8AG.png");
    daGround = loadImage("https://i.imgur.com/KVhbWTf.png");
    stillMan = loadImage("https://i.imgur.com/JRbHrTk.png");
    message5 = loadImage("https://i.imgur.com/BuNkluX.png");
    //for the walking kid
    var filenames2 = [];
    filenames2[0] = "https://i.imgur.com/8IEaEQz.png" 
    filenames2[1] = "https://i.imgur.com/eSKype2.png" 
    filenames2[2] = "https://i.imgur.com/3Jc1SAO.png" 
    filenames2[3] = "https://i.imgur.com/xD4OH72.png" 
    filenames2[4] = "https://i.imgur.com/IT7FXKF.png"  
    filenames2[5] = "https://i.imgur.com/Syn95Ib.png" 
    filenames2[6] = "https://i.imgur.com/OHlPsCf.png" 
    filenames2[7] = "https://i.imgur.com/mJMmHXz.png"
    //array for walking
    for(var z=0; z < filenames2.length; z++) {
    kidFramez.push(loadImage(filenames2[z]));
    }
    
    //dream 4 load-ins
    bed = loadImage("https://i.imgur.com/0Lc8iQs.png");
    woman = loadImage("https://i.imgur.com/bINLqta.png");
    message4 = loadImage("https://i.imgur.com/HzVhpA1.png");
    
    //dream 3 load-ins
    building = loadImage("https://i.imgur.com/rNIfdQ5.png");
    tree = loadImage("https://i.imgur.com/hgvQQsn.png");
    moon = loadImage("https://i.imgur.com/b2JY2gV.png"); 
    groundRipples = loadImage("https://i.imgur.com/12PrKWt.png");
    dirt = loadImage("https://i.imgur.com/SIdPvf1.png");
    message3 = loadImage("https://i.imgur.com/ZqzLPma.png");
    
    //dream 2 load-ins
    spinnyThing = loadImage("https://i.imgur.com/VLWV1Ri.png");
    lamp  = loadImage("https://i.imgur.com/cfaSffr.png");
    touchyGuy = loadImage("https://i.imgur.com/bcEIg2B.png");
    LadyWithEyes = loadImage("https://i.imgur.com/AHm0VMD.png");
    weirdKid = loadImage("https://i.imgur.com/AkoodGn.png");
    note = loadImage("https://i.imgur.com/PP7U6Rg.png");
    message2 = loadImage("https://i.imgur.com/hbIgCMR.png");
    
    //dream 1 load-ins
    trees = loadImage("https://i.imgur.com/WXXHuxn.png");
    girl = loadImage("https://i.imgur.com/vI3RID0.png");
    papers = loadImage("https://i.imgur.com/gdNlDPK.png");
    ripples = loadImage("https://i.imgur.com/DpPYeiP.png");
    message1 = loadImage("https://i.imgur.com/VKZcrYA.png");
    
    //These URLs are for fly's cycle
    var filenames3 = [];
    filenames3[0] = "https://i.imgur.com/MSyp1iw.png" 
    filenames3[1] = "https://i.imgur.com/lVJeXAA.png" 
    filenames3[2] = "https://i.imgur.com/GENXp9g.png"
    filenames3[3] = "https://i.imgur.com/Th6Ckap.png" 
    //fly man 
    for(var q=0; q < filenames3.length; q++) {
      flyFramez.push(loadImage(filenames3[q]));
    }
    
}
 
function setup(){
    createCanvas(480, 375);
    background(30);
    imageMode(CENTER);
    frameRate(10);
    //Initialize main character postition & target
    mainCharPreX = 50; 
    mainCharPreY = height/2; 
    targetX = mainCharPreX;
    targetY = mainCharPreY;    
    //initialize fly's position & target
    flyPreX = 50;
    flyPreY = height/2;
    targetX = flyPreX;
    targetY = flyPreY;
        //initialize fly's position & target
    flyPreX = width/2;
    flyPreY = height/2;
    targetX = flyPreX;
    targetY = flyPreY;
    //initialize child's position & target
    kidPreX = width-50;
    kidPreY = 360;
    targetX = kidPreX;
    targetY = kidPreY;   
    
    //stars
    //# which allows for new star to appear
    StarProb = 30; 
    //morningStars inital amount 
    for (var i = 0; i < 22; i++) {
      morningStars[i] = new Star(random(width));
    } 
} 
 
function draw(){
  //cycle through dreams by pressing 1,2,3,4, or 5
    if (DreamTracker === 0){
      Dream1();  
    } else if (DreamTracker == 1){
      Dream2();
    } else if (DreamTracker == 2){
      Dream3();
    } else if (DreamTracker == 3){
      Dream4();
    } else if (DreamTracker == 4){
      Dream5();
    }
}

function Dream1(){
    push();
    scale(.81);
    noStroke();
    fill(224,196,195);
    rect(0,0,width+120,height-100); //sky
    drawStars();
    noStroke();
    fill(192,198,210);
    rect(0,height-124,width+120,height); //ground
    image(trees,302,215,trees.width*1.2,trees.height*1.2);
    image(girl,312,265,girl.width*1.1,girl.height*1.1);
    image(ripples,312,219,ripples.width*1.3,ripples.height*1.1);
    image(papers,312,255,papers.width*1.2,papers.height*1.2);
    pop();
    fly();
    //hover over note to see message
    if(dist(mouseX,mouseY,message1X,message1Y)<10){
      image(message1,width/2,height/2);
    }
}

function Dream2(){
    push();
    scale(.81);
    noStroke();
    mainCharY = 305;
    fill(223,212,119);
    rect(0,0,width+120,170); //sky
    noStroke();
    fill(252,207,185);
    rect(0,170,width+120,height); //ground
    image(spinnyThing,312,225,spinnyThing.width*1.2,spinnyThing.height*1.2);
    image(lamp,300,225,lamp.width*1.2,lamp.height*1.2);
    image(touchyGuy,312,225,touchyGuy.width*1.2,touchyGuy.height*1.2);
    image(LadyWithEyes,312,225, LadyWithEyes.width*1.2, LadyWithEyes.height*1.2);
    mainCharWalks();
    image(weirdKid,312,225,weirdKid.width*1.2,weirdKid.height*1.2); 
    image(note,312,225,note.width*1.2,note.height*1.2);
    pop();
    
    //hover over note to see message
    if(dist(mouseX,mouseY,message2X,message2Y)<15){
      image(message2,width/2,height/2);
    }
}

function Dream3(){
    push();
    scale(.75);
    mainCharY = 405;
    noStroke();
    fill(179,132,13);
    rect(0,0,width+180,height*2); //sky
    fill(51,45,29);
    rect(0,height+20,width+180,height*2); //ground
    drawStars();
    image(dirt,312,235,dirt.width*1.3,dirt.height*1.3);
    image(moon,310,250,moon.width*1.3,moon.height*1.3);
    image(tree,312,235,tree.width*1.3,tree.height*1.3);
    image(groundRipples,312,235,groundRipples.width*1.3,groundRipples.height*1.3);
    image(building,312,235,building.width*1.3,building.height*1.3);
    image(note,500,352,note.width/1.5,note.height/1.5);
    mainCharWalks();
    pop();

    //hover over note to see message
    if(dist(mouseX,mouseY,message3X,message3Y)<10){
      image(message3,width/2,height/2);
    }
}

function Dream4(){
    push();
    scale(.75);
    noStroke();
    fill(32,34,26);
    rect(0,0,width,height); //sky
    image(bed,320,250,bed.width*1.3,bed.height*1.4)
    image(woman,320,250,woman.width*1.3,woman.height*1.4)
    pop();
    fly();
    //hover over note to see message
    if(dist(mouseX,mouseY,message4X,message4Y)<10){
      image(message4,width/2,height/2);
    }
}

function Dream5(){
    push();
    scale(.75);
    //the sky is is comprised of two images
    image(daSky,320,210,daSky.width*1.6,daSky.height*1.2)
    drawStars();
    image(clouds,320,250,clouds.width*1.3,clouds.height*1.4)
    image(daGround,320,250,daGround.width*1.3,daGround.height*1.4)
    image(stillMan,585,345,stillMan.width*1.05,stillMan.height*1.05)
    image(note,90,309,note.width/1.5,note.height/1.5);
    image(mainCharFramez[5],40,412)
    pop();
    push();
    scale(.75)
    kidWalks();
    pop();
    
    //hover over note to see message
    if(dist(mouseX,mouseY,message5X,message5Y)<10){
      image(message5,width/2,height/2);
    }
    
  
}

//all of the moveable characters
function fly(){
  //--------flying conditions...
    var dx = targetX - flyPreX;
    var dy = targetY - flyPreY;
    var distanceFromCharacterToTarget = sqrt(dx*dx + dy*dy);
    //control how fly moves toward target 
    flyX = lerp(flyPreX,targetX,0.15);
    flyY = lerp(flyPreY,targetY,0.15);
    //keep looping through the images seamlessly 
    if (flyTrack >= flyFramez.length){
      flyTrack = 0; 
    }
  //--------the actual flying part & more conditions...
    if (flyX < flyPreX){
      push();
      scale(-1,1);//flip image 
      image(flyFramez[flyTrack],flyX*-1,flyY); //you multiply the X-coordinate by -1 so it walks in the right direction 
      pop();
    }
    //otherwise if it's larger, it will be flying right
    else if (flyX >= flyPreX){
      image(flyFramez[flyTrack],flyX,flyY);
    }
  //------------------Refresh values...
    flyPreX = flyX;
    flyPreY = flyY;
    //cycle through the walking images 
    flyTrack = flyTrack + 1
}    

function kidWalks(){
  //--------walking conditions...
    var dx = targetX - kidPreX;
    var dy = targetY - kidPreY;
    var distanceFromCharacterToTarget = sqrt(dx*dx);
    //control how character moves toward target 
    kidX = lerp(kidPreX,targetX,.15);
    //keep looping through the images seamlessly 
    if (kidTrack >= kidFramez.length){
      kidTrack = 0; 
    }
  //--------the actual walking part & more conditions...
  //if the current x location is smaller than last x location, walk left
    if (distanceFromCharacterToTarget < 15 && kidX < kidPreX){
      push();
      scale(-1,1);//flip image 
      image(kidFramez[2],kidX*-1,kidY);
      pop();
    } 
    else if(distanceFromCharacterToTarget < 15){
      image(kidFramez[2],kidX,kidY);
    } 
    else if(kidX < kidPreX){
      push();
      scale(-1,1);//flip image 
      image(kidFramez[kidTrack],kidX*-1,kidY); 
      pop();
    }
    //otherwise if larger, walk right
    else if(kidX >= kidPreX){
      image(kidFramez[kidTrack],kidX,kidY);
    }
  //------------------Refresh values...
    kidPreX = kidX;
    kidTrack = kidTrack + 1;
}

function mainCharWalks(){
  //--------walking conditions...
    var dx = targetX - mainCharPreX;
    var dy = targetY - mainCharPreY;
    var distanceFromCharacterToTarget = sqrt(dx*dx );
    //control how character moves toward target 
    mainCharX = lerp(mainCharPreX,targetX,.15);
    theY = lerp(mainCharPreY,targetY,.15);
    //keep looping through the images continuously/seamlessly 
    if (trackMain >= mainCharFramez.length){
      trackMain = 0; 
    }
  //--------the actual walking part & more conditions...
    //if the current x location is smaller than last x location, walk left
    if(distanceFromCharacterToTarget < 15 && mainCharX < mainCharPreX){
      push();
      scale(-1,1);//flip image 
      image(mainCharFramez[7],mainCharX*-1,mainCharY);
      pop();
    } 
    else if(distanceFromCharacterToTarget < 15){
      image(mainCharFramez[7],mainCharX,mainCharY);
    } 
    else if (mainCharX < mainCharPreX){
      push();
      scale(-1,1);//flip image 
      image(mainCharFramez[trackMain],mainCharX*-1,mainCharY); 
      pop();
    }
    //otherwise if larger, walk right
    else if (mainCharX > mainCharPreX){
      image(mainCharFramez[trackMain],mainCharX,mainCharY);
    }
  //------------------Refresh values...
    mainCharPreX = mainCharX;
    mainCharPreY = theY;
    trackMain = trackMain + 1;
}

//other stuff
function mousePressed(){
    targetX = mouseX;
    targetY = mouseY;
}

function keyPressed(){
    if (key == "1"){
      DreamTracker = (0);
    } else if (key == "2"){
      DreamTracker = (1);
    } else if (key == "3"){
      DreamTracker = (2);
    } else if (key == "4"){
      DreamTracker = (3);
    } else if (key == "5"){
      DreamTracker = (4);
    }
}    

function drawStars(){
  //when random # is smaller than probability then new start occurs  
  if (StarProb > random(0,100)) {
    morningStars.push(new Star(width));
  }
  for (var i = 0; i < morningStars.length; i++) {
    morningStars[i].move(); //update star array
    morningStars[i].display(); 
  //if star goes out of boundary, remove it
    if (morningStars[i].x < 0) { 
      morningStars.splice(i, 1);
    }    
  }
}

//generate morningStars
function Star(xLocation){
    var randoOpa = random(80,180); //have the brightness of stars vary 
    var randoSize = random(0.5,2); //have star size vary 
    strokeWeight(randoSize);
    this.x = xLocation;//controlled above by random width 
    this.y = random(1,380); //range for stars to appear
    this.speed = (-1.5); //speed       
    this.move = function() {
      this.x += this.speed; //move the stars
    }
    this.display = function() {
	  //draw the stars here 
	    stroke(202,195,232,80);
      fill(202,195,232,randoOpa);
	    ellipse(this.x, this.y,randoSize,randoSize);
    }
}

Conclusion:
Overall this project was exhausting to complete – but I’m pleased with the way it looks. Each image was hand drawn in photoshop with a one pixel brush so as to have the utmost control over my vision.  I spent all of my free-time working on this, trying to bring it to life as best I could. There is still much more I would’ve liked to do with it, such as adding smoother transitions between dream sequences or adding more notes but overall it really sticks close to how I envision it in my head. In terms of the notes, I intended for them to be difficult to read to act as a parallel to the ambiguity and hazy quality of dreams – how things can seem so fuzzy and vague but you still can understand what’s going on perfectly.

Here’s a video of a play through with all the actions:

 

 

Here are some photos of each scene and the corresponding note:

If you want to know what each of the notes say, here is a quick copy of each of them:

Note from dream 1:
“I remember a young girl desparately searching for something… she was wading through papers in a clear blue body of water. There were pathetic and skinny little trees that grew around and behind her directly from the water which was a bit of an odditiy… I remeber trying to call out to her – ask her what she was looking for or if I could help… but she ignored me. The more I tried to screm the less I seemed to make a sound and I was quickly becoming panicked – it was at that point that I realized thtat I was just a fly. She couldn’t hear or understand me no matter how hard I would try and I was nothing more than a buzzing nuisance. I resigned to watch after realizing this and was surprised by the fact that she was so involved in her task – that she was completely unbothered by the annoying buzzing coming from me.”

Note from dream 2:
“There were three people all standing or sitting around, it was outside – but I’m not exactly sure where – mostly because we were in the grass but there was also a lamp plugged in outside? I tried to turn it on, but the lamp was broken. The sky in combination with the color of the ground reminded me of an anemic watermelon – maybe this is summer then? Anywho I remember seeing a girl sitting down and a gentlemen beside her -only he wasn’t much of a gentleman… his hands were crawling up her leg and I could see her whole face go black (well, everything but her eyes which remained a piercing white color). There was also a strange you child – just watching. Everyone had eyes but the only one with a mouth was Mr.Touchy feely.. I still don’t understand this.”

Note from dream 3:
“This dream I don’t remember all too well – all I remember is how it looked and felt to be there, the way the stars moved across the sky (as they always do in my dreams for some reason) and the odd abandoned structure sitting still beneath a blossomig tree – It looked so rickety, like it could’nt possibly hold anyone up inside of it… but somehow in that absence of another person – you could feel them there… I don’t know who exactly, just that there was supposed to be someone there. There is some presence in absence here…”

Note from dream 4:
“I remember this dream so vividly – it was beautiful – the plush bed reminded me of the way that cloth is rendered in paintings of Vesnus by TItian or other great artsists who inspired the classical period – the colors were off though – the women, although supple and lush was a gastly shade of green and somehow upon looking at her I knew she was dead. Dead people aren’t usually green – I know, but it was that weird “dreamer’s intuition” where you know nothing makes sense but somehow you are able to piece things together and just know things somehow. What didn’t know was why or how. Maybe there’se something to be said for the fact that I appeared asa fly in this dream as well…”

Note from dream 5:
“It was dark – like time was moving backward . The sky shifted from a deep red to dark blue – almost like a sunset? But not quite. The clouds draped down the sky and had an overwhleming presence – they were almost too big – and I remember the way the stars moved behind the clouds – like they were being projected in motion across the sky – but the strangest part were the two people I saw – one not even moving, but entranced by the sky – the other walked backwards and refused to make eye-contct. I couldn’t move at all – I was trapped like the one looking to the sky and I only remember the fear that filled my body at the younger one moved closer – I was unsure of what they would do”

yushano_Final Project

yushano-12
sketch

//Isabella Ouyang
//Section A
//yushano@andrew.cmu.edu
//Assignment-12

var choice = [];
var trees = [];
var snowmen = [];
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;
var thespeed = 1;
var songs=[];
var textX = 0;
var playMusic = false;

function preload() {
   var song1 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/all-i-want-for-christmas-is-you.mp3");
   var song2 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/ChristmasIsntChristmas.mp3");
   var song3 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/jingle-bell.mp3");
   var song4 = loadSound("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/silent-night.mp3");
   songs.push(song1);
   songs.push(song2);
   songs.push(song3);
   songs.push(song4);
   imgplus = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/plus.jpg");
   imgmusic = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/music.jpg");
   imgminus = loadImage("https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/minus.jpg");
}

function setup() {
    createCanvas(480, 240); 
    frameRate(5);
}

function draw() {
    background(205,233,233); 

    // display the background
    stroke(0);
    strokeWeight(1);
    drawMountain();
    displayHorizon();

    // draw objects
    // Ferris Wheel
    // update the rotation
    drawFerrisWheel();
    thespeed += 0.5;
    
    // Trees
    updateAndDisplayTrees();
    addNewTreesWithSomeRandomProbability();

    // Snowmen
    updateAndDisplaySM();
    addNewSMWithSomeRandomProbability();

    // snow
    drawSnow();

    // window frame
    strokeWeight(40);
    stroke(230);
    line(0,0,0,height);
    line(width,0,width,height);

    // load buttons
    image(imgplus,width-20,10);
    image(imgmusic,0,10);
    image(imgminus, width-20, 40);

}

function drawFerrisWheel(){
    strokeWeight(2);
    noFill();
    
    // draw the structure
    noStroke();
    fill(200);
    rect(width/2-2,height/2,4,85);
    fill(150);
    ellipse(width/2,height/2,10);
    rect(width/2-20,height/2+80,40,5);

    // draw the curve
    push();
    noFill();
    translate(width / 2, height / 2);
    rotate(thespeed);
    // the curve inside
    for (var i = 0; i < 8; i++) {
        // calculate the gradient of color
        var r = 207 - (207 - 152) / 6 * i;
        var g = 171 - (171 - 92) / 6 * i;
        var b = 177 - (177 - 103) / 6 * i;
        stroke(r, g, b);
        drawTetracuspidCurve();    
        rotate(PI / 14);
    }
    pop();   
    
}

function drawTetracuspidCurve(){
    var nPoints = 400;
    var x;
    var y;
    var a = 75;
    var ph = 0;
    noFill();
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        x = a / 4 * (3*cos(t) -  cos(ph + 3 * t));
        y = a / 4 * (3*sin(t) +  sin(ph + 3 * t));
        vertex(x, y);
        push();
        // draw the cart at each peak
        if (x == 0 || y == 0) {
            for (var i = 0; i < 4; i++) {
                fill(204, 229, 255);
                rect(x + 35, y + 3, 10, 10);
                rotate(TWO_PI / 4);
            
            }    
        }
        pop();
    }
    endShape(CLOSE);    
}

function drawMountain() {
    fill(255); 
    noStroke();
    beginShape(); 
    vertex(0, 200);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t), 0,1, 30, 200);
        vertex(x, y);    
    }
    vertex(width, 200);   
    endShape();
}

function drawSnow() {
    var xS = 10;
    var yS;
    for (var i = 0; i < 50; i++) {
        yS = 0;
        for (var j = 0; j < 25; j++){
            stroke(255);
            strokeWeight(0.5);
            //noStroke();
            ellipse(xS, yS, 2);
            line(xS - 3, yS - 3, xS + 3, yS + 3);
            line(xS + 3, yS - 3, xS - 3, yS + 3);
            line(xS, yS - 3, xS, yS + 3);
            yS += random(10, 20);
        }
        xS += random(8, 25);    
    }
}

    
// DRAW THE CHRISTMAS TREE
function updateAndDisplayTrees() {
    // Update the tree's positions, and display them.
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function addNewTreesWithSomeRandomProbability() {
    // With a very tiny probability, add a new tree to the end.
    var newTreeLikelihood = 0.1; 
    if (random(0,1) < newTreeLikelihood) {
        var theX = random(20, width-20);
        trees.push( makeTree(theX,0) );
    }
}


// method to update position of tree every frame
function treeMove() {
    this.y += this.speed;
}
    

// draw the tree and some ornaments
function treeDisplay() { 
    stroke(0); 
    push();
    translate(this.x, this.y);
    // tree
    strokeWeight(0.5);
    fill(0, 102, 51);
    triangle(0, this.y + 30, this.breadth / 2, this.y, this.breadth, this.y + 30); 
    fill(108,22,22)
    rect(this.breadth / 2 - 5, this.y + 30, 10, this.treeH / 3);
    // ornaments
    var x0 = this.breadth / 6;
    for (var i = 0; i < 5; i++){
        fill(255, 0, 0);
        ellipse(x0, this.y + 25, 5);
        x0 += this.breadth / 6;
    }
    pop();
}


function makeTree(birthLocationX, birthLocationY) {
    var tree = {x: birthLocationX, 
                y: birthLocationY,
                breadth: 30,
                speed: 2.0,
                treeH: 10,
                move: treeMove,
                display: treeDisplay}

    return tree;
}

// DRAW THE SNOWMAN
function updateAndDisplaySM() {
    // Update the tree's positions, and display them.
    for (var i = 0; i < snowmen.length; i++){
        snowmen[i].move();
        snowmen[i].display();
    }
}

function addNewSMWithSomeRandomProbability() {
    // With a very tiny probability, add a new tree to the end.
    var newSMLikelihood = 0.1; 
    if (random(0, 1) < newSMLikelihood) {
        var theX = random(20, width - 20);
        snowmen.push(makeSnowman(theX,0));
    }
}


// method to update position of sm every frame
function smMove() {
    this.y += this.speed;
}
    

// draw the snowman 
function smDisplay() { 
    stroke(0); 
    push();
    translate(this.x, this.y);
    // tree
    fill(245);
    strokeWeight(0.8);
    ellipse(this.x, this.y + 8, 13);
    ellipse(this.x, this.y, 8);
    // ornaments
    fill(255, 0, 0); // the hat
    triangle(this.x - 2, this.y - 4, this.x, this.y - 7, this.x + 2, this.y - 4);
    fill(0); // eyes
    ellipse(this.x - 2, this.y, 1);
    ellipse(this.x + 2, this.y, 1);
    fill(255, 128, 0);
    triangle(this.x - 1, this.y + 2, this.x + 1, this.y + 2, this.x, this.y + 6);
    pop();
}


function makeSnowman(birthLocationX, birthLocationY) {
    var snowman = {x: birthLocationX, 
                y: birthLocationY,
                speed: 2.0,
                move: smMove, 
                display: smDisplay}

    return snowman;
}

// Draw the soil 
function displayHorizon(){
    stroke(0);
    fill(0, 51, 102);
    rect (0, height - 40, width, 40);
}

// Interaction with user
function mousePressed() {
    // button to play the music
    if (mouseX < 20 & mouseY < 30 && mouseY > 10) {
        playMusic = !playMusic;
    }
    if ( playMusic == false ) {
        for (var i = 0; i < songs.length; i++ ){
            if (songs[i].isPlaying()) {
                songs[i].stop();
            }
        }
    } else {
        songs[floor(random(1,5))].play();
    }
 

    // button to add more Christmas trees or snowmen
    if (mouseX > width-20 & mouseX < width && mouseY < 30 && mouseY > 10) {
        var choice = ceil(random(0,2));
        if (choice == 1) {
            trees.push(makeTree(random(20, width - 20),0));
        } else {
            snowmen.push(makeSnowman(random(20, width - 20),0));
        }
    }
    // button to get rid of some Christmas trees or snowmen
    if (mouseX > width-20 & mouseX < width && mouseY < 60 && mouseY > 40) {
        var choice = ceil(random(0,2));
        if (choice == 1) {
            trees.pop(makeTree(random(20,width-20),0));
        } else {
            snowmen.pop(makeSnowman(random(20,width-20),0));
        }

    }
}

My final project is an interactive animation which I try to mimic the Christmas scene. I integrate the use of curve (string art), music and images into this project. The center is a ferris wheel that is coded by curves. The Christmas trees, snowmen and snow are also coded instead of using images. The mountain behind are winter snow mountain.

Instruction:

If you press the music button on the left, it will play a random music. If you click it again, it stops. If you click it again then, it plays next random song. If you press the plus or minus button on the right, there will be more or less Christmas trees or snowmen that are falling from the sky.