Set 3 AP computer science programming project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

655 lines
19 KiB

/*
Set 3 programming project
5-18-16
*****************Tanks***************
https://github.com/jrtechs/Tanks/wiki
*/
package tanks;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Tanks
{
//fields
private JFrame frame;
private JPanel panel;
private int fheight=650;
private int fwidth=900;
private Timer move;
private KeyListener key;
//game elements
private ArrayList<Bullet> bullets;
private Player p;
private ArrayList<Enemy> enemy;
private Wave wave;
//constructor
public Tanks()
{
frame=new JFrame("Tanks project");
frame.setSize(fwidth,fheight + 150);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newGame();
key=new KeyListener() {
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
{
if(wave.gameMode == 1)
{
wave.setGameMode(3);
}
else if (wave.gameMode == 3)
{
wave.setGameMode(1);
}
}
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{
if(wave.gameMode == 0 || wave.gameMode == 2)
{
newGame();
wave.gameMode = 1;
}
}
p.updateDir(e, true);
}
@Override
public void keyReleased(KeyEvent e)
{
p.updateDir(e, false);
}
};
frame.addKeyListener(key);
panel = new JPanel()
{
protected void paintComponent(Graphics g) {
//Paint Wave
wave.draw(g);
for(Bullet b: bullets) {
b.draw(g);
}
for(Enemy en: enemy) {
en.draw(g);
}
g.setColor(Color.BLACK);
g.fillRect(0, fheight, fwidth, 150);
p.draw(g);
//Game Info Section
//Wave
g.setColor(Color.WHITE);
g.setFont(new Font("Arial" , 1, 25));
g.drawString("Wave: " + wave.waveNum + " Ammo: "+ p.ammo + " Kills: " + wave.kills +" Health: " + p.health + " Time: " + wave.timeCount, 50, fheight + 50);
//Pausing the game
if(wave.gameMode == 3) {
g.setColor(Color.WHITE);
g.setFont(new Font("Arial" , 1, 40));
g.drawString("PAUSED - PRESS ESC TO CONTINUE" , 75, fheight/2);
}
if(wave.gameMode == 2) {
//On screen
g.setColor(Color.RED);
g.setFont(new Font("Arial" , 1, 40));
g.drawString("You Died" , fwidth/2 - 100, fheight/2);
//In black bar
g.setColor(Color.WHITE);
g.setFont(new Font("Arial" , 1, 25));
g.drawString("Press enter to play", 50, fheight + 100);
}
else if(wave.gameMode ==0) {
g.drawString("Press enter to play", 50, fheight + 100);
}
}
};
frame.add(panel);
frame.setVisible(true);
//Timer
//Override
ActionListener tic = e -> {
if(wave.gameMode == 1)
{
p.move();
for(int i = 0; i < bullets.size(); i ++) {
bullets.get(i).move();
}
for(int i = 0; i < enemy.size(); i++) {
enemy.get(i).move();
}
}
wave.waveCheck();
panel.repaint();
};
move = new Timer(30, tic); //Timer that moves things... Moves the player and enemies?
move.start();
}
void newGame()
{
bullets = new ArrayList<>();
enemy = new ArrayList<>();
p = new Player();
wave = new Wave();
}
/*
Sub-classes that require the fields in tanks
*/
/**
* the player class which extends the living class
* a player has a turret and an int kills
* a player has a specialized move method
* a player has a update direction method which takes in a keyevent
*/
private class Player extends Living
{
private Turret t;
private boolean up,down,left,right, rleft, rRight;
private int ammo=10;
private boolean shoot;
ActionListener coolDown = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e) {
if(shoot==false)
{
shoot=true;
}
}
};
Timer time=new Timer(300,coolDown);
public Player()
{
x = frame.getWidth()/2;
y = frame.getHeight()/2;
time.start();
t=new Turret(this);
speed = 5;
health = 100;
this.imageLocation = "player.png";
super.loadImage();
width = 50;
height = 50;
}
void move()
{
if(rleft)
{
t.rotate(-1);
}
if(rRight)
{
t.rotate(1);
}
if(up==true)
{
super.move(-1);
t.move(-1);
}
if(down==true)
{
t.move(1);
super.move(1);
}
if(left==true)
{
super.direction -=5;
t.rotate(-1);
}
if(right==true)
{
super.direction+=5;
t.rotate(1);
}
if(y<=0)
{
y+=speed;
}
else if(x<=0)
{
x+=speed;
}
else if(x>=fwidth-width)
{
x-=speed;
}
else if(y>=fheight-height)
{
y-=speed;
}
t.x = x;
t.y = y;
}
void updateDir(KeyEvent e, boolean pressed) {
int id=e.getKeyCode();
if(id== KeyEvent.VK_UP) {
up=pressed;
}
else if(id==KeyEvent.VK_DOWN) {
down=pressed;
}
else if(id==KeyEvent.VK_LEFT) {
left=pressed;
}
else if(id==KeyEvent.VK_RIGHT) {
right=pressed;
}
else if(id==KeyEvent.VK_A) {
rleft = pressed;
}
else if(id==KeyEvent.VK_D) {
rRight = pressed;
}
else if(id==KeyEvent.VK_R && wave.gameMode ==1) {
ammo=10;
}
else if(id==KeyEvent.VK_SPACE && wave.gameMode !=0) {
if(pressed) {
if (shoot) {
shoot();
shoot=false;
}
}
}
}
void shoot()
{
if(ammo>0) {
bullets.add(new Bullet (t));
ammo--;
}
}
public void draw (Graphics g) {
super.draw(g);
t.draw(g);
}
}
/**
* A zombie extends Enemy
* a zombie has a specialized move method which
* moves it twards the player
*
* the move method checks to see if it collides with the player
* if so it removes itself from the arraylist in tanks and deducts damage
*/
private class Zombie extends Enemy
{
//constructor instanciated fields
public Zombie()
{
super();
spawn(fwidth, fheight);
width = 30;
height = 30;
health = 10;
isAlive=true;
speed = 3;
imageLocation = "zombie.png";
super.loadImage();
}
//uses super to move player if collision then removes zombie and player
//takes damage
public void move() {
direction = angleToPlayer(p);
super.move(-1);
if(this.checkCollision(p)) {
enemy.remove(this);
p.takeDamage();
if(!p.isAlive) {
wave.setGameMode(2);
wave.kills++;
}
}
}
}
/**
* a bullet moves at a specified angle
* if the bullet collides with a enemy it gives damage
* if the bullet goes off the screen it removes itself from the arraylist
*/
private class Bullet extends RotationalElement
{
public boolean enemyBullet; // whether it is an enemy or player bullet
public Bullet(RotationalElement e)
{
width = 25;
height = 25;
x = e.x + 12;
y = e.y + 12;
direction = e.direction;
speed = 10;
imageLocation = "bullet.png";
super.loadImage();
}
//Moving the bullet
public void move() {
super.move(-1);
//Checks if the bullet goes off screen, if so... it get removed
if(x < 0 || x > fwidth) {
bullets.remove(this);
}
if (y < 0 || y > fheight) {
bullets.remove(this);
}
//Checks for collision with enemies, enemy takes damage and byllet is removed
for(int i = 0; i < enemy.size(); i++) {
if(enemyBullet == false) {
boolean collided = this.checkCollision(enemy.get(i));
if(collided) {
enemy.get(i).takeDamage();
bullets.remove(this);
if(!enemy.get(i).isAlive) {
enemy.remove(enemy.get(i));
wave.kills++;
}
}
}
}
//Checking enemy bullet collision with the player, player takes damage and bullet is removed
if(enemyBullet)
{
boolean collided = this.checkCollision(p);
if(collided) {
p.takeDamage();
bullets.remove(this);
if(!p.isAlive) {
wave.setGameMode(2);
}
}
}
}
}
/**
* a turret is drawn ontop of the tank
* a turret can rotate and shoot bullets,
* if rotate is called, put in -1 or 1, if -1, it will
* turn left, 1 will cause
* it to turn right
*/
private class Turret extends RotationalElement {
public Turret(RotationalElement e) {
width = 50;
height = 50;
x = e.x;
y = e.y;
direction = e.direction;
speed = 10;
imageLocation = "turret.png";
super.loadImage();
}
public void rotate(int e) {
super.direction = super.direction + 5*e;
}
}
/*
A version of the emeny tank that arrives at some point
*/
private class Tank extends Enemy
{
Bullet b;
Turret t;
Timer tim;
ActionListener al;
public Tank()
{
super();
enemy.add(this);
this.spawn(fwidth, fheight);
width = 50;
height = 50;
health = 20;
isAlive=true;
speed = 2;
imageLocation = "enemyTank.png";
super.loadImage();
t = new Turret(this);
t.imageLocation = "enemyTurret.png";
t.loadImage();
al = e -> {
if(getAlive()) {
b = new Bullet(t);
b.enemyBullet=true;
bullets.add(b);
}
};
tim = new Timer(3500,al);
tim.start();
}
public void draw (Graphics g) {
super.draw(g);
t.draw(g);
}
public void move() {
if(this.distToPlayer(p)>250) {
direction = angleToPlayer(p);
super.move(-1);
if(this.checkCollision(p)) {
p.takeDamage();
this.takeDamage();
if(isAlive==false) {
enemy.remove(this);
}
if(!p.isAlive) {
wave.setGameMode(2);
}
}
}
t.x=this.x;
t.y=this.y;
t.direction=this.angleToPlayer(p);
}
}
private class Wave extends DrawableElement
{
/**fields time is continous while playing, gameMode(1=playing,
* 2=dead, 3=paused. spawntime keeps a countdown until next spawn,
* kills keeps track of kills duh.
* 4 win
* 1 alive and playing
* 0 main
*/
int timeCount, kills, gameMode, waveNum, spawnedTanks, spawnedZombies;
Timer spawnTank, spawnZombie, time;
//constuctor
public Wave()
{
timeCount=0;
kills=0;
gameMode=0;
waveNum=1;
imageLocation = "wave.jpg";
super.loadImage();
//actionlistener calls spawn every 2 seconds
ActionListener z = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(gameMode == 1) {
spawnZombie();
}
}
};
ActionListener ta = e -> {
if(gameMode ==1)
spawnTank();
};
//action listener increments time
spawnTank = new Timer(2000,ta);
spawnZombie = new Timer(2000, z);
spawnZombie.start();
ActionListener t = new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e) {
if(gameMode==1) {
timeCount++;
}
}
};
time = new Timer(1000,t);
time.start();
}
public void setGameMode(int newGameMode) {
gameMode = newGameMode;
if(gameMode == 2) {
//Player has died, ending the game
time.stop();
//move.stop();
spawnZombie.stop();
spawnTank.stop();
}
else if(gameMode == 4) {
//Player has won
time.stop();
//move.stop();
spawnZombie.stop();
spawnTank.stop();
}
}
//spawn method checks if spawn timer ==0 and if so then spawns an
//enemy
public void spawnTank() {
enemy.add(new Tank());
spawnedTanks++;
}
public void spawnZombie() {
enemy.add(new Zombie());
spawnedZombies++;
}
public void waveCheck()
{
if(gameMode == 1)
{
switch(waveNum)
{
case 1:
if(kills == 15) {
changeWave();
}
break;
case 2:
if(kills == 20) {
changeWave();
}
break;
case 3:
if(kills == 26) {
spawnTank.start();
changeWave();
}
break;
case 4:
if(kills == 32) {
changeWave();
}
break;
case 5:
if(kills == 33) {
changeWave();
}
break;
case 6:
if(kills == 35) {
changeWave();
}
break;
case 7:
if(kills == 37) {
changeWave();
}
break;
case 8:
if(kills == 40) {
changeWave();
}
break;
case 9:
if(kills == 49) {
changeWave();
}
break;
case 10:
if(kills == 60)
{
//Game over
}
break;
}
}
}
public void changeWave() {
waveNum++;
spawnedZombies = 0;
spawnedTanks = 0;
kills = 0;
spawnTank.setDelay(4000);
}
}
//Main method
public static void main(String[] arguments) {
Tanks game = new Tanks();
}
}