///////////////////////////////
//////SUPER BOX SHOOTER////////
///////////////////////////////
//Oct 22nd 2016
//Intro to Media Computation
//Instructor: Nicolas Hesler
//Created by: William Lu
//WASD or ARROW KEYS to move. Hold SPACE to shoot.
//Destroy as many boxes as you can!
//Don't touch them!
//I know, the game isn't very balanced.
//Defining objects as each class
Player mainChar;
Platform base1;
Platform base2;
Platform middle;
Platform mid2;
Platform mid3;
Platform mid4;
Platform top;
Spawner spawner;
Enemy[] e;
Game_State gs;
Wall leftWall;
Wall rightWall;
Wall topw1;
Wall topw2;
Wall bot1;
Wall bot2;
//boolean to check if the main character is on the ground
boolean grounded;
int arrayN;
boolean[] groundCheck;
//player dead
boolean pDead;
ArrayList<Bullet> bullets;
//player movement
boolean playerRight;
boolean playerLeft;
boolean playerUp;
boolean playerShoot;
boolean facingRight = true;
boolean facingLeft = false;
//The last button held down by the user. 1 = right, 2 =left
int lastHeldButton = 1;
//# of enemies
int enemyNum = 1000;
float gravity;
void setup () {
size (600, 400);
frameRate(60);
noStroke();
//spawner = new Spawner();
//defining the objects
mainChar = new Player();
base1 = new Platform(0, 400, 260, 380, 0);
base2 = new Platform(340, 400, 600, 380, 1);
middle = new Platform(150, 295, 450, 280, 2);
mid2 = new Platform(0, 195, 200, 180, 3);
mid3 = new Platform(400, 195, 600, 180, 4);
mid4 = new Platform(250, 95, 350, 80, 5);
top = new Platform(0, 20, 600, 0, 6);
rightWall = new Wall( 580, 400, 600, 0);
leftWall = new Wall( 0, 400, 20, 0);
spawner = new Spawner();
bullets = new ArrayList<Bullet>();
e = new Enemy[enemyNum];
gs = new Game_State();
//assigns random constructor variables for enemies. random speed, and random paths. numbers each monster.
for (int i = 0; i<enemyNum; i++) {
e[i] = new Enemy( random( 0.8, 1.2), int(random(1, 5)), i);
}
facingRight = true;
facingLeft = false;
groundCheck = new boolean[10];
arrayN = 0;
grounded = false;
}
void draw () {
background (255);
if (bullets==null) {
return;
}
bullets.add(new Bullet());
//draws every bullet all at once
for (int i=0; i<bullets.size(); i++) {
Bullet bullet=bullets.get(i);
bullet.update();
bullet.hit();
bullet.display();
}
//removes the first bullet from the array once max size is reached
if (bullets.size() > 100) {
bullets.remove(0);
}
top.display();
top.collisionCheck();
spawner.display();
spawner.updateCounter();
direction();
mainChar.update();
mainChar.display();
updateGravity();
base1.display();
base1.collisionCheck();
base2.display();
base2.collisionCheck();
middle.display();
middle.collisionCheck();
middle.sideCollisionCheck();
mid2.display();
mid2.collisionCheck();
mid2.sideCollisionCheck();
mid3.display();
mid3.collisionCheck();
mid3.sideCollisionCheck();
mid4.display();
mid4.collisionCheck();
mid4.sideCollisionCheck();
leftWall.display();
leftWall.sideCollisionCheck();
rightWall.display();
rightWall.sideCollisionCheck();
keyPresses();
grounding();
gs.playerDeath();
gs.updateScore();
//text used for debugging
//fill (0);
//text (mainChar.position.x + " " + mainChar.position.y, 100, 100);
//text (mainChar.velocity.x + " " + mainChar.velocity.y, 100, 120);
//text (mainChar.acceleration.x + " " + mainChar.acceleration.y, 100, 140);
//println (grounded, facingRight, s.counter, e[0].hp, pDead, gs.score);
}
void keyPresses() {
//key press visuals
//up
rectMode(CENTER);
if (playerUp == true) {
//slowly fades away over time
fill(0, 175 - frameCount/3);
} else {
fill ( 150, 175 - frameCount/3);
}
rect ( 250, 180, 15, 15);
//space
if (playerShoot == true) {
fill(0, 175 - frameCount/3);
} else {
fill ( 150, 175 - frameCount/3);
}
rect ( 335, 200, 90, 15);
//left
if (playerLeft == true) {
fill(0, 175 - frameCount/3);
} else {
fill ( 150, 175 - frameCount/3);
}
rect ( 230, 200, 15, 15);
//right
if (playerRight == true) {
fill(0, 175 - frameCount/3);
} else {
fill ( 150, 175 - frameCount/3);
}
rect ( 270, 200, 15, 15);
//down
fill ( 150, 175 - frameCount/3);
rect ( 250, 200, 15, 15);
}
void updateGravity () {
if (grounded == true) {
//no gravity if player is on the ground. DONT do this in your own code, I approached this wrong. gravity should never change
gravity = 0;
} else {
gravity = 0.07;
}
}
void grounding() {
//Check every platform to see if a player is standing on any of them. if true, then grounded = true
for (arrayN=0; arrayN < 9; arrayN = arrayN +1) {
if (groundCheck[arrayN] == true) {
grounded = true;
} else if (groundCheck [arrayN] == false) {
}
}
if (arrayN == 9) {
arrayN = 0;
}
}
void keyPressed() {
if (key == 'a' || key == 'A' || keyCode == LEFT) {
playerLeft = true;
lastHeldButton = 2;
}
if (key == 'd' || key == 'D' || keyCode == RIGHT) {
playerRight = true;
lastHeldButton = 1;
}
if (key == 'w' || key == 'W' || keyCode == UP) {
playerUp = true;
}
if (key == ' ') {
playerShoot = true;
}
}
void keyReleased() {
if (key == 'a' || key == 'A' || keyCode == LEFT) {
playerLeft = false;
}
if (key == 'd' || key == 'D' || keyCode == RIGHT) {
playerRight = false;
}
if (key == 'w'|| key == 'W' || keyCode == UP) {
playerUp = false;
}
if (key == ' ') {
playerShoot = false;
}
}
void mousePressed() {
//if you die, and you click the mouse, all the variables are reset
if (pDead == true) {
mainChar = new Player();
base1 = new Platform(0, 400, 260, 380, 0);
base2 = new Platform(340, 400, 600, 380, 1);
middle = new Platform(150, 295, 450, 280, 2);
mid2 = new Platform(0, 195, 200, 180, 3);
mid3 = new Platform(400, 195, 600, 180, 4);
mid4 = new Platform(250, 95, 350, 80, 5);
top = new Platform(0, 20, 600, 0, 6);
rightWall = new Wall( 580, 400, 600, 0);
leftWall = new Wall( 0, 400, 20, 0);
spawner = new Spawner();
bullets = new ArrayList<Bullet>();
e = new Enemy[enemyNum];
gs = new Game_State();
for (int i = 0; i<enemyNum; i++) {
e[i] = new Enemy( 1, int(random(1, 5)), i);
}
pDead = false;
}
}
void direction() {
//determines the direction you're facing based on your x axis acceleration
if (mainChar.acceleration.x > 0) {
facingRight = true;
facingLeft = false;
}
if (mainChar.acceleration.x < 0) {
facingLeft = true;
facingRight = false;
}
}class Bullet {
PVector position = new PVector(mainChar.position.x, mainChar.position.y);
PVector velocity = new PVector(0, 0);
//hit position
PVector hitPos = new PVector();
boolean exit = false;
boolean control = true;
boolean shot = false;
boolean wallHit = false;
//monster hit
boolean monHit = false;
int hitAnim = 0;
void update() {
// if the bullet hasn't left the chamber, then it's inside the player.
if (exit == false || wallHit == true) {
position.x = mainChar.position.x;
position.y = mainChar.position.y;
control = true;
}
//when you press space, the bullet exits. restricted by frame count so you dont shoot like crazy when you hold down space.
if (playerShoot == true && shot == false &&frameCount% 15 ==0 && pDead == false) {
exit = true;
}
// when the bullet exits:
if (exit == true && wallHit == false) {
//shoots bullet right if facing right. can no longer control the direction of the bullet based on where you are facing
if (facingRight ==true &&control == true) {
position.x = mainChar.position.x+15;
velocity.x = abs(mainChar.velocity.x) +6;
control = false;
shot = true;
//bullet left
} else if (facingLeft ==true &&control == true) {
position.x = mainChar.position.x-15;
velocity.x =-abs(mainChar.velocity.x)-6;
control = false;
shot = true;
}
}
//if bullet somehow exits the screen
if (position.x > width || position.x < 0 && exit == true && shot == true) {
position.x = mainChar.position.x;
position.y = mainChar.position.y;
exit = false;
}
//Controls bullet position
position.add(velocity);
}
void hit() {
//collision for Walls. If the bullet hit the wall, play the animation
if (position.x + 5> rightWall.x1 || position.x - 5< leftWall.x2) {
hitAnim = 1;
}
//platform collision for middle
if (position.x -5 < middle.x2 && position.x +5 > middle.x1&& position.y-5< middle.y1 && position.y+5> middle.y2 && hitAnim ==0) {
hitAnim = 1;
}
//mid2
if (position.x -5 < mid2.x2 && position.x +5 > mid2.x1&& position.y-5< mid2.y1 && position.y+5> mid2.y2 && hitAnim ==0) {
hitAnim = 1;
}
//mid3
if (position.x -5 < mid3.x2 && position.x +5 > mid3.x1&& position.y-5< mid3.y1 && position.y+5> mid3.y2 && hitAnim ==0) {
hitAnim = 1;
}
//mid4
if (position.x -5 < mid4.x2 && position.x +5 > mid4.x1&& position.y-5< mid4.y1 && position.y+5> mid4.y2 && hitAnim ==0) {
hitAnim = 1;
}
//bullet monster hit collision
//numbers every monster, using i.
for (int i =0; i<enemyNum; i++) {
//checks the collision of every bullet and every enemy at once. if the bullet enters ANY enemy:
if (pDead == false && e[i].bottomLeft.x <= position.x + 5 && e[i].topRight.x >= position.x - 5) {
if (monHit == false && e[i].topRight.y - 15 <= position.y + 5 && e[i].bottomLeft.y >= position.y - 5) {
//plays animation, enemyHP goes down
velocity.x = 0;
hitAnim = 1;
e[i].hp--;
monHit = true;
}
}
}
//bullet explosion animation
if (hitAnim == 1) {
wallHit = true;
hitAnim = 2;
hitPos = position;
fill( 255, 41, 41);
rectMode (CENTER);
rect (hitPos.x, hitPos.y, 25, 25);
}
}
void display() {
if (exit == true && wallHit == false) {
fill( 255, 87, 41);
rectMode (CENTER);
rect (position.x, position.y, 10, 10);
}
}
}class Enemy {
PVector position= new PVector(width/2, 0);
PVector bottomLeft = new PVector();
PVector topRight = new PVector();
PVector velocity= new PVector();
PVector acceleration= new PVector();
// determines which path the enemy takes
int path;
// which stage of the path the enemy is on
int pathStage =1;
int hp = 20;
int monNum;
float eGravity = 0.07;
float speed;
float radius = 12;
boolean spawned = false;
boolean dead;
//constructors for each enemy, speed, the path it takes, and the assigned # of each monster
Enemy(float tempSpeed, int tempPath, int tempMonNum) {
speed = tempSpeed;
path = tempPath;
monNum = tempMonNum;
}
void update() {
// PVectors for the corners of the enemy, just to make things easier
bottomLeft.x = position.x-radius;
bottomLeft.y = position.y+radius;
topRight.x = position.x+radius;
topRight.y = position.y-radius;
//death check
if (hp <0) {
spawned = false;
dead = true;
gs.score++;
hp=3;
}
//Spawning, counter is controlled by the spawner class
if (spawner.counter== monNum && spawned == false) {
position.y =0;
spawned = true;
//if hasn't spawned, stays off screen
} else if (spawned == false|| dead == true) {
position.y = -200;
position.x = width/2;
velocity.x = 0;
velocity.y =0;
acceleration.y =0;
}
//terminal horizontal velocity
if (velocity.x >1.5) {
velocity.x = 1.5*speed;
} else if (velocity.x < -1.5) {
velocity.x = -1.5*speed;
}
//horizontal movement controls
//left spawn
if (path ==1) {
//when it hits the wall, go to stage 2
if (bottomLeft.x < leftWall.x2) {
pathStage = 2;
}
if (topRight.x > rightWall.x1) {
pathStage = 4;
}
if (pathStage == 1) {
acceleration.x = -0.5;
} else if (pathStage == 2) {
//turns around
acceleration.x = 0.5;
} else if (pathStage == 4) {
acceleration.x = -0.5;
}
}
//left-right spawn
if (path ==2) {
if (bottomLeft.x < leftWall.x2) {
pathStage = 2;
}
//when it reaches the center, reach stage 3
if (topRight.x > width/2+50) {
pathStage = 3;
}
if (pathStage == 1) {
acceleration.x = -0.5;
} else if (pathStage == 2) {
acceleration.x = 0.5;
} else if (pathStage == 3) {
acceleration.x = -0.5;
}
}
//right spawn
if (path ==3) {
if (bottomLeft.x < leftWall.x2) {
pathStage = 2;
}
if (topRight.x > rightWall.x1) {
pathStage = 4;
}
if (pathStage == 1) {
acceleration.x = 0.5;
} else if (pathStage == 2) {
acceleration.x = 0.5;
} else if (pathStage == 4) {
acceleration.x = -0.5;
}
}
//right-left spawn
if (path ==4) {
if (topRight.x > rightWall.x1) {
pathStage = 2;
}
if (bottomLeft.x < width/2-50) {
pathStage = 3;
}
if (pathStage == 1) {
acceleration.x = 0.5;
} else if (pathStage == 2) {
acceleration.x = -0.5;
} else if (pathStage == 3) {
acceleration.x = 0.5;
}
}
//vertical movement controls
// controls collision based on which platform
//for mid4
if (bottomLeft.y> mid4.y2 && topRight.y < mid4.y1 && bottomLeft.x < mid4.x2 && topRight.x > mid4.x1) {
position.y = mid4.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//for mid3
if (bottomLeft.y> mid3.y2 && topRight.y < mid3.y1 && bottomLeft.x < mid3.x2 && topRight.x > mid3.x1) {
position.y = mid3.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//for mid2
if (bottomLeft.y> mid2.y2 && topRight.y < mid2.y1 && bottomLeft.x < mid2.x2 && topRight.x > mid2.x1) {
position.y = mid2.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//for middle
if (bottomLeft.y> middle.y2 && topRight.y < middle.y1 && bottomLeft.x < middle.x2 && topRight.x > middle.x1) {
position.y = middle.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//for base1
if (bottomLeft.y> base1.y2 && topRight.y < base1.y1 && bottomLeft.x < base1.x2 && topRight.x > base1.x1) {
position.y = base1.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//for base2
if (bottomLeft.y> base2.y2 && topRight.y < base2.y1 && bottomLeft.x < base2.x2 && topRight.x > base2.x1) {
position.y = base2.y2 - radius;
velocity.y = 0;
acceleration.y=0;
}
//as long as it's alive, it moves
if (dead == false) {
acceleration.y += eGravity;
velocity.add(acceleration);
position.add(velocity);
}
}
void playerCollision() {
//if enemy touches the player, you die
if (mainChar.position.x - 15 <= position.x + radius && mainChar.position.x +15 >= position.x - radius) {
if (mainChar.position.y - 15 <= position.y + radius && mainChar.position.y + 15 >= position.y - radius) {
pDead = true;
}
}
}
void display() {
fill(53, 129, 184);
rectMode(CORNERS);
if (dead == false) {
rect (bottomLeft.x, bottomLeft.y, topRight.x, topRight.y);
}
// noStroke();
}
}