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.

Leave a Reply