Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
//*********************************************************************************
//Democrocy: Pride and Joy
//Jared Moeller
//
//A parody of old unliscenced movie tie-in games,
//Democracy: Pride and Joy is made in the image of 'National Treasure' the movie
//staring Nicholas Cage. In this interactive toy, the player (Nikoli Container) attempts to traverse a
//series of hazzards to steal the 'Statement of Freedom'.
//
//Controls -
//Left and Right arrow keys (or 'A' and 'D' keys) to move left and right respectively.
//*********************************************************************************

/// GLOBAL VARIABLES ///

// system variables
boolean artifactObtained = false;
boolean winCondition = false;
boolean loseCondition = false;
int time = millis();
int timeLimit=(2*60*1000);
int health = 12;

// player variables
boolean playerMoving = false;
float playerPositionX = 30;
int playerPositionY = 175;
boolean playerDirection = true;
int playerWidth = 20;
int playerHeight = 50;

// electric variables
float electricTopY=115;
float electricMiddleTopX;
float electricMiddleBottomX;
int electricWidth = 30;
int electricHeight = 18;

// spikes variables
int spikeX = 135;
int spikeY = 115;
int spikeWidth;
// 1 = inactive, 2 = 2 seconds until active, 3 = active
int spikeState = 1;
float spikeSwitchTime = time + (2 * 1000);

// dart variables
boolean dartTrigger1 = false;
boolean dartTrigger2 = false;
boolean dartMoving = false;
float dartFireDelay = 0;
int dartFireCount = 0;
float dart1Y = 90;
float dart2Y = 90;
float dart3Y = 90;
float dart4Y = 90;

// fire variables
float fireY=200;
int fireX = 255;
boolean fireMoving = false;
boolean fireDirection = false;
float fireSwitchTime = (3*1000);

// sawblade variables
int sawHeight = 50;
int sawSegmentHeight = 10;
boolean sawDirection = true;
float sawY = 200;
int sawX = 305;

void setup() {
  size(400, 400);
  frameRate(60);
  rectMode(CORNER);
  ellipseMode(CENTER);
}

void draw() {
  // update time
  time=millis();
  // process traps/projectiles
  updateTrapElectric();
  updateTrapSpikes();
  updateTrapDarts();
  updateTrapFire();
  updateTrapSawblade();
  // process player movement
  updatePlayer();
  // check for a collision with the updated info
  checkCollision();
  // check score
  updateScore();
  // draw background pieces
  drawBackground();
  drawArtifact();
  //draw traps
  drawTrapElectric();
  drawTrapSpikes();
  drawTrapDarts();
  drawTrapFire();
  drawTrapSawblade();
  // draw player
  drawPlayer();
  // draw front wall and UI
  drawUI();
}

//////////////////////////////////////////////////////////////////////////////////
//  
//   Land of the Functions
//
//////////////////////////////////////////////////////////////////////////////////

//
///
//// BACKGROUND
///
//

void drawBackground() {
  // floor
  background(75, 87, 118);
  // back wall
  noStroke();
  fill(152, 55, 55);
  rect(0, 0, width, height/4);
  // back wall brick pattern
  strokeWeight(1);
  stroke(175, 88, 88);
  for (int brickVertical = 0; brickVertical<10; brickVertical++) {
    for (int brickHorizontal = 0; brickHorizontal<50; brickHorizontal++) {
      line((brickHorizontal*15), (brickVertical*10), ((brickHorizontal+1)*15), ((brickVertical)*10));
      line(((brickVertical%2)*5)+(brickHorizontal*15), (brickVertical*10), ((brickVertical%2)*5)+(brickHorizontal*15), 10+((brickVertical)*10));
    }
  }
}

//
///
//// UPDATING
///
//

void updatePlayer() {
  // processes player movement
  if (playerMoving==true) {
    if ((keyCode==RIGHT||key==100)&&(playerPositionX<330)) {
      playerPositionX+=0.5;
    } else if ((keyCode==LEFT||key==97)&&(playerPositionX>30)) {
      playerPositionX-=0.5;
    } else {
    }
  }
}

void keyPressed() {
  // allows movement
  playerMoving = true;
}

void keyReleased() {
  // stops movement 
  playerMoving = false;
}

//
///
//// ELECTRIC
///
//

void updateTrapElectric() {
  // move bolt
  electricTopY+=.7;
  // randomize graphic
  electricMiddleTopX = 90+(random(-15, 15));
  electricMiddleBottomX = 90+(random(-15, 15));
  // reset projectile if its reached the bottom of the path
  if (electricTopY+electricHeight>=290) {
    electricTopY=115;
  }
}

//
///
//// SPIKE
///
//

void updateTrapSpikes() { 
  // inactive to warning
  if (spikeState==0) {
    if (time>=spikeSwitchTime) {
      spikeState = 1;
      spikeSwitchTime = time + (2 * 1000);
    }
  }
  // warning to active
  if (spikeState==1) {
    if (time>=spikeSwitchTime) {
      spikeState = 2;
      spikeSwitchTime = time + (5 * 1000);
    }
  }
  // active to inactive
  if (spikeState==2) {
    if (time>=spikeSwitchTime) {
      spikeState = 0;
      spikeSwitchTime = time + ((5+random(1, 3)) * 1000);
    }
  }
}


//
///
//// DART
///
//

void updateTrapDarts() {
  // catch to disable darts when they reach the end of the screen
  if (dart4Y>400) {
    dartMoving = false;
    dart1Y = 90;
    dart2Y = 90;
    dart3Y = 90;
    dart4Y = 90;
  }

  // first firing cycle
  if (dartTrigger1 == true) {
    if (dartFireCount==0) {
      if (time>=dartFireDelay) {
        // begins cycle
        dartMoving = true;
        // counts the darts fired
        dartFireCount++;
        // set the dart in moving range
        dart1Y=91;
        // delay to next dart
        dartFireDelay = time + 1000;
      }
    }
    if (dartFireCount==1) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart2Y=91;
        dartFireDelay = time + 1000;
      }
    }
    if (dartFireCount==2) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart3Y=91;
        dartFireDelay = time + 1000;
      }
    }
    if (dartFireCount==3) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart4Y=91;
      }
    }
  }

  // second firing cycle
  if (dartTrigger2 == true) {
    if (dartFireCount==4) {
      if (time>=dartFireDelay) {
        dartMoving = true;
        dartFireCount++;
        dart1Y=91;
        dartFireDelay = time + 1000;
      }
    }
    if (dartFireCount==5) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart2Y=91;
        // larger delay between bolts to trick players into false security
        dartFireDelay = time + 2000;
      }
    }
    if (dartFireCount==6) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart3Y=91;
        dartFireDelay = time + 1000;
      }
    }
    if (dartFireCount==7) {
      if (time>=dartFireDelay) {
        dartFireCount++;
        dart4Y=91;
      }
    }
  }

  // move darts
  if (dart1Y>90) {
    dart1Y+=2;
  }
  if (dart2Y>90) {
    dart2Y+=2;
  }
  if (dart3Y>90) {
    dart3Y+=2;
  }
  if (dart4Y>90) {
    dart4Y+=2;
  }
}

//
///
//// FIRE
///
//

void updateTrapFire() {
  // catches for if the fire reaches an edge of the vertical path
  if (fireY+30>310) {
    fireDirection = true;
  }
  if (fireY<110) {
    fireDirection = false;
  }
  // moves the fire
  if (fireMoving==true) {
    if (fireDirection==true) {
      fireY-=.4;
    }
    if (fireDirection==false) {
      fireY+=.4;
    }
  }
  // processes the fire's modes (active/inactive)
  if (time>=fireSwitchTime) {
    if (fireMoving == true) {
      fireMoving = false;
      // semi-random time until resumes movement 3-6 seconds
      fireSwitchTime = time+ (2 * 1000) + (random(1, 4) * 1000);
    } else {
      // after inactive period, the fire's direction will be randomized, (true = up, false = down)
      fireMoving=true;
      if (random(0, 10) >= 5) {
        fireDirection = true;
      } else {
        fireDirection = false;
      }
      fireSwitchTime = time+(2 * 1000) + (random(1, 4) * 1000);
    }
  }
}

//
///
//// SAWBLADE
///
//

void updateTrapSawblade() {
  // catches for if the saw reaches end of path
  if (sawY<110) {
    sawDirection = false;
  }
  if (sawY+sawHeight>310) {
    sawDirection = true;
  }
  // moves saw
  if (sawDirection == true) {
    sawY -= .4;
  }
  if (sawDirection == false) {
    sawY += .4;
  }
}

//
///
//// DRAWING
///
//

void drawPlayer() {
  // head
  noStroke();
  fill(227, 204, 169);
  rect(5+playerPositionX, 5+playerPositionY, 10, 15);
  rect(playerPositionX, 10+playerPositionY, 20, 5);
  // body
  fill(178, 119, 0);
  rect(5+playerPositionX, 20+playerPositionY, 10, 15);
  // player direction flips when artifact is obtained
  if (playerDirection==true) {
    // face
    fill(255);
    rect(10+playerPositionX, 5+playerPositionY, 5, 5);
    fill(0);
    rect(playerPositionX, 10+playerPositionY, 5, 5);
    rect(5+playerPositionX, 5+playerPositionY, 5, 5);
    // pant
    fill(106, 82, 35);
    rect(5+playerPositionX, 35+playerPositionY, 10, 15);
    rect(5+playerPositionX, 45+playerPositionY, 15, 5);
  } else {
    // face
    fill(255);
    rect(5+playerPositionX, 5+playerPositionY, 5, 5);
    fill(0);
    rect(15+playerPositionX, 10+playerPositionY, 5, 5);
    rect(10+playerPositionX, 5+playerPositionY, 5, 5);
    // pant
    fill(106, 82, 35);
    rect(5+playerPositionX, 35+playerPositionY, 10, 15);
    rect(playerPositionX, 45+playerPositionY, 15, 5);
  }
  // hat
  fill(106, 82, 35);
  rect(5+playerPositionX, playerPositionY, 10, 5);
  strokeWeight(2);
  stroke(106, 82, 35);
  line(playerPositionX, 5+playerPositionY, 20+playerPositionX, 5+playerPositionY);
  noStroke();
}

void drawArtifact() {
  noStroke();
  // base (pillar)
  fill(72, 61, 139);
  rect(350, 195, 20, 5);
  rect(355, 200, 10, 20);
  rect(350, 220, 20, 5);
  // artifact (statement of freedom)
  if (artifactObtained == false) {
    fill(147, 112, 219);
    rect(355, 175-9, 10, 15);
  }
}

//
///
//// ELECTRIC
///
//

void drawTrapElectric() {
  // fantasy style electric rods
  fill(101, 123, 129);
  triangle(75, 85, 105, 85, 90, 120);
  fill(125, 145, 147);
  ellipse(90, 120, 20, 20);

  fill(101, 123, 129);
  triangle(75, 305, 105, 305, 90, 280);
  fill(125, 145, 147);
  ellipse(90, 280, 20, 20);

  // electric bolt
  stroke(255);
  strokeWeight(2);
  line(90, electricTopY, electricMiddleTopX, electricTopY+6);
  line(electricMiddleTopX, electricTopY+6, electricMiddleBottomX, electricTopY+12);
  line(electricMiddleBottomX, electricTopY+12, 90, electricTopY+18);
}

//
///
//// SPIKES
///
//

void drawTrapSpikes() {
  noStroke();
  // draw spike trap
  int spikeCollumn = 0;
  for (int spikeRow = 0; spikeRow<99; spikeRow++) {
    if (spikeRow!=0&&spikeRow%3==0) {
      spikeCollumn++;
    };
    // spike holes
    fill(62, 53, 44);
    ellipse(spikeX+((spikeRow%3)*10+5), spikeY+(spikeCollumn*10), 10, 5);
    // spikes
    fill(170, 163, 155);
    triangle(spikeX+((spikeRow%3)*10), spikeY+(spikeCollumn*10), spikeX+((spikeRow%3)*10)+10, spikeY+(spikeCollumn*10), spikeX+((spikeRow%3)*10)+5, spikeY+(spikeCollumn*10)-(spikeState*5));
    // checkering effect
    spikeRow++;
    if (spikeRow%3==0) {
      spikeCollumn++;
    };
  }
}

//
///
//// DARTS
///
//

void drawTrapDarts() {
  // blowhole in the wall
  noStroke();
  fill(80, 80, 80);
  ellipse(210, 90, 10, 10);
  // preassure plate 1
  if (dartTrigger1 == true) {
    fill(165, 165, 165);
    rect(170, 215, 25, 25);
  } else if (dartTrigger1 == false) {
    fill(165, 165, 165);
    rect(170, 210, 25, 25);
    fill(80, 80, 80);
    rect(170, 235, 25, 5);
  }

  // preassure plate 2
  if (dartTrigger2 == true) {
    fill(165, 165, 165);
    rect(225, 215, 25, 25);
  } else if (dartTrigger2 == false) {
    fill(165, 165, 165);
    rect(225, 210, 25, 25);
    fill(80, 80, 80);
    rect(225, 235, 25, 5);
  }

  // draw darts
  if (dartMoving == true) {
    fill(0);
    stroke(0);
    strokeWeight(2);
    line(210, dart1Y, 210, dart1Y+10);
    triangle(210, dart1Y+10, 210-2, dart1Y+10-2, 210+2, dart1Y+10-2);
    line(210, dart2Y, 210, dart2Y+10);
    triangle(210, dart2Y+10, 210-2, dart2Y+10-2, 210+2, dart2Y+10-2);
    line(210, dart3Y, 210, dart3Y+10);
    triangle(210, dart3Y+10, 210-2, dart3Y+10-2, 210+2, dart3Y+10-2);
    line(210, dart4Y, 210, dart4Y+10);
    triangle(210, dart4Y+10, 210-2, dart4Y+10-2, 210+2, dart4Y+10-2);
  }
}

//
///
//// FIRE
///
//
void drawTrapFire() {
  // draw oil
  noStroke();
  fill(0);
  rect(260, 110, 10, 250);
  // draw fire tips
  fill(255, 0, 0);
  ellipse(fireX+3+random(1, 14), fireY+3, 6, 6);
  ellipse(fireX+3+random(1, 14), fireY+3, 6, 6);
  ellipse(fireX+3+random(1, 14), fireY+3, 6, 6);
  // draw fire arms
  fill(255, 30, 30);
  ellipse(fireX+5+random(1, 10), fireY+8, 10, 10);
  ellipse(fireX+5+random(1, 10), fireY+8, 10, 10);
  // draw fire neck
  fill(255, 60, 60);
  ellipse(fireX+7+random(1, 6), fireY+15, 14, 14);
  // draw fire body
  fill(255, 70, 70);
  ellipse(fireX+10, fireY+20, 20, 20);
}

//
///
//// SAWBLADE
///
// 

void drawTrapSawblade() {
  // draw saw path
  noStroke();
  fill(62, 53, 44);
  rect(310, 110, 5, 400);
  // draw saw base
  fill(150, 150, 150);
  rect(sawX, sawY, 15, sawHeight);
  // draw saw teeth effect
  int firstBladeY = int(sawY);
  int firstBladeHeight=10;
  int lastBladeHeight = 10;
  if ((int(sawY)/10)%2==0) {
    firstBladeHeight = int(sawY)%10;
  } else {
    firstBladeY += int(sawY)%10;
  }
  if (int(sawY)<firstBladeY) {
    lastBladeHeight = 10- (firstBladeY - int(sawY));
  }

  fill(0, 0, 0, 50);

  rect(sawX, firstBladeY, 15, firstBladeHeight);
  rect(sawX, firstBladeY+firstBladeHeight+10, 15, 10);
  rect(sawX, firstBladeY+firstBladeHeight+30, 15, lastBladeHeight);
}

//
///
//// COLLISION CHECK
///
//

void checkCollision() {
  // player - artifact collision
  if (playerPositionX >= 330 && artifactObtained == false) {
    playerDirection = false;
    artifactObtained = true;
    timeLimit+=(30*1000);
  }
  // player - door collision
  if (playerPositionX <= 30 && artifactObtained == true) {
    winCondition = true;
  }
  // player - electric collision
  if ((playerPositionX+playerWidth>=75&&playerPositionX<=105)&&(playerPositionY<=(electricTopY+electricHeight-20)&&playerPositionY+playerHeight>=electricTopY)) {
    artifactObtained = false;
    playerDirection = true;
    playerPositionX = 30;
    health--;
    dartTrigger1 = false;
    dartTrigger2 = false;
    dartFireCount=0;
    dartMoving = false;
  }
  // player - spike collision
  if ((playerPositionX+playerWidth>=spikeX&&playerPositionX<=spikeX+30)&&spikeState == 2) {
    artifactObtained = false;
    playerDirection = true;
    playerPositionX = 30;
    health--;
    dartTrigger1 = false;
    dartTrigger2 = false;
    dartFireCount=0;
    dartMoving = false;
  }
  // player - dart plate 1 collision
  if ((playerPositionX+playerWidth>=165&&playerPositionX<=190)&&(dartTrigger1!=true)) {
    dartTrigger1 = true;
    dartFireDelay = time;
    dartFireCount=0;
  }
  // player - dart plate 2 collision
  if ((playerPositionX+playerWidth>=225&&playerPositionX<=250)&&(artifactObtained == true)&&(dartTrigger2!=true)) {
    dartTrigger2 = true;
    //dartFireCount=0;
    dartFireDelay = time+(1.5*1000);
  }
  // player - dart collision
  if ((playerPositionX+playerWidth>=210&&playerPositionX<=210)&&((playerPositionY<=(dart1Y+10-20)&&playerPositionY+playerHeight>=dart1Y)||(playerPositionY<=(dart2Y+10-20)&&playerPositionY+playerHeight>=dart2Y)||(playerPositionY<=(dart3Y+10-20)&&playerPositionY+playerHeight>=dart3Y)||(playerPositionY<=(dart4Y+10-20)&&playerPositionY+playerHeight>=dart4Y))) {
    artifactObtained = false;
    playerDirection = true;
    playerPositionX = 30;
    health--;
    dartTrigger1 = false;
    dartTrigger2 = false;
    dartFireCount=0;
    dartMoving = false;
  }
  // player - fire collision
  if ((playerPositionX+playerWidth>=fireX&&playerPositionX<=fireX+20)&&(playerPositionY<=(fireY+30-20)&&playerPositionY+playerHeight>=fireY)) {
    artifactObtained = false;
    playerDirection = true;
    playerPositionX = 30;
    health--;
    dartTrigger1 = false;
    dartTrigger2 = false;
    dartFireCount=0;
    dartMoving = false;
  }
  // player - saw collision
  if ((playerPositionX+playerWidth>=sawX&&playerPositionX<=sawX+15)&&(playerPositionY<=(sawY+50-20)&&playerPositionY+playerHeight>=sawY)) {
    artifactObtained = false;
    playerDirection = true;
    playerPositionX = 30;
    health--;
    dartTrigger1 = false;
    dartTrigger2 = false;
    dartFireCount=0;
    dartMoving = false;
  }
}

void updateScore() {
  // check for win/lose
  if (artifactObtained == true && playerPositionX == 30) {
    winCondition = true;
  } else if ((time >= timeLimit || health == 0) && winCondition == false) {
    loseCondition = true;
  }
}

//
///
//// USER INTERFACE
///
//

void drawUI() {

  noStroke();

  if (winCondition == true) {
    // win screen (American Flag)
    // base
    fill(255);
    rect(0, 0, width, height);
    // stripes
    fill(255, 0, 0);
    for (int flagStripes = 0; flagStripes<13; flagStripes++) {
      if (flagStripes%2 == 0) {
        rect(0, (height/19.4)*flagStripes, width, height/19.4);
      }
    }
    // corner (blue)
    fill(0, 0, 128);
    rect(0, 0, width/2, (height/26)*11);
    // stars
    fill(255);
    int starCollumn = 0;
    int starSide = 16;
    for (int starRow = 0; starRow<99; starRow++) {
      // for the checkering
      if (starRow!=0&&starRow%11==0) {
        starCollumn++;
      };
      // top point
      triangle(12+(starSide/2)+((starRow)%11)*starSide, 12+(starCollumn*starSide), 12+(((starSide/5)*4)+((starRow)%11)*starSide), 12+starSide+(starCollumn*starSide), 12+(((starSide/3))+((starRow)%11)*starSide), 12+((starSide/3)*2)+(starCollumn*starSide));
      // star arms
      triangle(12+((starRow)%11)*starSide, 12+((starSide/5)*2)+(starCollumn*starSide), 12+(starSide)+((starRow)%11)*starSide, 12+((starSide/5)*2)+(starCollumn*starSide), 12+(starSide/2)+((starRow)%11)*starSide, 12+((starSide/5)*4)+(starCollumn*starSide));
      // remaining leg
      triangle(12+(starSide/2)+((starRow)%11)*starSide, 12+(starCollumn*starSide), 12+(((starSide/5))+((starRow)%11)*starSide), 12+starSide+(starCollumn*starSide), 12+(((starSide/3)*2)+((starRow)%11)*starSide), 12+((starSide/3)*2)+(starCollumn*starSide));

      // for the checkering
      starRow++;
      if (starRow%11==0) {
        starCollumn++;
      };
    }
  } else if (loseCondition == true) {
    // lose screen
    fill(0);
    rect(0, 0, width, height);
  } else {
    // time bar
    fill(32, 178, 170);
    rect(0, 0, (timeLimit-time)/(timeLimit/400), 30);
    // front wall
    fill(152, 55, 55);
    rect(0, 0+((height/4)*3), width, height/4);
    // brick pattern
    strokeWeight(1);
    stroke(175, 88, 88);
    for (int brickVertical = 0; brickVertical<17; brickVertical++) {
      for (int brickHorizontal = 0; brickHorizontal<50; brickHorizontal++) {
        line((brickHorizontal*15), ((height/4)*3)+(brickVertical*10), ((brickHorizontal+1)*15), ((height/4)*3)+((brickVertical)*10));
        line(((brickVertical%2)*5)+(brickHorizontal*15), ((height/4)*3)+(brickVertical*10), ((brickVertical%2)*5)+(brickHorizontal*15), 10+((height/4)*3)+((brickVertical)*10));
      }
    }
    // front wall plate (for UI)
    noStroke();
    fill(152, 55, 55);
    rect((width/5), ((height/10)*8)-9, (width/5)*3, (height/15)*3+1);
    // artifact obtained indicator
    if (artifactObtained == true) {
      fill(147, 112, 219);
      rect(275, 360, 20, 30);
    }
    // health hearts (12 points, 3 hearts, 4 quarters per heart
    for (int healthParts = health; healthParts>0; healthParts--) {
      fill(255, 0, 0);
      if (healthParts%4==0) {
        arc((width/2)-140+(30*(healthParts/2)), 370-9, 15, 15, radians(180), radians(360));
      }
      if (healthParts%4==1) {
        arc((width/2)-95+(30*(healthParts/2)), 370-9, 15, 15, radians(180), radians(360));
      }
      if (healthParts%4==2) {
        triangle((width/2)-132+(30*(healthParts/2)), 370-9, (width/2)-117+(30*(healthParts/2)), 370-9, (width/2)-117+(30*(healthParts/2)), 390-9);
      }
      if (healthParts%4==3) {
        triangle((width/2)-117+(30*(healthParts/2)), 370-9, (width/2)-102+(30*(healthParts/2)), 370-9, (width/2)-117+(30*(healthParts/2)), 390-9);
      }
    }
  }

  // "Democracy" title
  fill(255, 20, 20);
  textSize(44);
  text("Democracy", 80, 344);
  noStroke();
}