Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/////////////////////////////////////////////////////////////////////////////////////////
//Dragon's Den by Blaire Francis                                                       //
//A mother dragon is resting in her den. She seems to tolerate your presense (for now).//
//Why not try exploring? Interact with things in the cave by clicking on them or       //
//hovering over them with your mouse?                                                  //
/////////////////////////////////////////////////////////////////////////////////////////

//GLOBAL VARIABLES//
//eyes
float eyeX, eyeY, leftEyeX, leftEyeY, rightEyeX, rightEyeY;
float easing = 0.05;
//egg
float clickCount = 0;
//fire
float fireR= 222;
float fireG = 67;
float fireB = 16;
float fireColour1, fireColour2;
//water
float dropY;
float dropY2 = 0;
float dropY3 = 0;
int dropCount = int(random(1, 4));

void setup() {
  //sets size, frame rate, and background; runs once
  size(600, 400);
  frameRate(100);
  background(255);
}

void draw() {

  displayCave();
  displayDragon();
  displayBaby();
  displayEgg();
  displayChest();
  updateWater();
  displayStalagtites();

  updateEyes();
  updateEgg();
  updateFire();
  updateMouth();
  updateShine();
}

//FUNCTIONS//

void displayCave() {
  //draw cave walls
  noStroke();
  fill(86, 76, 127);
  rect(0, 0, 600, 400);
  //draw cave floor
  fill(62, 55, 92);
  ellipseMode(CORNER);
  ellipse(-150, 180, 900, 300);
  //cracks on wall
  stroke(62, 55, 92);
  strokeWeight(1);
  line(40, 70, 40, 150);
  line(40, 150, 35, 190);
  line(35, 190, 35, 230);
  line(40, 150, 45, 200);
  line(45, 200, 45, 210);
  line(90, 0, 90, 50);
  line(90, 20, 95, 60);
  line(95, 60, 90, 80);
  line(170, 20, 170, 80);
  line(250, 140, 250, 200);
  line(360, 20, 360, 60);
  line(360, 60, 340, 80);
  line(340, 80, 360, 120);
  line(340, 80, 335, 95);
  line(420, 280, 420, 140);
  line(420, 155, 425, 130);
  line(450, 0, 455, 60);
  line(520, 0, 520, 80);
  line(520, 80, 515, 120);
  line(520, 80, 525, 88);
  line(590, 240, 590, 180);
}

void displayStalagtites() {
  noStroke();
  fill(127, 115, 175);
  triangle(0, 0, 10, 40, 20, 0);
  triangle(10, 0, 18, 80, 25, 0);
  triangle(210, 0, 220, 30, 225, 0);
  triangle(225, 0, 240, 60, 250, 0);
  triangle(380, 0, 390, 60, 400, 0);
  triangle(500, 0, 505, 20, 510, 0);
  triangle(560, 0, 570, 80, 580, 0);
}

void displayDragon() {
  noStroke();
  //draw body
  fill(146, 155, 84);
  rect(100, 160, 220, 140, 40);
  quad(110, 170, 140, 250, 50, 310, 50, 250);
  //tail
  quad(315, 180, 360, 250, 365, 280, 315, 280);
  triangle(315, 280, 365, 280, 330, 330);
  quad(316, 280, 331, 330, 290, 330, 290, 300);
  triangle(290, 330, 290, 300, 260, 330);
  //neck
  fill(156, 165, 95);
  arc(50, 265, 95, 80, 0, PI+QUARTER_PI, OPEN);
  triangle(50, 270, 50, 310, 80, 285);
  triangle(130, 280, 100, 300, 65, 235);
  //head
  fill(167, 175, 106);
  ellipseMode(RADIUS);
  ellipse(110, 310, 35, 35);
  quad(130, 290, 110, 345, 170, 345, 180, 320);
  triangle(125, 280, 90, 300, 50, 250);
  //wing
  stroke(167, 175, 106);
  strokeWeight(2);
  line(140,170,170,175);
  line(180,175,140,175);
  line(140,175,200,195);
  line(200,195,280,180);
  line(280,180,240,182);
  line(240,182,275,175);
  line(275,175,230,175);
  line(230,175,250,170);
  line(250,170,220,170);
  //leg
  line(290,210,240,195);
  line(240,195,220,240);
  line(220,240,222,250);
}

void displayBaby() {
  noStroke();
  //displays baby dragon when clickCount reaches 4
  if (clickCount >= 4) {
    //head and body
    fill(120, 129, 62);
    ellipse(220, 250, 20, 20);
    triangle(200, 245, 195, 220, 210, 235);
    triangle(230, 235, 245, 220, 240, 245);
    quad(210, 250, 230, 250, 240, 280, 200, 280);
    //snout
    fill(146, 155, 84);
    ellipse(220, 260, 8, 8);
    stroke(0);
    strokeWeight(1);
    line(220, 260, 214, 265);
    line(220, 260, 224, 265);
    line(214, 265, 210, 260);
    line(224, 265, 229, 260);
  }
}

void displayEgg() {
  noStroke();
  fill(250, 237, 225);
  //displays unhatched egg on screen until clickCount passes 3
  if (clickCount <= 3) {
    ellipse(220, 290, 30, 40);
  }
  //displays hatched egg once clickCount hits 4 and beyond
  if (clickCount >= 4) {
    arc(220, 290, 30, 40, 0, PI, OPEN);
    triangle(190, 290, 195, 260, 210, 290);
    triangle(200, 290, 210, 265, 220, 290);
    triangle(210, 290, 225, 270, 230, 290);
    triangle(220, 290, 245, 260, 250, 290);
  }
}

void displayChest() {
  noStroke();
  //chest
  fill(98, 71, 47);
  triangle(420, 180, 450, 170, 450, 230);
  quad(450, 170, 530, 180, 530, 240, 420, 240);
  //gold
  fill(214, 186, 82);
  arc(475, 200, 50, 35, PI, TWO_PI, OPEN);
  //coins
  fill(198, 170, 66);
  ellipse(470, 180, 3, 2);
  ellipse(460, 175, 3, 2);
  ellipse(480, 175, 3, 2);
  ellipse(500, 185, 3, 2);
  //chest
  fill(131, 88, 48);
  quad(420, 180, 420, 240, 500, 250, 500, 190);
  quad(500, 190, 530, 180, 530, 240, 500, 250);
  //details
  fill(193, 187, 166);
  quad(455, 183, 465, 185, 465, 196, 455, 195);
  stroke(98, 71, 47);
  strokeWeight(1);
  line(420, 190, 500, 200);
  line(420, 200, 500, 210);
  line(420, 210, 500, 220);
  line(420, 220, 500, 230);
  line(420, 230, 500, 240);
  line(500, 200, 530, 190);
  line(500, 210, 530, 200);
  line(500, 220, 530, 210);
  line(500, 230, 530, 220);
  line(500, 240, 530, 230);
}

void updateWater() {
  //draws droplets
  noStroke();
  fill(199, 221, 227);
  ellipse(18, dropY, 1, 2);
  ellipse(240, dropY2, 1, 2);
  ellipse(570, dropY3, 1, 2);

  //randomly chooses drops to fall
  if (dropCount == 1) {
    dropY++;
  }
  if (dropCount == 2) {
    dropY2++;
  }
  if (dropCount == 3) {
    dropY3++;
  }


  /*sends drops to top of screen once they leave frame and
   generates new random number with cerntain additions so the same number isn't chosen twice
   */
  if (dropY > 405) {
    dropY = 0;
    dropCount = int(random(2, 4));
  }
  if (dropY2 > 405) {
    dropY2 = 0;
    dropCount = int(random(1, 4));
    if (dropCount == 2) {
      dropCount = int(random(1, 4));
    }
  }
  if (dropY3 > 405) {
    dropY3 = 0;
    dropCount = int(random(1, 3));
  }
}

void updateEyes() {
  //handles dragon's eye movement then changes eye shape when counter reaches 4
  if (clickCount <= 3) {
    //eye white
    noStroke();
    fill(255);
    ellipse(125, 300, 10, 10);

    //constrains pupil to stay within eye white
    if (abs(mouseX - eyeX) > 0.1) {
      eyeX = eyeX + (mouseX - eyeX) * easing;
    }
    if (abs(mouseY - eyeY) > 0.1) {
      eyeY = eyeY + (mouseY - eyeY) * easing;
    }

    eyeX = constrain(eyeX, 120, 130);
    eyeY = constrain(eyeY, 300, 304);
    //pupil
    fill(0);
    ellipse(eyeX, eyeY, 5, 5);
    //eyebrow
    strokeWeight(10);
    stroke(167, 175, 106);
    line(118, 292, 135, 294);
  } else {
    stroke(1);
    noFill();
    strokeWeight(1);
    arc(125, 310, 10, 10, PI+QUARTER_PI, TWO_PI);
  }
  if (clickCount >= 4) {
    noStroke();
    //eye whites
    fill(255);
    ellipse(212, 245, 6, 6);
    ellipse(228, 245, 6, 6);

    //constrains baby's pupils to stay within eye whites
    if (abs(mouseX - leftEyeX) > 0.1) {
      leftEyeX = leftEyeX + (mouseX - leftEyeX) * easing;
    }
    if (abs(mouseY - leftEyeY) > 0.1) {
      leftEyeY = leftEyeY + (mouseY - rightEyeY) * easing;
    }
    if (abs(mouseX - rightEyeX) > 0.1) {
      rightEyeX = rightEyeX + (mouseX - rightEyeX) * easing;
    }
    if (abs(mouseY - rightEyeY) > 0.1) {
      rightEyeY = rightEyeY + (mouseY - rightEyeY) * easing;
    }

    leftEyeX = constrain(leftEyeX, 210.5, 214.5);
    leftEyeY = constrain(leftEyeY, 242.5, 247.5);
    rightEyeX = constrain(rightEyeX, 226.5, 230.5);
    rightEyeY = constrain(rightEyeY, 242.5, 247.5);
    //pupil
    fill(0);
    ellipse(leftEyeX, leftEyeY, 3.5, 3.5);
    ellipse(rightEyeX, rightEyeY, 3.5, 3.5);
  }
}

void updateEgg() {
  //draws
  stroke(180, 168, 157);
  strokeWeight(1);
  //draws cracks for each click
  if (clickCount == 1) {
    line(220, 250, 220, 255);
    line(220, 255, 225, 260);
    line(225, 260, 220, 265);
  }
  if (clickCount == 2) {
    line(220, 250, 220, 255);
    line(220, 255, 225, 260);
    line(225, 260, 220, 265);
    line(220, 265, 225, 270);
    line(220, 255, 215, 260);
    line(215, 260, 205, 265);
  }
  if (clickCount == 3) {
    line(220, 250, 220, 255);
    line(220, 255, 225, 260);
    line(225, 260, 220, 265);
    line(220, 265, 225, 270);
    line(225, 270, 220, 280);
    line(225, 260, 235, 275);
    line(220, 255, 215, 260);
    line(215, 260, 205, 265);
    line(205, 265, 210, 270);
  }
}

//creates 'fire' that flicker back and forth and grows and shrinks
void updateFire() {
  //big flames
  noStroke();
  fill(fireR, fireG, fireB);
  triangle(200+sin(frameCount*.2), 290+sin(frameCount/4), 190, 325, 210, 330);
  triangle(220+sin(frameCount*.25), 290+sin(frameCount/4), 210, 330, 230, 330);
  triangle(240+sin(frameCount*.2), 290+sin(frameCount/4), 230, 330, 250, 325);
  //medium flames
  fill(fireR, fireG+56, fireB+2);
  triangle(200+sin(frameCount*.25), 300+sin(frameCount/4), 195, 325, 205, 328);
  triangle(220+sin(frameCount*.2), 300+sin(frameCount/4), 215, 330, 225, 330);
  triangle(240+sin(frameCount*.25), 300+sin(frameCount/4), 235, 328, 245, 325);
  //fill(222, 178, 20);
}

void updateMouth() {
  //handles chest click event
  if (mousePressed && mouseX >= 420 && mouseX <= 530 && mouseY >= 160 && mouseY <= 250 && clickCount <= 3) {
    noStroke();
    fill(255);
    triangle(170, 345, 145, 338, 140, 345);
    println("Grrr...");
  }
}

void updateShine() {
  //displays shine if mouse is within parameters
  if (mouseX >= 420 && mouseX <= 530 && mouseY >= 160 && mouseY <= 250) {
    stroke(255);
    strokeWeight(1);
    line(440, 170, 450, 170);
    line(445, 165, 445, 175);
    line(440, 165, 450, 175);
    line(440, 175, 450, 165);
  }
}

//picks colour for fire
void fireColour() {
  fireR = random(255);
  fireG = random(255);
  fireB = random(255);
}

//handles egg and fire click events
void mousePressed() {
  //clicks within parameter add 1 to clickCount
  if (mouseX >= 190 && mouseX <= 250 && mouseY >= 250 && mouseY <= 290) {
    clickCount = clickCount + 1;
  }
  if (mouseX >= 190 && mouseX <= 250 && mouseY <= 330 && mouseY >= 290) {
    fireColour();
  }
}