Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/*
 Interactive Toy: Asteroid Avoid by Lori Sengbusch
 Avoid asteroids, every one passed increases score.
 Move ship horizontally with mouse
 Game over when hit
 */

//declare variables
int exhaustHeight, exhaustHeightSmall;
int starPosX, starPosY;
//start asteroids at random X positions each
int asteroidOneX = int(random(0, 400)), asteroidOneY = 0; 
int asteroidTwoX = int(random(0, 400)), asteroidTwoY = -150;
int asteroidThreeX = int(random(0, 400)), asteroidThreeY = -300;
int asteroidWidth =30;
int asteroidHeight = 45;
int asteroidSpeed = 8;
int asteroidHole, holeX;
int score = 0;
boolean playerHit = false;
boolean gameStart = false;
int startTime, timePassed;
int scorePosX, scorePosY;

void setup() {
  size(400, 400);
}

void draw() {
  background(0, 0, 100);
  if (!gameStart) {
    //wait until mouse is clicked to start game
    if (mousePressed) {
      gameStart = true;
      startTime = millis();//time game actually started at
    } else {
      clickToPlay(); //draw instructions if game hasn't started
    }
  } else {
    //start counting time
    timePassed = millis() - startTime; //subtract startTime for real current time

    //draw background & stars
    drawSpace();
    drawStars();
    //randomize exhaust height before drawing ship
    exhaustHeight = height - int(random(1, 10));
    exhaustHeightSmall = height - int(random(10, 15));
    drawSpaceship(exhaustHeight, exhaustHeightSmall);

    //draw asteroids
    drawAsteroid(asteroidOneX, asteroidOneY);
    drawAsteroid(asteroidTwoX, asteroidTwoY);
    drawAsteroid(asteroidThreeX, asteroidThreeY);

    //move asteroids
    moveAsteroids();

    //increase drop speed after various time passed, divide because milliseconds
    if ((timePassed / 1000) > 5) {
      asteroidSpeed = 12;
    } else if ((timePassed / 1000) > 20) {
      asteroidSpeed = 16;
    }
    //check for hits if player hasn't been hit yet
    if (!playerHit) {
      hitDetetion();
    }

    //draw score based on digits
    if (score < 10) {
      drawScore(score, 0);
    } else if  (score >= 10000) {
      score = 0; //reset score after exceeding 9999
    } else if (score >= 1000) {
      //depending on scores number of digits, find and draw them
      int firstDigit = digitAt(score, 4);
      int secondDigit = digitAt(score, 3);
      int thirdDigit = digitAt(score, 2);
      int fourthDigit = digitAt(score, 1);
      drawScore(firstDigit, 3);
      drawScore(secondDigit, 2);
      drawScore(thirdDigit, 1);
      drawScore(fourthDigit, 0);
    } else if (score >= 100) {
      int firstDigit = digitAt(score, 3);
      int secondDigit = digitAt(score, 2);
      int thirdDigit = digitAt(score, 1);
      drawScore(firstDigit, 2);
      drawScore(secondDigit, 1);
      drawScore(thirdDigit, 0);
    } else if (score >= 10) {
      int firstDigit = digitAt(score, 2);
      int secondDigit = digitAt(score, 1);
      drawScore(firstDigit, 1);
      drawScore(secondDigit, 0);
    }
  }
}

void drawSpaceship(int exhaustHeight, int exhaustHeightSmall) {
  //drawing spaceship
  //exhaust pipes
  noStroke();
  rectMode(CENTER);
  fill(0);
  rect((mouseX-8), (height-35), 8, 15);
  rect((mouseX+8), (height-35), 8, 15);
  //create base
  fill(255);
  triangle(mouseX, (height-100), mouseX-20, (height-40), mouseX+20, (height-40));
  //wings
  triangle(mouseX, (height-70), mouseX-40, (height-45), mouseX+40, (height-45));
  //window
  fill(0);
  stroke(255);
  strokeWeight(1);
  quad(mouseX-5, height-85, mouseX+5, height-85, mouseX+8, height-75, mouseX-8, height-75);

  //exhaust flames left
  noStroke();
  fill(255, 0, 0, 200);
  ellipse((mouseX-8), (height-20), 8, 8);
  triangle((mouseX-12), (height-20), (mouseX-4), (height-20), (mouseX-8), (exhaustHeight)); 
  fill(255, 255, 0, 200);
  ellipse((mouseX-8), (height-20), 4, 4);
  triangle((mouseX-10), (height-20), (mouseX-6), (height-20), (mouseX-8), (exhaustHeightSmall));
  //exhaust flames right
  noStroke();
  fill(255, 0, 0, 200);
  ellipse((mouseX+8), (height-20), 8, 8);
  triangle((mouseX+12), (height-20), (mouseX+4), (height-20), (mouseX+8), (exhaustHeight)); 
  fill(255, 255, 0, 200);
  ellipse((mouseX+8), (height-20), 4, 4);
  triangle((mouseX+10), (height-20), (mouseX+6), (height-20), (mouseX+8), (exhaustHeightSmall));
}

void drawStars() {
  stroke(255);
  strokeWeight(2);
  //loop for many stars, different position each iteration
  for (int i=0; i<10; i++) {
    stroke(255);
    strokeWeight(2);
    ///star
    starPosX = int(random(0, width));
    starPosY = int(random(0, height));
    point(starPosX, starPosY);
    //outer glow
    stroke(255, 50);
    strokeWeight(5);
    point(starPosX, starPosY);
  }
}

void drawAsteroid(int x, int y) {
  //asteroid body
  ellipseMode(CENTER);
  fill(100);
  ellipse(x, y, asteroidWidth, asteroidHeight);
  fill(75);
  asteroidHole = 5;
  holeX = 5;
  //draw multiple holes in asteroid
  for (int i=0; i<2; i++) {
    ellipse(x+10-holeX, y-15+asteroidHole, 10, 10);
    asteroidHole+=20;
    holeX+=5;
  }
}

void moveAsteroids() {
  asteroidOneY+= asteroidSpeed;
  asteroidTwoY+= asteroidSpeed;
  asteroidThreeY+= asteroidSpeed;

  //once an asteroid is offscreen, move it back to the top
  if (asteroidOneY > 400+asteroidHeight) {
    asteroidOneX = int(random(0, 400));
    asteroidOneY = -asteroidHeight;
    score++; //increment score for every asteroid passed;
  }

  if (asteroidTwoY > 400+asteroidHeight) {
    asteroidTwoX = int(random(0, 400));
    asteroidTwoY = -asteroidHeight;
    score++;
  }

  if (asteroidThreeY > 400+asteroidHeight) {
    asteroidThreeX = int(random(0, 400));
    asteroidThreeY = -asteroidHeight;
    score++;
  }
}

void hitDetetion() {
  //check for hit detection
  //if mouseX(where the player is located) is anywhere in between the position of the asteroid
  //and the asteroid is at the ships Y location then ship is hit
  //asteroids can actually pass through wings but not main body
  if ((mouseX <=  (asteroidOneX+(asteroidWidth/2)) && mouseX >=  (asteroidOneX-(asteroidWidth/2)))  && (asteroidOneY >= height-100) && (asteroidOneY <= height-35)) {
    drawCollision(asteroidOneX, asteroidOneY);
    playerHit = true;
    println("Game Over!\nScore: " + score);
     //stops draw from looping when game over
    
  } else if ((mouseX <=  (asteroidTwoX+(asteroidWidth/2)) && mouseX >=  (asteroidTwoX-(asteroidWidth/2)))  && (asteroidTwoY >= height-100) && (asteroidTwoY <= height-35)) {
    drawCollision(asteroidTwoX, asteroidTwoY);
    playerHit = true;
    println("Game Over!\nScore: " + score);
    
  } else if ((mouseX <=  (asteroidThreeX+(asteroidWidth/2)) && mouseX >=  (asteroidThreeX-(asteroidWidth/2)))  && (asteroidThreeY >= height-100) && (asteroidThreeY <= height-35)) {
    drawCollision(asteroidThreeX, asteroidThreeY);
    playerHit = true;
    println("Game Over!\nScore: " + score);
    
  }
}

void drawCollision(int x, int y) {
  //collision is drawn based on xPos and yPos of the asteroid
  ellipseMode(CENTER);
  fill(255, 100, 0, 100);
  ellipse(x, y, 50, 50);
  fill(255, 200, 0, 100);
  ellipse(x, y, 20, 20);
}

void clickToPlay() {
  strokeWeight(5);
  stroke(255);

  //C
  line(80, 100, 80, 160);
  line(80, 100, 100, 100);
  line(80, 160, 100, 160);
  //L
  line(120, 100, 120, 160);
  line(120, 160, 140, 160);
  //I
  line(160, 100, 160, 160);
  //C
  line(180, 100, 180, 160);
  line(180, 100, 200, 100);
  line(180, 160, 200, 160);
  //K
  line(220, 100, 220, 160);
  line(240, 100, 220, 130);
  line(240, 160, 220, 130);

  //T
  line(180, 180, 180, 240);
  line(160, 180, 200, 180);
  //O
  line(220, 180, 220, 240);
  line(240, 180, 240, 240);
  line(220, 180, 240, 180);
  line(220, 240, 240, 240);

  //P
  line(200, 260, 200, 320);
  line(220, 260, 220, 280);
  line(200, 260, 220, 260);
  line(200, 280, 220, 280);
  //L
  line(240, 260, 240, 320);
  line(240, 320, 260, 320);
  //A
  line(280, 260, 280, 320);
  line(300, 260, 300, 320);
  line(280, 280, 300, 280);
  line(280, 260, 300, 260);
  //Y
  line(340, 260, 340, 320);
  line(320, 260, 340, 290);
}

void drawScore(int digit, int digitPos) {
  stroke(255);
  strokeWeight(2);
  scorePosY = 20;

  //change where the digit is drawn based on how large the number is, digitPos passed prior as arguments
  if (digitPos == 0) {
    scorePosX = 360;
  } else if (digitPos == 1) {
    scorePosX = 320;
  } else if (digitPos == 2) {
    scorePosX = 280;
  } else if (digitPos == 3) {
    scorePosX = 240;
  }

  //draw digit needed
  if (digit == 0) {
    //draw 0
    line(scorePosX, scorePosY, scorePosX, scorePosY+40);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
  } else if (digit==1) {
    //draw 1
    line(scorePosX, scorePosY, scorePosX, scorePosY+40);
  } else if (digit==2) {
    //draw 2
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY+20, scorePosX, scorePosY+40);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+20);
  } else if (digit==3) {
    //draw 3
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
  } else if (digit==4) {
    //draw 4
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY, scorePosX, scorePosY+20);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
  } else if (digit==5) {
    //draw 5
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY, scorePosX, scorePosY+20);
    line(scorePosX+20, scorePosY+20, scorePosX+20, scorePosY+40);
  } else if (digit==6) {
    //draw 6
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY, scorePosX, scorePosY+40);
    line(scorePosX+20, scorePosY+20, scorePosX+20, scorePosY+40);
  } else if (digit==7) {
    //draw 7
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
  } else if (digit==8) {
    //draw 8
    line(scorePosX, scorePosY+40, scorePosX+20, scorePosY+40);
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY, scorePosX, scorePosY+40);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
  } else if (digit==9) {
    //draw 9
    line(scorePosX, scorePosY, scorePosX+20, scorePosY);
    line(scorePosX, scorePosY+20, scorePosX+20, scorePosY+20);
    line(scorePosX, scorePosY, scorePosX, scorePosY+20);
    line(scorePosX+20, scorePosY, scorePosX+20, scorePosY+40);
  }
}

void drawSpace() {
  //initialized bg colours
  int bgBlue = 50;
  int bgGreen = 0;
  int bgRed = 0;
  //xPos and yPos of bg rectangles
  int x = width/2; 
  int y = 25;
  rectMode(CENTER);
  noStroke();
  //bg colours change with time passed
  if ((timePassed / 1000) < 15) {
    for (int i=0; i<8; i++) {
      fill(bgRed, bgRed, bgBlue);
      rect(x, y, width, height/8);
      bgBlue+=15; //change colours slightly each iteration
      y+=50;
    }
  } else if ((timePassed / 1000) < 30) {
    for (int i=0; i<8; i++) {
      fill(bgRed, bgGreen, bgBlue);
      rect(x, y, width, height/8);
      bgBlue+=15;
      bgGreen+=15;
      y+=50;
    }
  } else if ((timePassed / 1000) < 50) {
    for (int i=0; i<8; i++) {
      fill(bgRed, bgGreen, bgBlue);
      rect(x, y, width, height/8);
      bgBlue+=15;
      bgGreen+=10;
      bgRed+=25;
      y+=50;
    }
  } else {
    for (int i=0; i<8; i++) {
      fill(bgRed, bgGreen, bgBlue);
      rect(x, y, width, height/8);
      bgBlue+=15;
      bgGreen+=15;
      bgRed+=15;
      y+=50;
    }
  }
}

//finding which numbers are at certain digits from https://stackoverflow.com/questions/19063001/extracting-digits-of-int-in-java
//input is the number itself and pos being digit position
int digitAt(int input, int pos) {     
  int i =(int) (input%(Math.pow(10, pos)));
  int j = (int) (i/Math.pow(10, pos-1));
  return Math.abs(j); // abs handles negative input
}