Sheenu-Final Project

Because it can’t be viewed properly on WordPress, please download the file.

I was always fascinated in animation ever since I was little and I always wanted to create something that would help introduce people to making animations. I made this so anyone at any age can know or get the idea and possibly get inspired.

SAMPLE:

Instructions:

  1. Adjust your character to your preferred position. Please move the character slowly.
  2. Save the frame
  3. Adjust your character very slightly little by little and save the frame every time
  4. You can view your animation forward and backward by pressing and holding one of the arrow buttons.

sketch
FinalProject-DOWNLOAD

//Sheenu You
//Section E
//sheenuy@andrew.cmu.edu; 
//Final Project

//Initial X and Y coordinates for the Ragdoll Bodyparts 
var charx = 640;
var chary = 380;
var hedx = 640;
var hedy = 220;
var arlx = 640 - 160;
var arly = 380;
var arrx = 640 + 160;
var arry = 380;
var brlx = 640 - 80;
var brly = 650;
var brrx = 640 + 80;
var brry = 650;

//Arrays that register all the X Y coordinates of all the bodyparts
var xb = [];
var yb = [];
var xh = [];
var yh = [];
var xal = [];
var yal = [];
var xar = [];
var yar = [];
var xbl = [];
var ybl = [];
var xbr = [];
var ybr = [];

//Variables that track animation frames
var frameNumber = -1;
var frames = 0;

//Variables that test if functions are running. 
var initialized = 0;
var forward = 0;
var backward = 0;

function setup() {
    createCanvas(1280, 720);
    background(220);
    frameRate(24);
}

function draw() {
    noStroke();
	
    //Controls drawing of buttons
    var playing = 0;
    var blockyMath = 100;
    var distance = 150;

    background(255, 245, 195);

    body();

    fill(124, 120, 106);
    textSize(20);
    text("FRAMES: " + frames, 5, 20);

    //Draws NewFrame Button
    fill(252, 223, 135);
    rect(width/2 - 10, 80 + 10, 180, 100);
    fill(141, 205, 193);
    rect(width/2, 80, 180, 100);
	
    //Draws Play/Stop Button
    fill(252, 223, 135);
    rect((width/2) - distance - 10, 80 + 10, blockyMath, blockyMath);
    fill(235, 110, 68);
    rect((width/2) - distance, 80, blockyMath, blockyMath);
	
    //Fills triangle if one frame is made 
    if (frames >= 1){
        fill(255);
	} else { 
        fill(231, 80, 29);
	}
    triangle((width/2) - distance + 40, 40, (width/2) - distance + 40, 120, (width/2) - distance - 40, 80);
    push();
        fill(255);
        textSize(30);
        text("ADD", 610, 75);
        text("FRAME", 590, 110);
    pop();
	
	//Draws Rewind/Stop Button
    fill(252, 223, 135);
    rect((width/2) + distance - 10, 80 + 10, blockyMath, blockyMath);
    fill(211, 227, 151);
    rect((width/2) + distance, 80, blockyMath, blockyMath);
    if (frames >= 1){
        fill(255);
    } else { 
        fill(182, 204, 104);
    }
    triangle((width/2) + distance - 40, 40, (width/2) + distance - 40, 120, (width/2) + distance + 40, 80);
	
	//PLAY/Stop Button Functions-Cycles forward through frames if mouse is pressing the button 
    if (mouseX >= ((width/2) + distance - blockyMath/2) & mouseX <= ((width/2) + 
        distance + blockyMath/2) && mouseY >= 30 && mouseY <= 135 && mouseIsPressed && frames >= 1){
        frameNumber += 1
		//Cycles through all arrays
        charx = xb[frameNumber];
        chary = yb[frameNumber];

        hedx = xh[frameNumber];
        hedy = yh[frameNumber];

        arlx = xal[frameNumber];
        arly = yal[frameNumber];

        arrx = xar[frameNumber];
        arry = yar[frameNumber];

        brlx = xbl[frameNumber];
        brly = ybl[frameNumber];

        brrx = xbr[frameNumber];
        brry = ybr[frameNumber];

        playing = 1;
        initialized = 1;
        forward = 1;
		//Goes back to latest frame when mouse is released.
    } else if (forward == 1){
        frameNumber =xb.length - 1
        playing = 0;
        initialized = 0;
        forward = 0;
    }

	//REWIND/Stop Button Functions-Cycles backward through frames if mouse is pressing the button 
    if (mouseX >= ((width/2) - distance - blockyMath/2) & mouseX <= ((width/2) - distance + 
        blockyMath/2) && mouseY >= 30 && mouseY <= 135 && mouseIsPressed && frames >= 1){
        frameNumber -= 1;
		//Cycles through all arrays
        charx = xb[frameNumber];
        chary = yb[frameNumber];

        hedx = xh[frameNumber];
        hedy = yh[frameNumber];

        arlx = xal[frameNumber];
        arly = yal[frameNumber];

        arrx = xar[frameNumber];
        arry = yar[frameNumber];

        brlx = xbl[frameNumber];
        brly = ybl[frameNumber];

        brrx = xbr[frameNumber];
        brry = ybr[frameNumber];
        initialized = 1;
        playing = 1;
        backward = 1;
		//Goes back to latest frame when mouse is released.
    } else if (backward == 1){
        frameNumber = xb.length - 1
        playing = 0;
        initialized = 0;
        backward = 0;
    }

	//Allows frames to loop when animation is going forward
    if (frameNumber >= xb.length - 1 & playing == 1 && forward == 1){
        frameNumber = -1;
    }
	//Allows frame to loop when animation is going backward
    if (frameNumber <= 0 & backward == 1 && playing == 1){
        frameNumber = xb.length;
    }

}

//Draws Ragdoll 
function body(){
	
	//Shadow
    fill(252, 223, 135);
    ellipse(charx, 670, (chary/2) + 100, 30);
	
	//Ligaments
    //Neck
    push();
    stroke(249, 213, 151);
    strokeWeight(30);
    line(charx, chary - 80, hedx, hedy);
    stroke(190, 228, 171);
    
    //ArmLeft
    line(charx, chary - 80, arlx, arly);
    
    //ArmRight
    line(charx, chary - 80, arrx, arry);
    stroke(88, 203, 172);
    
    //FootLeft
    line(charx - 20, chary + 70, brlx, brly);
   
    //FootRight
    line(charx + 20, chary + 70, brrx, brry);
    pop();

    noStroke();
    rectMode(CENTER);
    
    //Head 
    fill(249, 213, 151);
    ellipse(hedx, hedy, 100, 100);
    fill(80);
    ellipse(hedx - 10, hedy - 10, 10, 20);
    ellipse(hedx + 10, hedy - 10, 10, 20);
    ellipse(hedx, hedy + 20, 30, 30);
    fill(249, 213, 151);
    ellipse(hedx, hedy + 15, 30, 30);
   
    //Left Arm
    fill(249, 213, 151);
    ellipse(arlx, arly, 50, 50);
  
    //Right Arm
    fill(249, 213, 151);
    ellipse(arrx, arry, 50, 50);
 
    //Left Foot
    fill(112, 47, 53);
    rect(brlx, brly, 50, 50);
  
    //Right Foot
    fill(112, 47, 53);
    rect(brrx, brry, 50, 50);
   
     //Character
    fill(190, 228, 171);
    rect(charx, chary, 100, 200);
    fill(88, 203, 172);
    rect(charx, chary + 50, 100, 100);
    fill(88, 203, 172);
    rect(charx + 30, chary - 50, 20, 100);
    rect(charx - 30, chary - 50, 20, 100);

    //MouseDrag Body
    if (mouseX >= charx - 50 & mouseX <= charx + 50 && mouseY >= chary - 100 && mouseY <= chary + 100 && mouseIsPressed){
        charx = mouseX;
        chary = mouseY;
    }
    //MouseDrag Head
    if (mouseX >= hedx - 50 & mouseX <= hedx + 50 && mouseY >= hedy - 50 && mouseY <= hedy + 50 && mouseIsPressed){
        hedx = mouseX;
        hedy = mouseY;
    } 
    //MouseDrag Left Arm
    if (mouseX >= arlx - 25 & mouseX <= arlx + 25 && mouseY >= arly - 25 && mouseY <= arly + 25&& mouseIsPressed){
        arlx = mouseX;
        arly = mouseY;
    }
    //MouseDrag Right Arm
    if (mouseX >= arrx - 25 & mouseX <= arrx + 25 && mouseY >= arry - 25 && mouseY <= arry + 25 && mouseIsPressed){
        arrx = mouseX;
        arry = mouseY;
    }
    //MouseDrag Left Foot
    if (mouseX >= brlx - 25 & mouseX <= brlx + 25 && mouseY >= brly - 25 && mouseY <= brly + 25 && mouseIsPressed){
        brlx = mouseX;
        brly = mouseY;
    }
    //MouseDrag Right Foot
    if (mouseX >= brrx - 25 & mouseX <= brrx +25 && mouseY >= brry - 25 && mouseY <= brry + 25 && mouseIsPressed){
        brrx = mouseX;
        brry = mouseY;
    }

}
function mousePressed(){
	//Register/records character coordinates to new frame when "New Frame" button is pressed
    if (mouseX >= (width/2) - 90 & mouseX <= (width/2) + 90 && mouseY >= 30 && mouseY <= 135 && mouseIsPressed){
    frameNumber += 1
    frames += 1
	
	//Push character coordinates to x y arrays.
    xb.push(charx);
    yb.push(chary);

    xh.push(hedx);
    yh.push(hedy);

    xal.push(arlx);
    yal.push(arly);

    xar.push(arrx);
    yar.push(arry);

    xbl.push(brlx);
    ybl.push(brly);

    xbr.push(brrx);
    ybr.push(brry);

	//Flash
    background(255, 0, 0, 90);
	}

}
//Resets all body parts to x y coordinates of last frame created when mouse is released
//and cycling is over. 
function mouseReleased(){
    if (initialized == 1){
        charx = xb[xb.length - 1];
        chary = yb[yb.length - 1];

        hedx = xh[xh.length - 1];
        hedy = yh[yh.length - 1];
 
        arlx = xal[xal.length - 1];
        arly = yal[yal.length - 1];

        arrx = xar[xar.length - 1];
        arry = yar[yar.length - 1];

        brlx = xbl[xbl.length - 1];
        brly = ybl[ybl.length - 1];

        brrx = xbr[xbr.length - 1];
        brry = ybr[ybr.length - 1];
    }
}

Because it can’t be viewed properly on WordPress, please download the file.

 

juyeonk – Final Project

For this project I wanted to create a game, but not one of those kinds where you feel anxious and competitive while playing the game.

So I created this game where you can enjoy the winter scenery and a cute dog running while given a bit of an entertainment of being able to move around the dog and its sled to collect the presents.

 

How to:

Use the left/right arrow keys to move around the dog and its sled.

Use the space bar to generate more presents (will be falling from the sky)

NEVER HOLD THE KEY DOWN!!!

The sliding motion of the presents was to re-enact the real time inertia of the objects.

 

sketch

//Claire Koh
//juyeonk@andrew.cmu.edu
//Section E
//Final Project

var frames = []; // An array to store the puppy images
var x = 0; // Variable to draw out an image from the array

var houses = []; // An array to store the house images
var housepics = []; // Array to store the passing by houses

var terrainSpeed = 0.0015;
var terrainDetail = 0.01;
var stars = []; // Array to store the snowflakes

var puppyX = 270; // Initial x position of the puppy
var puppyY = 330; // Initial y position of the puppy (remains the same throughout)

var presents = []; //Array to store the newly created presents



function setup() {
    createCanvas(600, 426);
    frameRate(13)
    // Creates the snowflakes at the beginning
    for (var g = 0; g < 150; g ++) {
        var ry = random(width);
        stars[g] = makeStar(ry);
    }
    
    // Creates the houses at the beginning
    var x = 0;
    for(var i = 0; i < 4; i++) {
        var newHouse = new House();
        newHouse.image = housepics[i];
        newHouse.x = x;
        if(i == 2) {
            newHouse.width = 300;
            newHouse.y = 120;
        }
        x += 300;
        houses.push(newHouse);
    }
    
    
    // Creates the presents at the beginning
    for (i = 0; i <= width; i +=40) {
        presents.push(new Present());
    }
}
 
 
function preload(){
    
    var filenames = [];
    filenames[0] = "https://i.imgur.com/Dv85eeW.png";
    filenames[1] = "https://i.imgur.com/kRjE8sW.png";
    filenames[2] = "https://i.imgur.com/AZLU597.png";
    filenames[3] = "https://i.imgur.com/8wakuK8.png";
    filenames[4] = "https://i.imgur.com/7mD1cW9.png";
    filenames[5] = "https://i.imgur.com/tqUCgkx.png";
    filenames[6] = "https://i.imgur.com/yQ4WaYh.png";
    
    //Loads the images into the frames[] array
    for (var i = 0; i < filenames.length; i ++) {
        frames[i]= loadImage(filenames[i]);
    }

    
    var housepic =[];
    housepic[0] = "https://i.imgur.com/RNMEypc.png";
    housepic[1] = "https://i.imgur.com/NgL94xZ.png";
    housepic[2] = "https://i.imgur.com/TRsZkpd.png";
    housepic[3] = "https://i.imgur.com/X6qFGHM.png";
    housepic[4] = "https://i.imgur.com/TKd1cpX.png";
    housepic[5] = "https://i.imgur.com/uVz8Spc.png";

    // Loads teh images into the housepics[] array
    for (var j = 0; j < housepic.length; j ++) {
        housepics[j] = loadImage(housepic[j]);
    }
}
    


function draw() {
    background(200);
    
    var sky1 = color(27, 36, 49);
    var sky2 = color(30, 55, 92);
   

    for (var c = 0; c <= height; c += 1) {
        var amt = map(c, 0, height/2, 0, 1);
        var skygradient1 = lerpColor(sky1, sky2, amt);
        noStroke();
        fill(skygradient1);
        rect(0, c, width, 1);
    }
        
    
    for (var i = houses.length-1; i>=0; i--){
        houses[i].render();
        houses[i].move();  
    }
    
    createHillShadow();
    createHill();
    
    //SLED
    stroke(0);
    strokeWeight(1);
    line(puppyX-10, puppyY+68, puppyX+25, puppyY+50)
    push();
    noStroke();
    
    fill(112, 100, 35);
    ellipse(puppyX-10, puppyY+68, 8);
    
    strokeWeight(8);
    stroke(112,100,35);
    
    line(puppyX-100, puppyY+50, puppyX-80, puppyY+67.5);
    
    noStroke();
    rect(puppyX-80, puppyY+64, 70, 8);
    pop();
    
    
    
    //PUPPY
    image(frames[x], puppyX, puppyY, 90, 90);
        x += 1;
            if (x > 6) {
                x = 0;
            } 
     
    for (var i = 0; i < presents.length; i++) {
        presents[i].draw();
        presents[i].move();
        presents[i].update();
    }
    
    //SNOW
    updateAndDisplayStars();
    removeStarsThatHaveSlippedOutOfView();
    addNewStarsWithSomeRandomProbability();
    
    
    //INSTRUCTIONS
    push();
    if (frameCount < 50) {
        fill(255);
        textAlign(CENTER);
        text("Use left/right arrow keys to move the puppy", width/2, height/2 - 40)
        text("Press the spacebar to generate more presents", width/2, height/2 - 20)
        text("Try to collect as many presents as you want but you don't have to!", width/2, height/2)
    pop();
    }
    

}



// Function to create the presents
function Present() {
    this.x = random(width);
    this.y = -50;
    this.width = this.height = 20;
    this.velocity = random(1,5);
    this.R = random(100,255);
    this.G = random(100, 255);
    this.B = random(100, 255);
    this.w = -20
    this.draw = function() {
        noStroke();
        fill(this.R,this.G,this.B,200)
        rect(this.x, this.y, this.width, this.height);
        push();
        stroke(255);
        line(this.x, this.y+10, this.x + this.width, this.y + 10)
        line(this.x + 10, this.y, this.x + 10, this.y + this.width)
        pop();
    }
    
    this.move = function() {
        this.y += this.velocity;
        
    }
    
    this.update = function() {
        if (this.y >= height-52 & this.y <= height && abs((puppyX-50)-this.x) < 40) {
            this.y = height-52;
            this.velocity = 0;
        }
        if (keyIsDown(LEFT_ARROW) & this.velocity == 0) {
            this.x -= 10;
        }
        
        if (keyIsDown(RIGHT_ARROW) & this.velocity == 0) {
            this.x += 10;
        }
    }        
}



function keyPressed(){
    // Generates more presents
    if (keyCode === 32) {
        for (i = 0; i <= width; i +=40) {
            presents.push(new Present());
        }
    }
    // Moves the puppy with the left/right arrow keys
    if (keyCode === LEFT_ARROW) {
        puppyX -= 10;
        if (Present.velocity == 0) {
            presents[i].x -= 10;
        }
    }
    if (keyCode === RIGHT_ARROW) {
        puppyX += 10;
        if (Present.velocity == 0) {
            presents[i].x += 10
        }
    }
    
    
}




// Draws House 
function House(){
    this.x = width;
    this.y = 180;
    this.width = 200;
    this.speed = 6;
    this.image;

    this.render = function(){
        image(this.image,this.x, this.y, this.width, this.width);
    }
    
    this.move = function(){
        this.x -= this.speed;
        if (this.x < -200) {
            this.x = width + 100;
        }
     
        this.remove = function() {
            if (this.x < -150) {
                return true;
            } 
            else {
                return false;
            }
        }
    }
}



//BACKGROUND ELEMENTS

// Draws the snowflakes
function updateAndDisplayStars(){
    // Update the lantern's positions, and display them.
    for (var i = 0; i < stars.length; i++){
        stars[i].move();
        stars[i].display();
    }
}


function removeStarsThatHaveSlippedOutOfView(){
    var starsToKeep = [];
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x> 0) {
            starsToKeep.push(stars[i]);
        }
    }
    stars = starsToKeep;
}


function addNewStarsWithSomeRandomProbability() {
    // With some possibility, add new snowflakes
    var newStarLikelihood = 0.8;  
    if (random(0,1) < newStarLikelihood) {
        stars.push(makeStar(width));
    }
}


// Makes the snowflakes move
function starMove() {
    this.x -= this.speed*1.2;
}
    

// Draws the snowflakes
function starDisplay() {
    noStroke()
    fill(255, this.transparency);
    ellipse(this.breadth, this.x, this.size)
}


function makeStar(birthLocationX) {
    var star = {x: birthLocationX,
                y: random(10,70),
                breadth: random(width),
                breadthy: random(height),
                speed: random(0.1,4),
                move: starMove,
                display: starDisplay,
                size: random(2,7),
                transparency: random(150, 255)
               }
    return star;
}



// Creates the shadow of the hill
function createHillShadow() {
    var noiseScale = 0.001;
    var forestDetail = 0.0005;
    var forestSpeed = 0.0005;

    for (var g = 0; g < width; g++) {
        h = (g * forestDetail * 7 + millis() * forestSpeed/8);
        i = map(noise(h), 0, 1, 40, 100);
           stroke(30,70);
           line(g, i+200, g, height-80);
    }  
}


// Creates the hill
function createHill() {
    var noiseScale = 0.001;
    var forestDetail = 0.0005;
    var forestSpeed = 0.0005;

    for (var g = 0; g < width; g++) {
        h = (g * forestDetail * 8 + millis() * forestSpeed/4);
        i = map(noise(h), 0, 1, 40, 100);
           stroke(255);
           line(g, i+250, g, height);
    }  
}




ifv Final Project

sketch

//Isabelle Vincent
//ifv@andrew.cmu.edu
//Section E
//Final Project

var bigs;
var littles;
var algaes;
var foods;
var l;
var littleFish;
var bigFish;
var algae;
var lilypad;
var title;
var state = "title";



function preload() {
  title = loadImage('https://i.imgur.com/aebxPZS.png');
  algae = loadImage("https://i.imgur.com/qnqf1gs.png");
  lilypad = loadImage("https://i.imgur.com/3bfrSSw.png");
  littleFish = loadAnimation('https://i.imgur.com/AUq3ML3.png', 'https://i.imgur.com/1z3PLA8.png', 'https://i.imgur.com/Pxw05Sj.png', 'https://i.imgur.com/yA0uKGs.png', 'https://i.imgur.com/dnUjjsr.png', 'https://i.imgur.com/vprw1op.png', 'https://i.imgur.com/u9dgtas.png', 'https://i.imgur.com/tV1RxJZ.png');
  bigFish = loadAnimation('https://i.imgur.com/zqn5YLQ.png', 'https://i.imgur.com/GSV79Mw.png', 'https://i.imgur.com/oh8VzDx.png', 'https://i.imgur.com/RRiwPTC.png', 'https://i.imgur.com/nswooQs.png', 'https://i.imgur.com/w95esvz.png', 'https://i.imgur.com/uPy62tp.png', 'https://i.imgur.com/uHA6DaY.png');
}


function setup() {
  createCanvas(800, 400);
  //looping fish animations
  littleFish.looping = true;
  bigFish.looping = true;
  i = 1;
  //start out on title screen
   if(state == "title"){
    imageMode(CORNER);
    image(title,0,0);
  }

  //create empty groups
  bigs = new Group();
  littles = new Group();
  algaes = new Group();
  foods = new Group();

  //assign new sprites to groups
  for (var i = 0; i < 6; i++) {
    //i put all the creation and initialization instructions in a function I created
    createbig(random(0, width), random(0, height));
  }
}


function draw() {
  if(state == "gameplay"){
  //the more algae there is the darker the bg is
  var q = algaes.length * 20
  var c = color(136-q, 180-q, 136-q);
  background(c);
  textSize(20);
  fill(210, 239, 220);
  text("Click to feed fish, if you dont there will be no more fish",10,30);

  //spawn a algae randomly
  if (frameCount % 40 == 0 & algaes.length < 4 && bigs.length > 3) {
    createAlgae(random(0, width), random(0, height));
  }

  //create a new little fish every 60 frames if there are less than 20 little fish
  if (frameCount % 60 == 0 & littles.length < 20) {

    var side = floor(random(0, 4));

    if (side == 0) //left
      createlittle(0, random(height));
    if (side == 1) //right
      createlittle(width, random(height));
    if (side == 2) //top
      createlittle(random(width), 0);
    if (side == 3) //bottom
      createlittle(random(width), height);

  }

  for (var i = 0; i < algaes.length; i++) {
    var a = algaes[i];
    for (var j = 0; j < bigs.length; j++) {
      var b = bigs[j];
      a.overlap(bigs, algaeTouchesBig);
    }
  }


  //go through the bigs - they wander randomly
  for (var i = 0; i < bigs.length; i++) {

    //way to store fish position
    var b = bigs[i];
    
    b.noisePosition += 0.1;
    b.rotation += (noise(b.noisePosition) - 0.5) * 10;

    //set the velocity based on the new rotation
    b.setSpeed(2, b.rotation);
    
    //check all the bigs,
    for (var j = 0; j < foods.length; j++) {

      var f = foods[j]; //same as above

      var distance = p5.Vector.dist(b.position, f.position);

      //if they are closer make them attract
      if (distance < 500) {
        //find angle between the two
        var angle = degrees(atan2(f.position.y - b.position.y, f.position.x - b.position.x));
        //attraction inverseley proportional to distance
        var attraction = 200 / distance;
        b.addSpeed(attraction, angle);
        b.overlap(foods, BigTouchesFood);
      }
    }
    wrapAroundScreen(b);
  }

  //go through the littles group -
  //they go straight until they get close to bigs
  littles.bounce(bigs);
  bigs.bounce(bigs);
  for (var i = 0; i < littles.length; i++) {
    var l = littles[i]; //save in a temp variable
    l.overlap(algaes, littleTouchesAlgae);
    wrapAroundScreen(l);
  }


  //don't forget to draw all the sprites
  drawSprites();
}
}

//click mouse to feed fish
function mousePressed() {
  for (var i = 0; i < random(3, 5); i++) {
    createFood(mouseX, mouseY);
  }
}

//checks if a sprite is outside of the screen and teleports it on the other side
function wrapAroundScreen(s) {
  //wrap around the screen
  if (s.position.x > width + 20)
    s.position.x = 0;
  if (s.position.x < -20)
    s.position.x = width;
  if (s.position.y > height + 20)
    s.position.y = 0;
  if (s.position.y < -20)
    s.position.y = height;
}
//if little fish touches algae a new little fish is made and algae destroyed
function littleTouchesAlgae(little, algae) {
  algae.remove();
  createlittle(little.position.x, little.position.y);
}
//If algae and Big fish touch big fish disappear
function algaeTouchesBig(algae, big) {
  big.remove();
}
//If Big Fish touches food a new fish is created at a semi-random size
function BigTouchesFood(big, food) {
  food.remove();
  push()
  big.scale = random(0.5, 0.7);
  createbig(big.position.x, big.position.y);
  pop();
}


//function to create Big fish & add to group
function createbig(x, y) {

  var b = createSprite(x, y);

  b.addAnimation("big", bigFish);

  b.velocity.y += random(-2, 2);
  b.velocity.x += random(-2, 2);
  b.scale = 0.5;
  b.mass = b.scale;
  b.setCollider("spiral", -2, 2, 55);

  //use to generate the noise wandering
  b.noisePosition = random(0, 1000);
  //image rotates toward the direction
  b.rotateToDirection = true;

  b.maxSpeed = 2;

  bigs.add(b);

}

//function to create little fish & add to group
function createlittle(x, y) {
  var l = createSprite(x, y);
  l.addAnimation("little", littleFish);

  //set a random speed
  l.setSpeed(2, random(0, 360));
  l.scale = random(0.3, 0.7);
  //slower speed than bigs so they will never stick to them
  l.maxSpeed = 1.8;
  l.mass = l.scale;
  l.setCollider("spiral", -2, 2, 55);
  l.life = 500;
  //image rotates toward the direction
  l.rotateToDirection = true;
  littles.add(l);

}

//function to create food particles & add to group
function createFood(x, y) {
  var f = createSprite(x, y);
  f.scale = 0.4;
  f.addAnimation("food", "https://i.imgur.com/FTsnjxr.png");
  f.velocity.y += random(-2, 2);
  f.velocity.x += random(-2, 2);
  foods.add(f);
}
//function to create algae & add to group
function createAlgae(x, y) {
  var a = createSprite(x, y);
  a.addAnimation("algae", "https://i.imgur.com/qnqf1gs.png");
  a.life = 800;
  algaes.add(a);
}

//start game after spacebar pressed by changing the state
function keyPressed() {
  if (state === "title" & keyCode === 32) {
    state = "gameplay";
  }
}

 

This Project is a small ecosystem that is reliant on user interaction for it the eco system to flourish. Unfortunately I wasn’t able to take this project to the level I originally wanted to but coding with a different library was a learning experience for me.

agusman_adev_Final_Project

sketch

var angle = 0; //tree branch angle
var mic; //internal microphone
var forest = []; //holds trees
var iInc; //branch incriment
var ns = 10; //stars
var p; //moon curve variable
var q; //moon curve variable
var curveSize; //moon curve constraint

function setup() {
	createCanvas(480, 280);
	background(51);

	mic = new p5.AudioIn(); //create mic
	mic.start(); //activate mic

	//push 3 trees into array
	var tree1 = new Branch(87,10);
	forest.push(tree1);
	var tree2 = new Branch(70,70);
	forest.push(tree2);
	var tree3 = new Branch(40, 300);
	forest.push(tree3);

	flock = new Flock();

	//creating and pushing stars into an array
	for (var i = 0; i < ns; i++) {
		var p = makeStar(-10, -10,random(-50, 50), random(-50, 50));
		stars.push(p);
	}

	frameRate(10);

}

function draw() {
	background(51, 7.5);
	stroke(255,5);

	//get volume from mic (trees, stars, moon)
	var micLevel = mic.getLevel()*200;
	angle = micLevel/40;
	
	//call the function
	flock.run();

	//get volume from mic (flowy energy)
	var vol = mic.getLevel()*15;

		//if the volume is above a certain threshold, add a new flock of boids to the scene
		if (vol > 2) {
		flock.addBoid(new Boid(0, height/2)); 
		}
   
	pop(); 
	background(51,51,51,255*.2); //redrawing the background to give ghostly layering effect

		//Trees
		for(var i = 0; i < forest.length; i++){ //create multiple trees
			push();
			var xPos = forest[i].x;
			translate(xPos, height);
			forest[i].display();
			pop();
		}

		//Stars
		//if the volume exceeds a certain threshold, new stars are drawn
		if (micLevel > 10) {
			var newS = makeStar(random(10, width), random(10, height/3*2), random(-0.5, 0.5), random(-0.5, 0.5));
			stars.push(newS);
		}

		//store newly created stars
	 	newStars = []; 
		for (var i = 0; i < stars.length; i++) {
			var p = stars[i];
			p.draw();
			
			if (p.age < 200) {
				newStars.push(p);
			}
		}
   
	stars = newStars;

	//Moon
   
   	//map volume threshold to moon curve formula
	p = map (micLevel, 0, 100, 0, 100); 
	q = map (micLevel, 0, 100, 0, 130);

	curveSize = map (micLevel, 0, width, 20, 20);

	//curve formula 
	var k = p/q;
	push();
	translate (380, 70);
	iInc = map (micLevel, 0, height, 0.05, 1.5); 

		for (var i = 0; i < TWO_PI * q ; i+= iInc*1.2) {
		var r = curveSize * cos (k*i);
		var x = r * cos(i);
		var y = r * sin(i);
		fill(189, 207 , 253, 10);
		strokeWeight(iInc*5);
		point (x, y);
		fill(255);
	}  
}

//Completing the tree objects
function Branch(len, xTrans){
	this.originalTall = len;
	this.x = xTrans;
	
	this.display = function(){
		push();
		translate(50);
		branching(this.originalTall);
		pop();
	}
	
}

//Making the recursive tree
function branching(len){
	line(0,0,0,-len);
	translate(0,-len);
	stroke(255);
	if(len > 4) {
		push();
		rotate(angle);
		branching(len * 0.67);
		pop();

		push();
		rotate(-angle);
		branching(len * 0.67);
		pop();
	}
}

//Making the stars
function starDraw() {
	fill(255);
	point(this.x + random (0.1, -0.1), this.y + random(-0.1, 0.1));
}

//create the star
function makeStar(sx, sy) {
	p = {x: sx +random(-0.1, 0.1), y: sy + (-0.1, 0.1),
		 age: 0,
		 draw: starDraw
		}
	return p;
}

var stars = [];

// Starting here:
// Flocking Behavior algorithm sampled from Daniel Shiffman, "The Nature of Code" 
// http://natureofcode.com

function Flock() {
  // An array for all the boids
  this.boids = []; // Initialize boids array
}

Flock.prototype.run = function() {
  for (var i = 0; i < this.boids.length; i++) {
	this.boids[i].run(this.boids);  // Passing the entire list of boids to each boid individually
  }
}

Flock.prototype.addBoid = function(b) {
  this.boids.push(b); //
}

// Separation, Cohesion, and Alignment forces added

//defining the boid object
function Boid(x,y) {
  this.acceleration = createVector(0,0);
  this.velocity = createVector(random(-1,1),random(-1,1));
  this.position = createVector(x,y);
  this.r = 3.0; //radius of boid
  this.maxspeed = 2;    // Maximum speed
  this.maxforce = 0.05; // Maximum steering force

// Starting here:
// Our own original code

  var rr = random(70, 90); 
  var gg = random(70, 90); 
  var bb = random(80, 100); 
  this.rcolor = rr; 
  this.gcolor = gg; 
  this.bcolor = bb; 

  // Keep track of old x y coordinates of boid
  this.history = []; 
}

// Our own original code
// Ending here:

// Continuing here:
// Flocking Behavior algorithm sampled from Daniel Shiffman, "The Nature of Code" 
// http://natureofcode.com

Boid.prototype.run = function(boids) {
  this.flock(boids);
  this.update();
  this.borders();
  this.render();
}

Boid.prototype.applyForce = function(force) {
  this.acceleration.add(force);
}

// We accumulate a new acceleration each time based on three rules
Boid.prototype.flock = function(boids) {
  var sep = this.separate(boids);   // Separation
  var ali = this.align(boids);      // Alignment
  var coh = this.cohesion(boids);   // Cohesion

  // Arbitrarily weight these forces
  sep.mult(1.5);
  ali.mult(1.0);
  coh.mult(1.0);
  
  // Add the force vectors to acceleration
  this.applyForce(sep);
  this.applyForce(ali);
  this.applyForce(coh);
}

// Method to update location
Boid.prototype.update = function() {
  // Update velocity
  this.velocity.add(this.acceleration);
  // Limit speed
  this.velocity.limit(this.maxspeed);
  this.position.add(this.velocity);

  // update the property that stores old positions
  var v = [this.position.x, this.position.y]; //AG
  this.history.push(v); //AG

  // Reset accelertion to 0 each cycle
  this.acceleration.mult(0);
}

// A method that calculates and applies a steering force towards a target
// STEER = DESIRED MINUS VELOCITY
Boid.prototype.seek = function(target) {
  var desired = p5.Vector.sub(target,this.position);  // A vector pointing from the location to the target
  // Normalize desired and scale to maximum speed
  desired.normalize();
  desired.mult(this.maxspeed);
  // Steering = Desired minus Velocity
  var steer = p5.Vector.sub(desired,this.velocity);
  steer.limit(this.maxforce);  // Limit to maximum steering force
  return steer;
}

//Starting Here:
//Heavily modified perameters by us

Boid.prototype.render = function() {
  // Draw a triangle rotated in the direction of velocity
  var theta = this.velocity.heading() + radians(90);
  noFill();
  noStroke();
  push();
  translate(this.position.x,this.position.y);
  rotate(theta);
  beginShape();
  vertex(0, -this.r);
  vertex(-this.r, this.r*6); //boid size
  vertex(this.r, this.r*6); //boid size
  endShape(CLOSE);
  pop();

// Starting here:
// Our own original code

	// Displays path of old locations
	for (var i = 0; i < this.history.length; i++) { 
	  var posx = this.history[i][0]; 
	  var posy = this.history[i][1];
	  fill(this.rcolor, this.gcolor, this.bcolor, 90); 
	  ellipse(posx, posy, 5, 5);
	}
}
// Our own original code
// Ending here:

// Starting here:
// Separation, Alignment and Cohesion force algorithms sampled from Daniel Shiffman, "The Nature of Code" 
// http://natureofcode.com

// Border Constraints
Boid.prototype.borders = function() { 
  if (this.position.x < 0) {
	  this.velocity.x = -this.velocity.x; 
  }
  if (this.position.y > height) { 
	  this.velocity.y = -this.velocity.y;
  }
  if (this.history.length > 10) { 
	  this.history.shift(); 
  }
}

// Separation
// Method checks for nearby boids and steers away
Boid.prototype.separate = function(boids) {
  var desiredseparation = 25.0;
  var steer = createVector(0,0);
  var count = 0;

  // For every boid in the system, check if it's too close
  for (var i = 0; i < boids.length; i++) {
	var d = p5.Vector.dist(this.position,boids[i].position);

	// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
	if ((d > 0) & (d < desiredseparation)) {
	  // Calculate vector pointing away from neighbor
	  var diff = p5.Vector.sub(this.position,boids[i].position);
	  diff.normalize();
	  diff.div(d); // Weight by distance
	  steer.add(diff);
	  count++; // Keep track of how many
	}
  }

  // Average -- divide by how many
  if (count > 0) {
	steer.div(count);
  }

  // As long as the vector is greater than 0
  if (steer.mag() > 0) {

	// Implement Reynolds: Steering = Desired - Velocity
	steer.normalize();
	steer.mult(this.maxspeed);
	steer.sub(this.velocity);
	steer.limit(this.maxforce);
  }
  return steer;
}

// Alignment
// For every nearby boid in the system, calculate the average velocity
Boid.prototype.align = function(boids) {
  var neighbordist = 50;
  var sum = createVector(0,0);
  var count = 0;
  for (var i = 0; i < boids.length; i++) {
	var d = p5.Vector.dist(this.position,boids[i].position);
	if ((d > 0) & (d < neighbordist)) {
	  sum.add(boids[i].velocity);
	  count++;
	}
  }
  if (count > 0) {
	sum.div(count);
	sum.normalize();
	sum.mult(this.maxspeed);
	var steer = p5.Vector.sub(sum,this.velocity);
	steer.limit(this.maxforce);
	return steer;
  } else {
	return createVector(0,0);
  }
}

// Cohesion
// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
Boid.prototype.cohesion = function(boids) {
  var neighbordist = 50;
  var sum = createVector(0,0);   // Start with empty vector to accumulate all locations
  var count = 0;
  for (var i = 0; i < boids.length; i++) {
	var d = p5.Vector.dist(this.position,boids[i].position);
	if ((d > 0) & (d < neighbordist)) {
	  sum.add(boids[i].position); // Add location
	  count++;
	}
  }
  if (count > 0) {
	sum.div(count);
	return this.seek(sum);  // Steer towards the location
  } else {
	return createVector(0,0);
  }
}

Anna Gusman and I created a therapeutic garden landscape that grows when it’s sung to. We chose to collaborate on this project because we were both super eager to explore p5’s comprehensive and lauded sound library. We thought that sonic interactions and audiovisual expressions would be great domains to explore by utilizing this tool.

Initially, we brainstormed ways by which people could see themselves “reflected” in a dynamic digital environment. By activating and scaling properties of the internal mic, we could poise the voice of an audience as the actuator of a captivating and therapeutic experience. The scene we designed contains four dynamic elements: recursion, flocking behavior, algorithmic curves and a particle system. Respectively, these would inform the emergence of natural objects like trees, wind, the moon and stars. Each of these dynamic elements are initiated by a singing voice and continue to grow as the viewer continues to sing! While some elements with more exposure to sound multiply, others express continued metamorphosis within themselves.

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

katieche – final project

final project

// BORROWED FROM IRA GREENBERG
var radius = 45, rotAngle = -90;
var accelX = 0.0, accelY = 0.0;
var deltaX = 0.0, deltaY = 0.0;
var springing = 0.0009, damping = 0.98;

//corner nodes
var nodes = 5;

//zero fill arrays
var nodeStartX = [];
var nodeStartY = [];
var nodeX = [];
var nodeY = [];
var angle = [];
var frequency = []; // END OF BORROWED CODE

// array for the rings and boxes
var rings = [];
var boxes = [];

// initializing colors for keypressed changes
var r = 250;
var g = 250;
var b = 250;

var frames = [];

//var score = 0;

function preload() { // loading ring popping animation frames
	var f = [];
		f[0] = "https://i.imgur.com/AZJNy6P.png";
		f[1] = "https://i.imgur.com/coAJvFm.png";
		f[2] = "https://i.imgur.com/Y3RE12y.png";
		f[3] = "https://i.imgur.com/9sTJNBz.png";


		for(var i =0; i < 4; i++){
			frames[i] = loadImage(f[i]);
		}
}


function setup() {
  createCanvas(480, 480);


  // BORROWED FROM IRA GREENBERG: initialize arrays to 0
  for (var i=0; i<nodes; i++){
    nodeStartX[i] = 0;
    nodeStartY[i] = 0;
    nodeY[i] = 0;
    nodeY[i] = 0;
    angle[i] = 0;
  } // END OF BORROWED CODE

  // initializes collection of rings 
  for (var i = 0; i < 3; i++){
    	var ry = random(-300, 0); //rings are falling from above the canvas at random
        rings[i] = makeRing(ry);
        boxes[i] = makeBox(ry);
        }

  // BORROWED FROM IRA GREENBERG: iniitalize frequencies for corner nodes
  for (var i = 0; i < nodes; i++){
    frequency[i] = random(4, 5);
  } // END OF BORROWED CODE

  noStroke();
  frameRate(30);
}

function draw() {
	fill(50);
	rect(0,0,width, height);

	// display rings + boxes
	updateAndDisplayRings();
	ringAdd();

	updateAndDisplayBox();
	boxAdd();

	// for the character
  	drawShape();
  	moveShape();

  	// instructional text
  	text("press 'Q' to eat blue, 'W' to eat pink, 'E' to eat yellow", 180, 450);


}
// CHARACTER
// CODE IS BASED ON IRA GREENBERG'S SOFT BODY EXAMPLE:
// https://p5js.org/examples/simulate-soft-body.html
// HAS BEEN HEAVILY EDITED BY ME
function drawShape() {
  //  calculate node  starting locations
  for (var i=0; i<nodes; i++){
    nodeStartX[i] = mouseX+cos(radians(rotAngle))*radius;
    nodeStartY[i] = mouseY+sin(radians(rotAngle))*radius;
    rotAngle += 360.0/nodes;
  }

  // draw polygon
  curveTightness(0.5); // to create soft body like organic shape
  noStroke();
  fill(r,g,b);
  beginShape();
  // creates a point at each (nodeX, nodeY) for the 5 corners in the array
  for (var i=0; i<nodes; i++){
    curveVertex(nodeX[i], nodeY[i]);
  }
  // to make shape connect all the way around
  for (var i=0; i<nodes-1; i++){
    curveVertex(nodeX[i], nodeY[i]);
  }
  endShape(CLOSE); // END OF BORROWED CODE

  // eyes
  fill(149, 166, 193);
  ellipse(mouseX+30, mouseY, 10, 10);
  ellipse(mouseX-30, mouseY, 10, 10);

  push();
  noFill();
  stroke(149, 166, 193);
  strokeWeight(3);
  ellipse(mouseX+30, mouseY, 15, 15);
  ellipse(mouseX-30, mouseY, 15, 15);
  pop();
}


function moveShape() { // BORROWED FROM IRA GREENBERG
  //move center point
  deltaX = mouseX;
  deltaY = mouseY;

   //create springing effect
  deltaX *= springing;
  deltaY *= springing;
  accelX += deltaX*0.8;
  accelY += deltaY*0.8;

  // slow down springing
  accelX *= damping;
  accelY *= damping;

  //move nodes
  for (var i=0; i<nodes; i++){
    nodeX[i] = nodeStartX[i]+sin(radians(angle[i]))*(accelX);
    nodeY[i] = nodeStartY[i]+sin(radians(angle[i]))*(accelY);
    angle[i] += frequency[i];
  }
} // END OF BORROWED CODE

function keyPressed() { // changes blob's color

    if(keyCode == 81) { // "Q" blue
        r = 202;
        g = 220;
        b = 247;
    }
    if(keyCode == 87) { // "W" pink
        r = 247;
        g = 207;
        b = 207;
    }
    if(keyCode == 69) { // "E" yellow
        r = 255;
        g = 241;
        b = 193;
    }
}

// RINGS
function updateAndDisplayRings(){
    // Update the rings positions, and display them.
    for (var i = 0; i < rings.length; i++){
        rings[i].move();
        rings[i].display();
    }
}


function ringAdd() {
    // With a very tiny probability, add a new ring to the end.
    var newringLikelihood = 0.02; 
    if (random(0,1) < newringLikelihood) {
        rings.push(makeRing(0));
        rings.push(makeRing(0));

    }
}

// moving the rings
function ringMove() {
    this.y += this.speed;

}
    
// drawing the rings
function ringDisplay() {
	noFill();
	stroke(210);
	strokeWeight(2);

	if (dist(mouseX, mouseY, this.x, this.y) <= 50) { // if the mouse is 50 points close to the ring, it pops
		this.isPopped = true;
		this.timePopped = frameCount; // record the framecount at which it pops
	}


	if (this.isPopped == false) { // if the state of the ring is not popped
		ellipse(this.x, this.y, this.diam, this.diam);
	}

	else {
		this.popped(); // if this.isPopped == true, then calls ringPop which displays pop animation

	}


}

function ringPop() { // animating rings popping
	var num = frameCount-this.timePopped;
	if (num >= frames.length) {
		// if num goes past the number of animation frames, the pop dissapears
	}
	
	else {
    image(frames[num], this.x, this.y, 50, 50);
	}
}


// making the rings
function makeRing(cy) {
    var ring = {y: cy,
    			x: random(0,600),
    			diam: random(15,25),
 				speed: random(2.0, 3.0),
                move: ringMove,
                display: ringDisplay,
                isPopped: false,
                popped: ringPop,
                timePopped: -10
            }
    return ring;
}

// SQUARES
function updateAndDisplayBox(){
    // Update the clouds' positions, and display them.
    for (var i = 0; i < boxes.length; i++){
        boxes[i].bmove();
        boxes[i].bdisplay();
    }
}


function boxAdd() {
    // With a very tiny probability, add a new ring to the end.
    var newboxLikelihood = 0.02; 
    if (random(0,1) < newboxLikelihood) {
        boxes.push(makeBox(0));
    }
}

// moving the rings
function boxMove() {
    this.by += this.bspeed;
    this.py += this.pspeed;
    this.yy += this.yspeed;

}
    
// drawing the rings
function boxDisplay() {

	// blue box
	if (dist(mouseX, mouseY, this.bx, this.by) <= 50 & r == 202 && g == 220 && b == 247) { 
	// if the mouse is 50 points close to the box and the blob is blue
		this.bisEaten= true;
	}


	if (this.bisEaten == false) { // if the state of the box is not eaten
		noStroke();
		fill(202, 220, 247);
		rect(this.bx, this.by, this.bs, this.bs, 5);
	}

	else {
	}

	// pink box
	if (dist(mouseX, mouseY, this.px, this.py) <= 50 & r == 247 && g == 207 && b == 207) { 
	// if the mouse is 50 points close to the box and the blob is pink
		this.pisEaten = true;
	}


	if (this.pisEaten == false) { // if the state of the box is not eaten
		noStroke();
		fill(247, 205, 202);
		rect(this.px, this.py, this.bs, this.bs, 5);
	}

	else {
		// box disapears when state is true
	}

	// yellow box
	if (dist(mouseX, mouseY, this.yx, this.yy) <= 50 & r == 255 && g == 241 && b == 193) { 
	// if the mouse is 50 points close to the box and the blob is pink
		this.yisEaten = true;
	}

	if (this.yisEaten == false) { // if the state of the box is not eaten
		noStroke();
		fill(255, 241, 193);
		rect(this.yx, this.yy, this.bs, this.bs, 5);
	}

	else {
		// box disapears when state is true
	}

}

// making the rings
function makeBox(ty) {
    var box = {	// blue box coord
    			by: ty,
    			bx: random(0,600),
    			// pink box coord
    			py: random(0,200),
    			px: random(0,600),
    			// yellow box coord
    			yy: random(0,200),
    			yx: random(0,600),

    			bs: random(20,25),
 				bspeed: random(1.0, 2.0),
 				pspeed: random(1.0, 2.0),
 				yspeed: random(1.0, 2.0),
                bmove: boxMove,
                bdisplay: boxDisplay,

                bisEaten: false, // blue false
                pisEaten: false, // pink false
                yisEaten: false, // yellow false
            }
    return box;
}

For my final project, I wanted to create a game with a fun ambiguous character. In a way, the game is like a fight between an organic shape and geometric shapes. It’s slightly different from my proposal but I like the way it turned out. It uses a modified version of the generative landscape functions, making the terrain (falling objects) fall downwards instead of sideways. It was difficult to modify the code so that the shapes would fall in a way that was relatively even, and not in lines or waves. The character is done using a heavily modified version of the soft body code found on the p5.js examples.

The objective of the game is to clear the screen! The rings pop whenever the character touches them, but the character’s own color must match up with the color of the squares to eat them. To change the character’s color, the player must select Q, W or E on their keyboard.

jwchou-final project-E

For my project, I decided to stay with the theme I had developed throughout the semester with plane-based projects.

The objective of the game is to fly the plane onto the runway while avoiding mountains and lightning. Instructions for running the game are included.

I had a really hard time with this project. My original concept was perhaps more interesting but I had an extremely hard time executing it, so I pivoted my project to this secondary concept at the last minute. However, I had a lot of fun creating it, as well as working on the styling and themes of the splash screens in particular. I hope you enjoy it!

sketch 52

//Jackie Chou
//jwchou@andrew.cmu.edu
//Section E
//Final Project

//stores image variables
var explosion;
var lost;
var crash;
var win;
var beginScreen;
var lightning;
var mountain;
var img;

//variable to determine if the game has started
var gameStarted = false;

//position and speed variables for the plane
var xPos = 240;
var yPos = 0;
var xSpeed = 0;
var ySpeed = 0;

//arrays to store the obstacles in
var mountains = [];
var lightnings = [];


function setup() {
    createCanvas(480, 480);
    //load background and obstacle images
    img = loadImage("https://i.imgur.com/x3rvhGU.png");
    lightning = loadImage("https://i.imgur.com/v6p1ANv.png");
    mountain = loadImage("https://i.imgur.com/tLB1n6D.png");
    explosion = loadImage("https://i.imgur.com/8J62X6Z.png");

    //load splash screens
    lost = loadImage("https://i.imgur.com/znFRmOW.png");
    crash = loadImage("https://i.imgur.com/TXv7bto.png");
    win = loadImage("https://i.imgur.com/T0qvSdh.png");
    beginScreen = loadImage("https://i.imgur.com/J34UN7I.png");
    //pushes random coordinates into the obstacle arrays
    for (i = 0; i < 8; i++) {
        lightnings.push(random(0, width));
        lightnings.push(random(80, 350));
        mountains.push(random(0, width));
        mountains.push(random(80, 350))
    }   
}

function draw() {
    imageMode(CENTER);
    //draws background image
    image(img, 240, 240);
    //initializes plane if the game has begun
    if (gameStarted == true){
        ySpeed = 0.5;
    }
    //controls plane's direction
    yPos += ySpeed; 
    xPos += xSpeed;
    //calls function to draw obstacles
    drawObstacles();
    //displays splash screen before the game starts
    if (gameStarted == false) {
        image(beginScreen, width/2, height/2);
    }
    //drawing the airplane
    fill(240);
    strokeWeight(0.5);
    //wings
    ellipse(xPos, yPos, 70, 11); 
    ellipse(xPos, yPos - 20, 35, 8);
    //horz stabilizer
    fill(108, 190, 225);
    ellipse(xPos, yPos, 17, 45); 
    //fuselage
    ellipse(xPos + 17, yPos + 5, 6, 15); 
    //left engine
    ellipse(xPos - 17, yPos + 5, 6, 15); 
    //right engine
    fill(0);
    ellipse(xPos - 17, yPos + 10, 10, 2); 
    //right propeler
    ellipse(xPos + 17, yPos + 10, 10, 2); 
    //left propeller
    fill(240);
    ellipse(xPos, yPos - 25, 5, 17); 
    //tail
    fill(0);
    beginShape(); 
    //cockpit
    vertex(xPos - 5, yPos + 10);
    vertex(xPos, yPos + 17);
    vertex(xPos + 5, yPos + 10);
    vertex(xPos + 5, yPos + 5);
    vertex(xPos, yPos + 10);
    vertex(xPos - 5, yPos + 5);
    vertex(xPos - 5,yPos +  10);
    endShape(); 
    //checks to see if the plane has collided into lightning
    for (i = 0; i < lightnings.length; i += 2) {
        if (dist(xPos, yPos, lightnings[i], lightnings[i+1]) <= 35) {
            gameOver();
        }   
    }
    //checks to see if the plane has collided in mountains
    for (i = 0; i < mountains.length; i += 2) {
        if (dist(xPos + 3, yPos, mountains[i], mountains[i+1]) <= 38) {
            gameOver();
        }   
    }
    //calls landing function if plane crosses top edge of runway
    if (dist(xPos, yPos, 235, 440) <= 15) {
        xSpeed = 0;
        ySpeed = 0;
        landed();
    }
    //calls lost screen function if plane leaves canvas (x)
    if (xPos <= 10 || xPos >= 470) {
        gotLost();
    }
    //calls lost screen function if plane leaves canvas (y)
    if (yPos >= 470) {
        gotLost();
    }
}

//draws the obstacles using randomized values from the arrays
function drawObstacles() {
    for (i = 0; i < lightnings.length; i += 2) {
        image(lightning, lightnings[i], lightnings[i+1]);
        //image(mountain, random(0, width), random(80, 350));
    }
    for (i = 0; i < mountains.length; i += 2) {
        image(mountain, mountains[i], mountains[i+1]);
    }
}

//controls the direction of the plane via arrow keys
function keyPressed() {
    if (keyCode === RIGHT_ARROW) {
        xSpeed = 0.65;
    }
    if (keyCode === LEFT_ARROW) {
        xSpeed = -0.65;
    }
    if (keyCode === DOWN_ARROW) {
        xSpeed = 0;
    }
}

//starts the game
function mousePressed() {
    gameStarted = true;
}

//game over function, displays splash screen
function gameOver() {
    image(explosion, xPos, yPos - 3);
    image(crash, width/2, height/2);
    noLoop();
}

//plane lost function
function gotLost() {
    image(lost, width/2, height/2);
    noLoop();
}

//plane landed function
function landed() {
    image(win, width/2, height/2);
    noLoop();
}

mstropka Final Project E (FIXED)

sketch

//Name: Max Stropkay
//Andrew ID: mstropka@andrew.cmu.edu
//Section: E
//Final Project

//decalare variables for font, and audio file
var avenir;
var littlewing;

//array to store vehicle objects
var vehicles = [];

//diameter of circles
var diameter;

//store the value of the amplitude of the audio file
var amplitude;

//array to store the strings that make up the lyrics
//of the song
var lyrics = ['little wing', 'well','shes','walking','through',
  'the','clouds','with a', 'circus', 'mind', 'thats','running', 'round',
  'butterflies', 'zebras', 'moonbeams', 'fairytales',
  'thats all', 'she ever', 'thinks about', 'riding with', 'the', 'wind', 'when',
  'Im sad', 'she comes', 'to me', 'with a', 'thousand', 'smiles', 'she',
  'gives to', 'me', 'free','its alright', 'she said', 'its alright', 'take',
  'anything', 'you', 'want', 'from me', 'anything'];

//array to store the times at which the lyrics
//should appear on screen
var times = [34000, 500, 500, 3000, 500, 500, 2000, 200, 300, 3000, 500,
  500, 3000, 1500, 1500, 2000, 3000, 3000, 300, 300, 300, 2000, 4000,
  500, 500, 3000, 500, 500, 2000, 200, 300, 3000, 500,
  500, 3000, 1500, 1500, 2000, 3000, 3000, 300, 300, 2000, 300, 18000];

var word = -1;

//load soundfile and font
function preload() {
  littlewing = loadSound('https://courses.ideate.cmu.edu/15-104/f2017/wp-content/uploads/2017/12/Jimi-Hendrix-Little-Wing.mp3')
  avenir = loadFont("https://s3.us-east-2.amazonaws.com/maxstropkayfinalproject/AvenirNextLTPro-Demi.otf");
}

function setup() {
  createCanvas(1200, 480);
  //play audio file,set volume
  littlewing.play();
  littlewing.setVolume(0.5);
  //set value of amplitude to the amplitude of audio
  amplitude = new p5.Amplitude(.04);
  updateLyrics();

}

function draw() {
  background(51);

  //for every vehicle run behaviors, update, and show
  for (var i = 0; i < vehicles.length; i++){
    var v = vehicles[i];
    v.behaviors();
    v.update();
    v.show();
  }

  //set diameter to be determined by the amplitude
  var level = amplitude.getLevel();
  var volume = map(level, 0, 1, 0, 200);
  diameter = volume;
}

//define Vehicle object
  function Vehicle(x, y) {
    this.pos = createVector(random(0, width), random(0, height));
    this.target = createVector(x, y);
    this.vel = p5.Vector.random2D();
    this.acc = createVector();
    this.r = 10;
    this.color = 255;
    this.maxspeed = 10;
    this.maxforce = 0.5;
  }

  Vehicle.prototype.behaviors = function(f) {
    var arrive = this.arrive(this.target);
    this.applyForce(arrive);
  }

  Vehicle.prototype.applyForce = function(f) {
    this.acc.add(f);
  }
  //move vehicles based on attraction to the
  //target location
  Vehicle.prototype.update = function() {
    this.pos.add(this.vel);
    this.vel.add(this.acc);
    this.acc.mult(0);
    this.r = diameter + 10*(random(0,1));
    this.color = color(diameter*random(0, 100), diameter*random(0, 5), diameter*random(0, 10));
  }
  //draw ellipses at x,y coordinates of objects
  Vehicle.prototype.show = function() {
    noStroke();
    fill(this.color);
    ellipse(this.pos.x, this.pos.y, this.r, this.r);
  }
  //change speed of object as it gets closer to
  //its target location
  Vehicle.prototype.arrive = function(target) {
    var desired = p5.Vector.sub(target, this.pos);
    var d = desired.mag();
    var speed = this.maxspeed;
    if (d < 100){
      var speed = map(d, 0, 100, 0, this.maxspeed);
    }
    desired.setMag(speed);
    var steer = p5.Vector.sub(desired, this.vel);
    steer.limit(this.maxforce);
    return steer;

  }
  //move object toward its desired position
  Vehicle.prototype.seek = function(target) {
    var desired = p5.Vector.sub(target, this.pos);
    desired.setMag(this.maxspeed);
    var steer = p5.Vector.sub(desired, this.vel);
    steer.limit(this.maxforce);
    return steer;

  }

//display the next word in the array lyrics
//at the time from the time array
function updateLyrics(){
  vehicles = [];
  word = (word + 1) /*% lyrics.length*/;
  print(word);
  textAlign(CENTER);
  textFont("Avenir")
  var points = avenir.textToPoints(lyrics[word], 70, 300, 192);
  //console.log(points)

  for (var i = 0; i < points.length; i++){
    var pt = points[i];
    var vehicle = new Vehicle(pt.x, pt.y);
    vehicles.push(vehicle);
    // stroke(0,255,0);
    // strokeWeight(4);
    // point(pt.x, pt.y);
}
print(times[word]);
setTimeout(updateLyrics,times[word]);

}

For my final project, I made a program that generates dots that change size and color based on the volume of the music thats being played in the background. The dots then fly to form the lyrics in the song. Syncing up the timing of the lyrics and the music was harder and more time consuming than I anticipated, so it only is synced for the first verse.

Attached is the zip file that contains the audio and the font that can be run on a local server.

mstropka_Final Project_E

To run, first open terminal and copy and paste in this line of code

python -m SimpleHTTPServer 8000

This will run a local server. Then type into the URL in your browser

localhost:8000

Then navigate to wherever you downloaded the file and click to run it.

 

 

elizabew-final project

Click on either of the two choices that are available to continue through the story.

(Try the closet route!)

sketch

//calls beginning function to start the game over
var scene = new beginning();

//holds background images
var bg = [];

var bgURL = [
  //outside image
  "https://i.imgur.com/NhThk6g.jpg",
  //lake reflection image
  "https://i.imgur.com/GA10Vet.jpg",
  //image of both lake and forest
  "https://i.imgur.com/c6C6zEC.jpg",
  //cat image
  "https://i.imgur.com/4zrzVTj.jpg",
  //true ending image
  "https://i.imgur.com/LADTQJI.jpg"];

function setup() {
  createCanvas(480, 450);
}

function preload(){
  // load images from URL
  for (i = 0; i < bgURL.length; i++){
    bg.push(loadImage(bgURL[i]));
  }
}

//LIST OF SCENES
function beginning() {
  this.sentence = "You wake up surrounded by complete darkness." +
  " Your body aches and you hear the faint sound of growling behind you." +
  " You pull your red hood around yourself to keep warm." +
  " You feel around and find two doors." +
  " One with a round knob and one of with a square knob.";
  this.left = new sit1();
  this.right = new sitA();
  this.lefttext = "go through the round knobbed door";
  this.righttext = "go through the square knobbed door";
  this.fillcolor = "black";
}

//Round knobbed door
function sit1() {
  this.sentence = "You immediately begin to sprint out the door." +
  " The fresh air hits your face like cold knives. Outside." +
  " You look behind you to hear the growling rumble louder." +
  " She's waking up too.";
  this.left = new sit2();
  this.right = new death("You wait and see what happens." +
  " The beast begins to wake up and it immediately sees you" +
  " She's angry and you know exactly why." +
  " She leaps towards you in a familiar fashion," +
  " mouth wide open and ready to bite down...");
  this.lefttext = "RUN!!!!";
  this.righttext = "Wait and see what happens";
  this.fillcolor = "";
  this.b = "outside";
}

function sit2() {
  this.sentence = "You run away before the beast could notice you leaving." +
  " You see a forest and a lake in the distance";
  this.left = new sitOne();
  this.right = new sit3();
  this.lefttext = "Run towards the forest";
  this.righttext = "Run towards the lake";
  this.fillcolor = "";
  this.b = "treeAndLake"
}

function sit3() {
  this.sentence = "As you run towards the lake," +
  " you stop by the edge of the water," +
  " mesmorized by your own unrecognizable reflection...";
  this.left = new death("You can't help but continue staring at yourself." +
  " Bright blue eyes and a long red cape embracing your frail body." +
  " You hear growling beghind you... GIVE...IT...BACK.... ");
  this.right = new sitThree();
  this.lefttext = "Keep staring at your own reflection";
  this.righttext = "Pull your eyes away and continue running";
  this.fillcolor = "";
  this.b = "reflection"
}

function sitOne(){
  this.sentence = "Start running faster and faster through the forest," +
  " trees flashing past you." +
  " You hear the growling not too far behind...";
  this.left = new death("You climbed up the tree as fast as you could." +
  " Right as you grabbed a second branch," +
  " you feel your hood getting tugged, pulling you down with it...");
  this.right = new sitTwo();
  this.lefttext = "Climb up a tree";
  this.righttext = "Hide in the bushes";
  this.fillcolor = "flashing green";
}

function sitTwo(){
  this.sentence = "You jump into a nearby bush and wait..." +
  " the sound of a frustrated growling felt close," +
  " but it seems to have disappeared now.";
  this.left = new sitThree();
  this.right = new sit3();
  this.lefttext = "Keep running!";
  this.righttext = "Run back towards the lake";
  this.fillcolor = "";
  this.b = "outside";
}

function sitThree(){
  this.sentence = "You decide to keep running." +
  " As you run you trip over a soft rock." +
  " Wait, that's a cat!";
  this.left = new sitFour();
  this.right = new sitFour();
  this.lefttext = "Pet the cat";
  this.righttext = "Scratch the cat's belly";
  this.fillcolor = "";
  this.b = "cat";
}

function sitFour(){
  this.sentence = "The cat purrs and rolls around on the ground." +
  " After a few minutes it gets up.";
  this.left = new sitneutralending();
  this.right = new sitneutralending();
  this.lefttext = "Follow the cat";
  this.righttext = "Why wouldn't you follow this cat?";
  this.fillcolor = "";
  this.b = "cat";
}

//Neutral ending
function sitneutralending(){
  this.sentence = "(Neutral ending) You follow the cat into a small den." +
  " I guess this is a nicer ending."
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "outside";
}

//--------------------
//Square knobbed door
function sitA() {
  this.sentence = "You open the door and find yourself looking into a closet." +
  " You run in and shut the door as quietly as you can." +
  " She's awake now too.";
  this.left = new sitB();
  this.right = new death("You decided to scream on the top of your lungs." +
  " Immediately and without warning, the beast breaks through the closet" +
  " door. Did you have a death wish?");
  this.lefttext = "Stay quiet and hope she leaves";
  this.righttext = "SCREAM!!!";
  this.fillcolor = "black";
}

//Closet scene
function sitB() {
  this.sentence = "You decide to sit quietly in the closet." +
  " After what seemed like hours, the growling disappeared...";
  this.left = new sitC();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Walk out";
  this.fillcolor = "black";
}

function sitC() {
  this.sentence = "You felt uneasy and decided to stay in the closet." +
  " You lean back onto the back of the closet and surprisingly," +
  " you fell into a hole that leads outside!";
  this.left = new sitD();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Crawl outside";
  this.fillcolor = "black";
}

function sitD(){
  this.sentence = "You STILL decide to stay in the closet for some reason." +
  " Maybe you're still feeling uneasy..." +
  " Time continues to pass as it usually does."+
  " Are you even going to continue on this journey?";
  this.left = new sitE();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "CRAWL OUTSIDE";
  this.fillcolor = "black";
}

function sitE(){
  this.sentence = "You still stay in the closet. This is not like the narnia" +
  " wardrobe. There is nothing special about this closet." +
  " Why do you want to stay in here so badly?";
  this.left = new sitF();
  this.right = new sit1A();
  this.lefttext = "Stay in the closet";
  this.righttext = "Crawl. Outside. Now.";
  this.fillcolor = "black";
}

function sitF(){
  this.sentence = "Okay, you've committed, we'll stay in this dumb closet."+
  " I even took away the 'crawl outside' button. I hope you're happy with yourself.";
  this.left = new sitG();
  this.right = new sitG();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitG(){
  this.sentence = "I bet you're happy about this endless loop,"+
  " Even if you change your mind you won't get it back, you're gonna have to" +
  " refresh this whole game manually.";
  this.left = new sitH();
  this.right = new sitH();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitH(){
  this.sentence = "...";
  this.left = new sitI();
  this.right = new sitI();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitI(){
  this.sentence = "..........";
  this.left = new sitJ();
  this.right = new sitJ();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitJ(){
  this.sentence = "..................";
  this.left = new sitK();
  this.right = new sitK();
  this.lefttext = "Stay in the closet";
  this.righttext = "Stay in the closet";
  this.fillcolor = "black";
}

function sitK(){
  this.sentence = "Okay, I'm just going to push you outside. Shoo!";
  this.left = new sit1A();
  this.right = new sit1A();
  this.lefttext = "OUTSIDE";
  this.righttext = "GO. OUTSIDE.";
  this.fillcolor = "black";
}

//To grandmothers house we go!
function sit1A(){
  this.sentence = "You walk outside to see the beast far off in the distance," +
  " obviously looking for you. But you have other plans...";
  this.left = new death("You dance(?) towards the beast flailing about,"+
  " probably hoping to get eaten. (I bet you were the same person wanting to" +
  " stay in that closet...)");
  this.right = new sit1B();
  this.lefttext = "Ignore your plans and dance towards the beast";
  this.righttext = "Head towards the smoke in the nearby forest";
  this.fillcolor = "";
  this.b = "outside";
}

function sit1B(){
  this.sentence = "You run through the forest, to grandmother's house." +
  " She'll protect you from the beast. You hear the beast" +
  " catching up to you, desperate to get what you've stolen back..." +
  " You notice that there is a large pit nearby";
  this.left = new sit1C();
  this.right = new goodishending();
  this.lefttext = "Continue running towards grandmother's house";
  this.righttext = "Wait to push the wolf into the pit";
  this.fillcolor = "flashing green";
}

function sit1C(){
  this.sentence = "You finally reach the door of the house" +
  " The beast is not far behing you. 'GRANDMOTHER' you scream, let me in!" +
  " Hurry!!";
  this.left = new trueending();
  this.right = new death("You decide to keep running, but the beast gets to you." +
  " And you were so close too!");
  this.lefttext = "Wait for grandmother to open the door";
  this.righttext = "Keep running!";
  this.fillcolor = "";
  this.b = "outside";
}

//True ending
function trueending(){
  this.sentence = "(True Ending) Soon after, the door opens." +
  " It's almost impossible to hide your grin..." +
  " You look back at the girl in wolfs skin that was chasing you," +
  " desperate to get her hood back." +
  " 'My, what big teeth you have, little riding hood'!";
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "trueEnd";
}

//Death scene when the beast gets you
function death(sentence) {
  this.sentence = sentence;
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "red";
}

//Good ending where you kill the beast
function goodishending(){
  this.sentence = "(Good Ending) You push the wolf into the pit. Hooray!" +
  " Now nothing is in your way...";
  this.lefttext = "";
  this.righttext = "";
  this.fillcolor = "";
  this.b = "outside";
}

function draw() {

  //Determining background color
  if (scene.fillcolor == "red"){
    background(171,6,11);
  }
  else if (scene.fillcolor == "blue"){
    background(0, 6, 34);
  }
  else if (scene.fillcolor == "flashing green"){
    frameRate(8);
    var r = random(0, 8);
    var g = random(0, 60);
    var b = random(0, 5);
    background(r, g, b);
  }
  else if (scene.fillcolor == "green"){
    background(2, 26, 8);
  }
  else if (scene.fillcolor == "black"){
    background(0);
  }
  else {
    background(0);
  }

  //Creates background images
  if (scene.b == "outside"){
    image(bg[0], 0, 0, 480, 450);
  }
  if (scene.b == "reflection"){
    image(bg[1], 0, 0, 480, 450);
  }
  if (scene.b == "treeAndLake"){
    image(bg[2], 0, 0, 480, 450);
  }
  if (scene.b == "cat"){
    image(bg[3], 0, 0, 480, 450);
  }
  if (scene.b == "trueEnd"){
    image(bg[4], 0, 0, 480, 450);
  }


  //Story text details
  fill(200);
  textSize(12);
  text(scene.sentence, 50, 270, 380, 80);
  //left text decision
  text(scene.lefttext, 50, 380, 100);
  //right text decision
  text(scene.righttext, 300, 380, 100);

  //Reset button text
  if (scene.lefttext == "") {
    text("click here to start over", 180, 370);
  }


}

//Creating "buttons" for choices and for reset
function mouseClicked(){

  //Reset button
  if (scene.lefttext == "") {
    if (mouseX > 180 & mouseX < 300 && mouseY > 360 && mouseY < 380){
       //resets game
       scene = new beginning();
    }
  }

 else{
   //left button decision
   if (mouseX > 50 & mouseX < 130 && mouseY > 370 && mouseY < 420){
     scene = scene.left;
   }
   //right button decision
   if (mouseX > 300 & mouseX < 440 && mouseY > 370 && mouseY < 420){
     scene = scene.right;
   }
 }

}

I decided to create a choose-your-own-adventure game! My initial idea was to focus on having no visuals—using only text and sound to guide the user through the story—but ultimately ended up using both visuals and text together, and just text on its own.

The story was difficult to write in its own right and I don’t claim that it is that good, but the point of this game is that most of the endings the user runs into will build on the story of the game. I decided to focus mainly on using objects (since that was the most difficult part of this class for me and I wanted to make sure I ended this class with the knowledge of how to use them).

gyueunp – Final Project

Final Project

/*
* GyuEun Park
* 15-104 E
* gyueunp@andrew.cmu.edu
* Final Project
*/

var dots = []; //array of dots in beginning scene
var gravity;
var stars = []; //array of stars in ending scene
var speed;
var ismoving = true;

function setup() {
    createCanvas(600, 600);
    background(14, 94, 96);

    //turtle for the center of the transition scene 
    var turtle = makeTurtle(width - 115, height - 455);
    turtle.penDown();
    turtle.setColor(0);
    for (var i = 0; i < 1300; i++) {
        turtle.forward(10);
        turtle.right(141.5);
        turtle.forward(420);
        if (i % 20 === 0) {
            turtle.forward(70);
        }
    }
    if (ismoving){
        //dots jump up relatively high due to gravity
        gravity = createVector(0, 0.2);
        fill(16, 198, 216, 100);
        stroke(186, 198, 216, 200);
        strokeWeight(4);
    }
    else {
        //array of stars up to 2000
    for (var i = 0; i < 2000; i++) {
    stars[i] = new Star();
    }
  }
}

function draw() {
    if (ismoving) {
        //drawing jumping dots in the initial scene
        background(1, 11, 28, 50);
        if (random(1) < 0.2) {
            dots.push(new Dots());
        }
        //push through the array of dots, update and show them
        for (var i = 0; i < dots.length; i++) {
            dots[i].update();
            dots[i].show();
        }
    }
    else {
        background(1, 11, 28, 10);
        //the lower the cursor, the slower the star movement 
        speed = map(mouseY, 10, width / 2, 0, 5);
        //translate so that stars moving out from center, not top left 
        translate(width / 2, height / 2);
        for (var i = 0; i < stars.length; i++) {
            //update and show stars that are in motion
            stars[i].update();
            stars[i].show();
        }
    }
}


//dot constructor function
function Dots() {
    this.dots = new Particle(random(width), height);
    this.update = function() {
        this.dots.applyForce(gravity);
        this.dots.update();
    }
    this.show = function() {
        this.dots.show();
    }
}



//particle constructor function
function Particle(x,y) {
    this.pos = createVector(x,y);
    this.vel = createVector(0, random(-15, -5));
    this.acc = createVector(0, 0);

    this.applyForce = function(force){
        //add force to acceleration, force accumulation
        this.acc.add(force);
    }

    this.update = function() {
        //take the acceleration and adds it to the velocity
        this.vel.add(this.acc);
        //take the velocity and adds it to the position
        this.pos.add(this.vel);
        //multiply acc to 0 so that acc starts with 0 
        this.acc.mult(0);
    }

    this.show = function() {
        point(this.pos.x, this.pos.y);
    }
}

//star details in the transitioned scene
function Star() {
  this.x = random(-width, width);
  this.y = random(-height, height);
  this.z = random(width);
  this.pz = this.z;

  this.update = function() {
    this.z = this.z - speed;
    if (this.z < 1) {
      this.z = width;
      this.x = random(-width, width);
      this.y = random(-height, height);
      this.pz = this.z;
    }
  }

  this.show = function() {
    fill(16, 198, 216, random(200));
    noStroke();

    //the locations of the stars, dispersed across the canvas
    var sx = map(this.x / this.z, 0, 4, 0, width);
    var sy = map(this.y / this.z, 0, 3, 0, height);

    //when closer bigger, when farther smaller in size
    var r = map(this.z, 0, width, 16, 0);
    ellipse(sx, sy, r, r);

  }
}

function mousePressed(){
    ismoving = !(ismoving);
    setup();
}

function turtleLeft(d){this.angle-=d;}function turtleRight(d){this.angle+=d;}
function turtleForward(p){var rad=radians(this.angle);var newx=this.x+cos(rad)*p;
var newy=this.y+sin(rad)*p;this.goto(newx,newy);}function turtleBack(p){
this.forward(-p);}function turtlePenDown(){this.penIsDown=true;}
function turtlePenUp(){this.penIsDown = false;}function turtleGoTo(x,y){
if(this.penIsDown){stroke(this.color);strokeWeight(this.weight);
line(this.x,this.y,x,y);}this.x = x;this.y = y;}function turtleDistTo(x,y){
return sqrt(sq(this.x-x)+sq(this.y-y));}function turtleAngleTo(x,y){
var absAngle=degrees(atan2(y-this.y,x-this.x));
var angle=((absAngle-this.angle)+360)%360.0;return angle;}
function turtleTurnToward(x,y,d){var angle = this.angleTo(x,y);if(angle< 180){
this.angle+=d;}else{this.angle-=d;}}function turtleSetColor(c){this.color=c;}
function turtleSetWeight(w){this.weight=w;}function turtleFace(angle){
this.angle = angle;}function makeTurtle(tx,ty){var turtle={x:tx,y:ty,
angle:0.0,penIsDown:true,color:color(128),weight:1,left:turtleLeft,
right:turtleRight,forward:turtleForward, back:turtleBack,penDown:turtlePenDown,
penUp:turtlePenUp,goto:turtleGoTo, angleto:turtleAngleTo,
turnToward:turtleTurnToward,distanceTo:turtleDistTo, angleTo:turtleAngleTo,
setColor:turtleSetColor, setWeight:turtleSetWeight,face:turtleFace};
return turtle;}

Instructions: Click anywhere or move your cursor around to make alterations.

Brief summary: Jumping Dots, Turtle, and Turquoise Starfield.

For my final project, I took the advantage of making my canvas a space in which the viewers could momentarily be immersed in. As I believe that the  strength of interactive artworks is their ability to allow the audiences to create unexpected changes, I allowed the environment of my work to be altered by the viewers. Despite the changeable environment, however, I also focused on achieving a sense of visual consistency through the usage of coherent colorations and forms.

Conflicting factors coexist in my work; the space is chaotic yet orderly, inviting yet daunting, random yet systematic. Coexistences such as these were merged in creating this single work. I hope you enjoy momentarily being immersed in this space I created!

I also filmed projections of my work to experience its amplified effects outside of my screen.

and here are screenshots of various possible outcomes:

Here is a video of a slight alteration of the piece. I liked how it looked (and reminded me of Christmas and our imminent winter break!), so I decided to include it.