import java.awt.*;
import java.util.HashMap;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.util.Random;
/**
* @author Justin Mobijohn and Zander
* This class the main class of this application. It creates a HashMap of
* GameObjects, and basically calls Update and Draw for each element in the
* HashMap.
*/
public class SpaceInvaders extends Canvas implements KeyListener {
// The height and width have to be public, so that the collision
// detection of the Missile class can determine if the missile when outside
// our window:
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
private HashMap<String, GameObject> m_CurrentGameObjects;
private boolean m_QuitFlag;
private BufferStrategy m_Strategy;
private float m_ElapsedTime;
private GAME_STATE m_CurrentState;
private static Random RANDOM_GENERATOR = new Random();
enum GAME_STATE {
PLAYING, GAMEOVER, YOUWIN
}
/**
*
* Default constructor for the game. Nothing special here.
*/
public SpaceInvaders() {
// Iniitalize all the private data members:
this.m_CurrentGameObjects = new HashMap<String, GameObject>();
this.m_QuitFlag = false;
this.m_ElapsedTime = 1;
// Create the window:
JFrame window = new JFrame("Space Invaders");
JPanel panel = (JPanel) window.getContentPane();
setBounds(0, 0, WIDTH, HEIGHT);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
panel.setLayout(null);
panel.add(this);
window.setBounds(0, 0, WIDTH, HEIGHT);
window.setVisible(true);
window.setResizable(false);
window.addKeyListener(this);
createBufferStrategy(2);
this.m_Strategy = getBufferStrategy();
this.m_CurrentState = GAME_STATE.PLAYING;
}
/**
*
* We don't do anything with keyTyped. We just need it here so that it
* compiles.
*/
@Override
public void keyTyped(KeyEvent e) {
}
/**
*
* All input modifies the spaceship only:
*/
@Override
public void keyPressed(KeyEvent e) {
((SpaceShip) this.m_CurrentGameObjects.get("SpaceShip")).HandleKeyPress(e);
}
/**
*
* All input modifies the spaceship only:
*/
@Override
public void keyReleased(KeyEvent e) {
((SpaceShip) this.m_CurrentGameObjects.get("SpaceShip")).HandleKeyRelease(e);
}
/**
*
* InitGame initializes the game by creating GameObjects into the hashmap.
*/
public void InitGame() {
// Load into the HashMap all the GameObjects
this.m_CurrentGameObjects.put("SpaceShip", new SpaceShip());
this.m_CurrentGameObjects.put("Monster1", new Enemy());
this.m_CurrentGameObjects.put("Monster2", new Enemy());
this.m_CurrentGameObjects.put("Monster3", new Enemy());
this.m_CurrentGameObjects.put("Monster4", new Enemy());
this.m_CurrentGameObjects.put("Monster5", new Enemy());
this.m_CurrentGameObjects.put("Monster6", new Enemy());
this.m_CurrentGameObjects.put("Monster7", new Enemy());
this.m_CurrentGameObjects.put("Monster8", new Enemy());
this.m_CurrentGameObjects.put("Monster9", new Enemy());
this.m_CurrentGameObjects.put("Monster10", new Enemy());
this.m_CurrentGameObjects.put("Monster11", new Enemy());
this.m_CurrentGameObjects.put("Monster12", new Enemy());
this.m_CurrentGameObjects.put("Monster13", new Enemy());
}
/**
*
* This is the heart of the game. While the game is running, the loop
* continously draws and updates the screen.
*/
public void GameLoop() {
// This is the heart of the game.
// We continuously update and paint the screen:
while (this.m_QuitFlag == false) {
long startTime = System.currentTimeMillis();
this.update(this.m_ElapsedTime);
this.paintScreen();
// Let's be friendly to the other apps on this machine:
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
try {
long endTime = System.currentTimeMillis();
float diff = endTime - startTime;
this.m_ElapsedTime = diff / 1000F;
} catch (ArithmeticException e) {
}
}
}
/**
*
* Update function in turn calls each GameObject's update function, passsing
* in the elapsedTime since we did a screen refresh.
*
* @param elapsedTime The amount of time that has gone by since last screen
* fresh.
*/
public void update(float elapsedTime) {
// Update the Spaceship and all enemmies:
for (String gameObject : this.m_CurrentGameObjects.keySet()) {
// No need to update dead monsters. (Should we remove them from list?)
if (this.m_CurrentGameObjects.get(gameObject).IsAlive()) {
this.m_CurrentGameObjects.get(gameObject).Update(elapsedTime);
}
}
// Now update all the missiles:
for (int i = GameObject.m_AllMissiles.size() - 1; i >= 0; i--) {
GameObject.m_AllMissiles.get(i).Update(elapsedTime);
if (GameObject.m_AllMissiles.get(i).DetectCollision(this.m_CurrentGameObjects)) {
GameObject.m_AllMissiles.remove(i);
}
}
// Test to make sure the spaceship is alive:
if (!this.m_CurrentGameObjects.get("SpaceShip").IsAlive()) {
this.m_CurrentState = GAME_STATE.GAMEOVER;
}
// Test to see if we killed all monsters on the screen:
boolean bAreMonstersStillAlive = false;
for (String gameObject : this.m_CurrentGameObjects.keySet()) {
if (this.m_CurrentGameObjects.get(gameObject).GetGameObjectType() == GameObject.GameObjectType.ENEMY) {
if (this.m_CurrentGameObjects.get(gameObject).IsAlive()) {
bAreMonstersStillAlive = true;
break;
}
}
}
if (bAreMonstersStillAlive == false) {
this.m_CurrentState = GAME_STATE.YOUWIN;
}
// Test to see if you are an enemy, and if so, test to see if you've
// reached bottom:
for (String gameObject : this.m_CurrentGameObjects.keySet()) {
if (this.m_CurrentGameObjects.get(gameObject).GetGameObjectType() == GameObject.GameObjectType.ENEMY) {
// We know it's a monster, so now we can type cast it safely:
if (((Enemy) this.m_CurrentGameObjects.get(gameObject)).GetHasReachedBottom()) {
this.m_CurrentState = GAME_STATE.GAMEOVER;
}
}
}
}
/**
*
* Foreach GameObject in the HashMap, call it's draw.
*/
public void paintScreen() {
// First clear the background:
Graphics g = this.m_Strategy.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
switch (this.m_CurrentState) {
case PLAYING:
// Now draw each game object:
for (String gameObject : this.m_CurrentGameObjects.keySet()) {
if (this.m_CurrentGameObjects.get(gameObject).IsAlive()) {
this.m_CurrentGameObjects.get(gameObject).Draw(g, this);
}
}
// Now update all the missiles:
for (int i = 0; i < GameObject.m_AllMissiles.size(); i++) {
GameObject.m_AllMissiles.get(i).Draw(g, this);
}
g.setColor(Color.red);
g.drawString("Life: "+this.m_CurrentGameObjects.get("SpaceShip").getLife(), 5, 10);
break;
case GAMEOVER:
g.setColor(Color.red);
g.drawString("GAME OVER! YOU LOSE!", 350, 300);
break;
case YOUWIN:
g.setColor(new Color(RANDOM_GENERATOR.nextInt(256), RANDOM_GENERATOR.nextInt(256), RANDOM_GENERATOR.nextInt(256)));
g.drawString("YOU'RE A WINNER!", 350, 300);
break;
}
this.m_Strategy.show();
}
/**
*
* The main entry point for the program.
*/
public static void main(String[] args) {
SpaceInvaders spaceInvaders = new SpaceInvaders();
spaceInvaders.InitGame();
spaceInvaders.GameLoop();
}
}
|