package Version2;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
import Version2.RowOfAlien;
/**
* @original author Kevin Glass
* @adapted by: Nikunj Raghuvanshi
* @adapted by: Kye Hedlund 3/2010
*/
public class Game extends Canvas {
// CONSTANTS
public final int ALIEN_WIDTH = 40;
public final int SCREEN_WIDTH = 800;
public final int SCREEN_HEIGHT = 600;
// Time (in ms) to pause after each step of the game loop.
// This, in part, determines the speed at which the game is
// updated on the screen.
public final int PAUSE_INTERVAL = 10;
// VARIABLES
private RowOfAlien rowofalien;
private Base base;
private Missile missile;
private Alien alien;
// Keyboard stuff - will be used in a future assignment
// True if we're holding up game play until a key has been pressed
private boolean waitingForKeyPress = true;
private boolean leftCursorCurrentlyPressed = false;
private boolean rightCursorCurrentlyPressed = false;
private boolean fireCurrrentlyPressed = false;
private boolean gameRunning = true;
// Graphics stuff
private Graphics2D g;
private BufferStrategy strategy; // Use accelerated page flipping
/*
* Create a new game that is ready to play
*/
public Game() {
graphicsInitialization();
initAllObjects();
}
public void playGame() {
while (gameRunning) {
moveAllObjects();
graphicsUpdateStartOfLoop();
drawAllObjects();
graphicsUpdateEndOfLoop();
}
}
private void drawAllObjects() {
rowofalien.drawAlien(g);
base.draw(g);
missile.draw(g);
alien.draw(g);
}
private void initAllObjects() {
final int ALIEN_X_POSITION = 20;
final int ALIEN_Y_POSITION = -40; // ?????????????? negative
alien = new Alien(ALIEN_X_POSITION, ALIEN_Y_POSITION, SCREEN_WIDTH, SCREEN_HEIGHT);
final int BASE_X_POSITION = 400;
final int BASE_Y_POSITION = 560;
base = new Base(BASE_X_POSITION, BASE_Y_POSITION);
final int MISSILE_X_POSITION = 400;
final int MISSILE_Y_POSITION = 560;
missile = new Missile(MISSILE_X_POSITION, MISSILE_Y_POSITION);
}
private void moveAllObjects() {
if (leftCursorCurrentlyPressed == true) {
base.moveLeft();
}
if (rightCursorCurrentlyPressed == true) {
base.moveRight();
}
if ((fireCurrrentlyPressed == true) && (missile.getUpperLeftY() >= 600)) {
missile.setUpperLeftX(base.getUpperLeftX());
missile.move();
}
if (missile.getUpperLeftY() < 600)
missile.move();
gameRunning = false;
for (int index = 0; index < 6; index++) {
if (rowofalien.getAlien(index).getUpperLeftX() <= missile.getUpperLeftX()
&& missile.getUpperLeftX() <= rowofalien.getAlien(index).getUpperLeftX() + 40
&& rowofalien.getAlien(index).getUpperLeftY() <= missile.getUpperLeftY()
&& missile.getUpperLeftY() <= rowofalien.getAlien(index).getUpperLeftY() + 40
&& missile.getUpperLeftY() > 0) {
System.out.println("Hit!");
rowofalien.setAlive(index, false);
}
rowofalien.move();
gameRunning = gameRunning || rowofalien.getAlive(index);
}
}
// **************************************************************
// Do not change any of the methods whose names begin with "graphics" or
// "key".
// From here to the end of the class - don't change anything.
public void graphicsUpdateEndOfLoop() {
// Finally, we've completed drawing so clear up the graphics
// and flip the buffer over
g.dispose();
strategy.show();
// Finally pause for a bit. Note: this should run us at about
// 100 fps but on windows this might vary each loop due to
// a bad implementation of timer
try {
Thread.sleep(PAUSE_INTERVAL);
} catch (Exception e) {
}
}
// Do no change any of the methods whose names begin with "graphics"
public void graphicsUpdateStartOfLoop() {
// Get hold of a graphics context for the accelerated
// surface and blank it out
g = (Graphics2D) strategy.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
}
public void graphicsInitialization() {
// Create a frame to contain our game
JFrame container = new JFrame("Space Invaders 110");
// Get the content of the frame and set up the resolution of the
// game
JPanel panel = (JPanel) container.getContentPane();
panel.setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
panel.setLayout(null);
// Setup our canvas size and put it into the content of the frame
setBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
panel.add(this);
// Tell AWT not to bother repainting our canvas since we're
// going to do that ourself in accelerated mode
setIgnoreRepaint(true);
// Make the window visible
container.pack();
container.setResizable(false);
container.setVisible(true);
// Add a listener to respond to the user closing the window. If they
// do we'd like to exit the game
container.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// Request the focus so key events come to us
requestFocus();
// Create the buffering strategy which will allow AWT
// to manage our accelerated graphics
createBufferStrategy(2);
strategy = getBufferStrategy();
// Add a key input system (defined below) to our canvas
// so we can respond to key pressed
addKeyListener(new KeyInputHandler());
}
/**
* A class to handle keyboard input from the user. The class handles both
* dynamic input during game play, i.e. left/right and shoot, and more
* static type input (i.e. press any key to continue)
*
* This has been implemented as an inner class more through habbit then
* anything else. Its perfectly normal to implement this as seperate class
* if slight less convienient.
*
* @author Kevin Glass
*/
private class KeyInputHandler extends KeyAdapter {
/**
* The number of key presses we've had while waiting for an "any key"
* press
*/
private int pressCount = 1;
/**
* Notification from AWT that a key has been pressed. Note that a key
* being pressed is equal to being pushed down but *NOT* released. Thats
* where keyTyped() comes in.
*
* @param e
* The details of the key that was pressed
*/
public void keyPressed(KeyEvent e) {
// if we're waiting for an "any key" typed then we don't
// want to do anything with just a "press"
if (waitingForKeyPress) {
return;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftCursorCurrentlyPressed = true;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightCursorCurrentlyPressed = true;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
fireCurrrentlyPressed = true;
}
}
/**
* Notification from AWT that a key has been released.
*
* @param e
* The details of the key that was released
*/
public void keyReleased(KeyEvent e) {
// if we're waiting for an "any key" typed then we don't
// want to do anything with just a "released"
if (waitingForKeyPress) {
return;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftCursorCurrentlyPressed = false;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightCursorCurrentlyPressed = false;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
fireCurrrentlyPressed = false;
}
}
/**
* Notification from AWT that a key has been typed. Note that typing a
* key means to both press and then release it.
*
* @param e
* The details of the key that was typed.
*/
public void keyTyped(KeyEvent e) {
// if we're waiting for a "any key" type then
// check if we've recieved any recently. We may
// have had a keyType() event from the user releasing
// the shoot or move keys, hence the use of the "pressCount"
// counter.
if (waitingForKeyPress) {
if (pressCount == 1) {
// since we've now recieved our key typed
// event we can mark it as such and start
// our new game
waitingForKeyPress = false;
// startGame();
pressCount = 0;
} else {
pressCount++;
}
}
}
}
}