/*
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
}