I had my code working (at least somewhat) and I must have changed something, because now it won't even launch. There's no shown errors within the code, but when I try to run it this is what appears:
"Exception in thread "main" java.lang.NullPointerException
at Version2.Game.moveAllObjects(Game.java:117)
at Version2.Game.playGame(Game.java:63)
at Version2.GameDemo.main(GameDemo.java:8)"
How do I fix it?
Here's my relevant code:
1.GameDemo:
package Version2; public class GameDemo { public static void main(String argv[]) { Game g = new Game(); g.playGame(); } }
2. Game:
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++; } } } } }
3. RowOfAlien:
package Version2; import java.awt.Graphics; public class RowOfAlien { // CONSTANTS public final int NUMBER_OF_ALIENS = 5; // Size of the canvas in which alien moves private final int MAX_WIDTH; private final int MAX_HEIGHT; // VARIABLES private Alien[] row; private boolean[] alive; private int upperLeftX, upperLeftY; //private boolean moveRight = true; private final int INITIAL_X_SPEED = 5; private final int DROP_DOWN_AMOUNT = 50; public RowOfAlien(int numberOfAliens, int theMaxWidth, int theMaxHeight) { MAX_WIDTH = theMaxWidth; MAX_HEIGHT = theMaxHeight; row = new Alien[6]; for (int index = 0; index < 6; index++) { row[index] = new Alien(index * 50, 50, theMaxWidth, theMaxHeight); alive[index] = true; } alive = new boolean[6]; } public void move() { for (int index = 0; index < row.length; index++) { if (alive[index]) { row[index].move(); } } //for (int index = 0; index < 6; index++) { //if (alive[index]) //if(row[index].getUpperLeftY() < 580){ //if (moveRight) //row[index].setUpperLeftX(row[index].getUpperLeftX() + INITIAL_X_SPEED); //else //row[index].setUpperLeftX(row[index].getUpperLeftX() - INITIAL_X_SPEED); //} } //for (int index = 0; index < 6; index++) { //if (alive[index]) //if (row[index].getUpperLeftX() >= 780){ //for (int j = 0; j < 6; j++) //row[j].setUpperLeftY(row[j].getUpperLeftY() + DROP_DOWN_AMOUNT); //moveRight = false; //if (row[index].getUpperLeftY() >= 580) //System.out.println("DONE"); //} else if (row[index].getUpperLeftX() <= 0) { //for (int j = 0; j< 6; j++) //row[j].setUpperLeftY(row[j].getUpperLeftY() + DROP_DOWN_AMOUNT); //moveRight = true; //} public void drawAlien(Graphics g) { for (int index = 0; index < row.length; index++) { if (alive[index]) { row[index].draw(g); } } } public void setAlive(int i, boolean val) { alive[i] = val; } public boolean getAlive(int i) { return alive[i]; } public Alien getAlien(int index) { return row[index]; } }
Any suggestions?