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.

amui1-LookingOutwards-12

For my final project, I want to make an interactive game so for my Looking Outwards, I researched the top games on market for inspiration.

For the first project of my Looking Outwards report, I researched the game Rider. I think Rider is a great source of inspiration for my project because the obstacle changes every round, every level, and as the car moves throughout the track. The player has to face new challenges each frame. I really admire this game’s interaction with the human because it creates a frustrating, but ultimately entertaining experience. This game was released by the company, Ketchapp, in July of 2017.

      

Caption: Above are some screenshots from the game, Rider.

The second project I chose for my Looking Outwards is Monument Valley. Monument Valley runs a player, princess Ida, through mazes of optical illusions and “sacred geometry”, which refers to impossible objects. The player goes through the mazes and finds hidden passages  while in pursuit of the map’s exit. The player must overcome moving platforms, pillars, or spontaneous bridges. Monument Valley was developed by Ustwo, a digital design firm, and was officially released in 2014. Again, I think game is an excellent source of inspiration because the landscape changes continuously and gives the user a surprise edge to face. In addition, I really admire this project’s design and visual graphics. In fact, it was awarded as the Apple Game of the Year and Design Award in 2014.

    

Caption: Above are screenshots from different levels in Monument Valley.

 

amui1-Final-Project-Proposal

For my final project, I want to make an interactive game inspired by Super Mario. The game will feature a penguin in which will travel throughout levels, avoiding obstacles and battling big predators, such as sharks. In addition, I am still thinking of ways I could make it educational. The penguin will be controlled by user inputs such as mouse pressed, dragged, or key pressed. The penguin will travel through an ever changing generative landscape, getting harder with each level. I also want to add a sound effect to accompany the actions.

Caption: Above, I created a model that will help me consolidate my thoughts. The model details different touch points, where the user interacts, throughout the game.   These interactions includes picking a player, jumping, slide on the belly, or fights.

Caption: Above, I created a storyboard that helped me visualize my game concept. Each frame illustrates a different human interaction throughout the game.

amui1-Project-11-Composition

amui1-p11

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

//variables for rain
var x = 30;
var y = 30;
var xSpeed = 0.5;
var ySpeed = 3;
var treex = 10;

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

function draw() {
    background(51,79,102);

    noStroke();
    fill(178,198,204);

    //make rows of rain
    for (row = 0; row < 10; row++) {
      ellipse(x + row*50,y,5,10);
      //make columns of rain
      for (col = 0; col < 5; col++) {
        ellipse(x+row*50,y-80*col,5,10);
      }
    }
    //move rain a different way based on location
    if (y < height/4){
      x -= xSpeed;
    }
    //move rain a different way based on location
    if (y > height/4){
      x += xSpeed;
    }
    //move rain down canvas
    y += ySpeed;
    //if rain off the page, go back to top
    if (y > height/2+10) {
      y = 0;
    }
    //if mouse is pressed, then show lightning
    if (mouseIsPressed) {
      lightning();
    }



    //move tree based on wind based on wind position
    //reposition trunk and tree based on how wind is moving the tree
    if (mouseX > width/2 - 10 & mouseX < width/2+10) {
      wind = 118;
      treew = 68;
      trunkw = 90;
      trunkDist = 50;

    }
    if (mouseX < width/2-10) {
      wind = 110;
      treew = 70;
      trunkw = 80;
      trunkDist = 50;
    }
    if (mouseX > width/2+10) {
      wind = 135;
      treew = 60;
      trunkw = 100;
      trunkDist = 38;
    }

    //make 5 trees
    for (t = 0; t < 5; t++) {
      turtleTree(treex+t*100,wind,treew,trunkw,trunkDist);
    }
}


//make turtle for lightning
function lightning() {
    light = makeTurtle(mouseX,mouseY);
    light.setColor(color(233,255,103));
    light.setWeight(5);
    light.penDown();
    light.forward(20);
    light.right(115);
    light.forward(30);
    light.left(135);
    light.forward(10);
    light.right(140);
    light.forward(30);
    light.left(125);
    light.forward(10);
    light.right(130);
    light.forward(40);
    light.right(150);
    light.forward(20);
    light.left(115);
    light.forward(10);
    light.right(130);
    light.forward(30);
    light.left(120);
    light.forward(10);
    light.right(123);
    light.forward(41);
    light.penUp();
}

//make turtle tree
function turtleTree(treex,wind,treew,trunkw,trunkDist) {

    trunk = makeTurtle(treex+25,height-trunkDist);
    trunk.setColor(color(95,81,48));
    trunk.setWeight(3);
    trunk.penDown();
    trunk.right(trunkw);
    trunk.forward(48);
    trunk.left(90);
    trunk.forward(10);
    trunk.left(90);
    trunk.forward(48);
    tree = makeTurtle(treex,height-50);
    tree.setColor(color(93,134,67));
    tree.setWeight(3);
    tree.penDown();
    tree.left(65);
    tree.forward(15);
    tree.left(125);
    tree.forward(8);
    tree.right(130);
    tree.forward(15);
    tree.left(125);
    tree.forward(8);
    tree.right(wind);
    tree.forward(80);
    tree.right(130);
    tree.forward(80);
    tree.left(230);
    tree.forward(8);
    tree.left(135);
    tree.forward(15);
    tree.left(240);
    tree.forward(8);
    tree.right(240);
    tree.forward(20);
    tree.right(122);
    tree.forward(treew);
    tree.penUp();
}


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;}

I had trouble coming up with a concept for this project. It was so open ended, that I wasn’t sure exactly what I should do. I managed to come to the idea of depicting a storm. The user can interact with the program by pressing the mouse to show lightning or move the mouse left and right to portray how wind would behave.

Caption: The user moved to the left side, as the “wind”, which swayed the trees on the bottom left.

Caption: The user clicked the mouse and the lightning appeared.

amui1-LookingOutwards-11

For this week’s Looking Outwards, I researched the Japanese artist, Notuv.

Caption: Above, he is pictured playing at one of his live sets.

I specifically chose to do my Looking Outwards on his piece, Fucertc, released in 2013. It can be found in the video below:

I admire Notuv and this piece because he combines sound control with a unique visual design. He controls the sound with a program called MaxMSP and the visuals with OpenFrameworks. I particularly admire this piece, Fucertc because he uses such a minimalistic approach with only a 2 step “vibe” and percussional sounds. I also like how as each measure comes, there is a new sound introduced, but with the same consistent background beat. The full writeup for Fucertc can be found here.

amui1-LookingOutwards-10

This week, I chose to do my Looking Outwards of Chloe Varelidi. Her portfolio can be found here.

Chloe Varelidi is a game designer that focuses on building playful products to encourage children to “be creative, kind, and curious about the world behind them” (quote from Chloe’s portfolio). She received her Masters in Fine Arts at Parsons’ Design and Technology Program and has since worked at Quest to Learn, Institute of Play, Mozilla, and now littleBits.

I specifically admire her projects for littleBits, codekit and a minicade. that I find particularly interesting. At littleBits, she works as a senior product design strategist. The codeKit is a small introduction kit of magnets and electrical items that create an interactive activity that teaches coding. The minicade is an open source mobile web application that encourages children to make short (40 line) games with their friends. This project aims to also teach coding but in an interactive and “silly” way.

Caption: Chloe says in the future, she hopes that the minicade can become a pop-up structure at any city corner, like the one in the picture above.

 

 

amui1-Project-10-Landscape

amui1-p10

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

//variables for image
var starImg = "https://i.imgur.com/0ns3TvE.png";
var monsterImg = "https://i.imgur.com/hqvDkxx.png";
var star;
var monster;
//variables for star positions
var sx = [];
var sy = [];
//variables for objects
var met = [];
var monst = [];
//variable for points
var counter = 0;


//loads images
function preload() {
  star = loadImage(starImg);
  monster = loadImage(monsterImg);
}


function setup(){
  createCanvas(480,380);
  //intializes meteor by calling make meteor. stores them in meteor array
  for (num = 0; num < 4; num++) {
    var ogX = random(width/2+width/4,width);

    met[num] = makeMet(ogX);

  }
  //intializes monster by calling make monster
  monst[0] = makeMonster();

  //creates random x and y locations for star
  for (s = 0; s < 15; s++) {
    sx.push(random(width));
    sy.push(random(height));
  }

  //loads star picture
  star.loadPixels();

}

function draw(){
  background(6,13,29);
  //shows picture of star in random x and y locations
  for (st = 0; st < 15; st++) {
    image(star,sx[st],sy[st]);
  }

  //displays meteor
  showMet();

  //constrains so space ship won't go off of screen
  var y = constrain(mouseY,45/2,height-38/2);
  var x = 80;
  //space ship
  fill(106,139,189);
  arc(x,y,45,45, PI, 0);
  fill(253,194,74);
  ellipse(x,y+6,50,25);
  ellipse(x,y+4,80,15);
  fill(68,110,172);
  ellipse(x,y,80,15);

  //displays monster
  showMonster();
  //keep tracks of points
  fill(255);
  text("Points:" + counter, 15, 20);
  text("Avoid the meteors!", width/2-50, 20);

}


function showMet() {
  //displays and moves all meteors in meteor array
  for (var i = 0; i < met.length; i++) {
      met[i].move();
      met[i].draw();

  }
}

function showMonster() {
  //displays and moves monster
  monst[0].move();
  monst[0].draw();
}




function drawMet() {
  //overall meteor
  var metSize = this.metSize;


  fill(146,164,174);
  noStroke();
  //meteor body
  ellipse(this.x,this.y,metSize,metSize);
  fill(75,99,107);
  //meteor blimps
  ellipse(this.x - 16, this.y, metSize/8,metSize/8);
  ellipse(this.x, this.y+17, metSize/8,metSize/8);
  ellipse(this.x + 8, this.y - 10, metSize/4, metSize/4);
  ellipse(this.x + 10, this.y + 10, metSize/10, metSize/10);

  //flames behind
  fill(247,223,61);
  rect(this.x+metSize/2+5, this.y-18,this.metSize+10,5,5);
  fill(243,161,28);
  rect(this.x+metSize/2+5,this.y-10,this.metSize+10-10,5,5);
  fill(247,223,61);
  rect(this.x+metSize/2+5, this.y-2, this.metSize+10-20,5,5);
  fill(243,161,28);
  rect(this.x+metSize/2+5,this.y+5,this.metSize+10,5,5);

}

function moveMet() {
  //moves meteor by speed
  this.x += this.speed;
  //moves meteor by meteor object speed
  if (this.x < -this.metSize/2-(this.metSize+10)) {
    //if meteor slips of successfully, increase point
    counter += 1;
    this.x = width+this.metSize/2;
    this.y = random(30,height-25);
  }
}

function makeMet(ogX) {
  //based off of provided code
  //creates meteor object
  meteor = {x: ogX,
            y: random(30,height-25),
            speed: random(-4,-1),
            move: moveMet,
            metSize: int(random(40,80)),
            draw: drawMet}
  return meteor;
}

function drawMonster() {
  //displays monster picture
  image(monster,monty.x,monty.y);
  monster.loadPixels();
}

function moveMonster() {
  //moves monster by monster object speed
  monty.x += monty.speed;
  //if off screen, re start monster
  if (monty.x < -monty.x-200) {
    monty.x = width+1500;
    monty.y = random(30,height-100);
  }
}

function makeMonster() {
  //makes monster object
  monty = {x: width,
             y: random(30,height-100),
             speed: random(-2,-0.5),
             move: moveMonster,
             draw: drawMonster}
  return monty;
}

I enjoyed this project more than the past projects. It had a lot of room for creativity. I first started off by sketching my idea and then went off to coding. For future improvements for this, with more time, I would find a way to incorporate shooting something when the mouse is clicked and if the shot x position reached the meteor or monster, then the monster would disappear. I would also try to find a way to decrease the points if the mouseY was in the same position as a meteor. All in all, I enjoyed this project and am happy with my final result.

Caption: Above is my first sketch of what I wanted the canvas to look like.

Caption: Above is my ugly monster. I drew it Illustrator and then loaded it onto imgur.

 

**edited b/c star image got removed from Imgur.

amui1-Project-09-Portrait

amui1-p9

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

//variables for image
var portraitImg = "https://i.imgur.com/UMgur46.png";
var portrait;

//list of random words
var words = ["cat","dog", "bun", "sun", "pot",
            "pen", "bot", "run", "fill the screen"];
var idx;
var word;

//variables for random coordinates
var px;
var py;


function preload() {
    //loads image into portrait variable
    portrait = loadImage(portraitImg);
}

function setup() {
    createCanvas(431,480);
    background(0);

    //variables for starting positions
    tpx = 30;
    tpy = 30;

    //identifies random word in word list
    fill(255);
    //stores length of array
    var length = words.length
    //picks random index in array
    var idx = int(random(0,length));
    //stores random word
    var word = words[idx];
    //displays random word
    text(word,width-100,380);

    //draw game like structure
    stroke(255);
    //border line
    line(0,400,width,400);
    fill(139,0,0)
    noStroke();
    //slight 3d effect
    ellipse(width/2-116,443,40,40);
    ellipse(width/2+124,443,40,40);
    fill(255,0,0);
    noStroke();
    //red buttons
    ellipse(width/2-120,445,40,40);
    ellipse(width/2+120,445,40,40);

    //loads picture pixels
    portrait.loadPixels();
}

function draw() {
    //shows timer
    fill(255);
    //if 900 frames already passed, show time alert
    if (frameCount == 500) {
      text("60 seconds left", 30, 380);
    }
    //if 1800 frames already passed, show game over alert
    if (frameCount >= 800) {
      frameRate = 60;
      fill(255,0,0);
      text("Game Over", width/2-30,380);
      //if game is over randomize locations
      px = random(0,width);
      py = random(0,height-150);
      var randomColor = portrait.get(px,py);
      fill(randomColor);
      //place circles in random locations to show the underlying picture
      ellipse(px,py,4,4);

    }

    stroke(0);

    //tfactor represents the number circle in the row
    var tfactor = 0;
    //run 8 circles/times
    for (t = 0; t < 8; t++){
      var tportraitColor = portrait.get(tpx+tfactor,tpy);
      fill(tportraitColor);
      //draw circle for the row
      ellipse(tpx+tfactor,tpy,6,6);
      tfactor += 6;
    }
    // if game is not over, allow user to move row
    if (frameCount < 800) {
      if (keyIsDown(LEFT_ARROW)) {
        tpx -= 5;

      }
      if (keyIsDown(UP_ARROW)) {
        tpy -= 5;

      }
      if (keyIsDown(DOWN_ARROW)) {
        tpy += 5;

      }
      if (keyIsDown(RIGHT_ARROW)) {
        tpx += 5;

      }
    }
    //create boundaries
    if (tpx > width - 1) {
      tpx = width-5;
    }
    if (tpx < 1) {
      tpx = 1;
    }
    if (tpy > height - 150) {
      tpy = height-150;
    }
    if (tpy < 1) {
      tpy = 1;
    }
}

I thought this project was rather difficult. I had a lot of ideas in mind and struggled with liking my final product. However, I became inspired by a childhood toy “etch-a-sketch”. So the idea behind my project, is a random word is generated which you have to try to write before the timer runs out.

Caption: Above are different states of the project. Below is a picture of the toy I was referring to.

 

Disclaimer: the page will move up and down if you press the keys as well.  This was not intended. :/

amui1- LookingOutwards-09

I chose to look at my friend, Katie’s, Looking Outwards for Week 8. She did her Looking Outwards on the Clouds Documentary.

Caption: The opening screen for the Clouds Documentary website. A kickstarter video for the project can be found below and at this website:

I liked how Katie referred to the project as “adding another dimension to the idea of marrying videography, design, and programming.” I strongly agree with this b/c this team figured out how to bring all of these mediums together to create an even more outrageous and innovative creation.

Caption : Visualization of Space Junk: One the interactive graphics that can be found on the cloud.

Caption: Visualization of a noise sphere: One of the interactive graphics found on the cloud.

Caption: Fernanda Viegas. One of the contributors to the cloud.

I chose this Looking Outwards because it also has some relation to what we are doing our project on this week: computational portraits. As you can see from the last photo, Fernanda is pixelating. The Cloud took into another level and pixelated a whole story. I think this project is really fascinating because of the mass amount of interdisciplinary contributors that helped bring this project forth.

 

 

amui1-LookingOutwards-08

The person I chose to reflect on for this week’s Looking Outwards is J.Meejin Yoon

Caption: A picture of J.Meejin and her husband, Eric. Together, they founded an architectural studio, called Höweler + Yoon Architecture LLP, as a husband and wife team. Yoon is also a cofounder of MyStudio.

J.Meejin Yoon is an architect, designer, and educator. She started her education in 1995, at Cornell University studying architecture. Then, she received her Masters of Architecture in Urban Design at Harvard (1997).

Now, she is the head of the Department of Architecture at MIT. Along with the 2015 new Generation Award, she was has been recognized as Architecture League’s Emerging Voices (2012), Rome Prize in Design (2005) and many more. Her works and research focus on intersecting architecture, technology, nature, and public space.

Caption: Eyeo talk by J.Meejin Yoon on interactive play in public space. I admired her presentation because she presented her work with humor, honesty, and thought processes to specific aspects of the project.

I admire that her work consistently incorporated nature. In addition, I like how her work aims to encourage  human interaction. I admire her as a person. She is very humble, yet so accomplished.

My favorite project was “Swing Time.” I liked this project because it was all about encouraging people of all ages to play and engage. She specifically mentioned, that she wanted to experiment to find a way to allow parents and young adults to be brought back to their childhood days with this project. I also really liked her project, Sean Collier Memorial. I like the way she incorporated Incan architecture and how she said at the end: the project was no longer her’s, but the project was now the MIT community’s.