2 Replies Latest reply: Oct 3, 2011 3:02 AM by 875749 RSS

    Can't Find Null Pointer Exception

    875749
      Hey, guys! I've spent a couple of hours trying to figure this out, and I've been unable. When I run my program, I get a long list of errors that basically says I have a NullPointerException at Line 160 in LevelRenderer. I can't figure out what is null after tons of analyzing and experimenting, so I was wondering if one of you could assist me with this.

      First, here is the runtime error code:
      Game Update Error: java.lang.NullPointerException
      Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
              at LevelRenderer.paint(LevelRenderer.java:160)
              at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
      
              at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
      
              at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:6
      93)
              at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(System
      EventQueueUtilities.java:125)
              at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
              at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
              at java.awt.EventQueue.access$000(EventQueue.java:84)
              at java.awt.EventQueue$1.run(EventQueue.java:602)
              at java.awt.EventQueue$1.run(EventQueue.java:600)
              at java.security.AccessController.doPrivileged(Native Method)
              at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessCo
      ntrolContext.java:87)
              at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
              at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThre
      ad.java:269)
              at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.
      java:184)
              at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThre
      ad.java:174)
              at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
      
              at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
      
              at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
      Here's the code for the classes that are relevant to the issue. The runtime code is pointing me to the paint method's call of myLevel.drawLevel(gr, 0, 0):

      Here's the class that is giving me the error:
      /* This class's job is to render a level object.
       *
       * The class will keep track of the top left coordinate of the space in which the player is moving
       * and how far the right side of the screen is. It will then draw the player always in the center
       * of the screen and allow the player to move the character. The character will animate with calls
       * to the Player class and also detect collision against the character. If there are collisions, then the
       * player will either fall or be unable to move. It will keep the screen image a little bit rendered
       * beyond the screen so that when the player moves, it will be able to still be visible until the next tile
       * is reached. It will update the screen every time the player moves and reference the level's collision
       * map for all of the collisions.
       *
       */
       
      import java.awt.*;
      import java.awt.event.*;
      import java.awt.image.*;
      import java.io.*;
      import javax.imageio.*;
      import javax.swing.JFrame;
      import javax.swing.*;
      import java.util.Random;
      import java.awt.Color;
      
      public class LevelRenderer extends JFrame
      {   
          //
          // CONSTANTS
          //
          
          private final int TILE_SIZE = 14;
          private final int SCREEN_WIDTH = 1280;
          private final int SCREEN_HEIGHT = 768;
          
          //
          // END OF CONSTANTS
          //
          
          // will be used as a buffer before everything is drawn to the screen
          private BufferedImage buffer;
          
          // character object
          private Player myPlayer;
          
          // level object
          private Level myLevel;
          
          // screen object
          private Screen s;
          
          // graphics object of the buffer
          private Graphics gr;
          
          // boolean to determine when to end the game
          private boolean endGame;
          
          // CONSTRUCTOR
          public LevelRenderer()
          {
              setPreferredSize(new Dimension(1280, 768));
      
              setFocusable(true);
              requestFocus();
              
              setResizable(false);
              
              addKeyListener( new KeyAdapter() 
              {
                  public void keyPressed(KeyEvent e)
                  { 
                      processKey(e);  
                  }
                  
                  public void keyReleased(KeyEvent e)
                  {
                      processRelease(e);
                  }
              });
              
              buffer = new BufferedImage(1280, 768, BufferedImage.TYPE_INT_ARGB);
              
              buffer.createGraphics();
              gr = buffer.getGraphics();
              
              myPlayer = new Player();
              Level myLevel = new Level("obstaclemap");
              
              endGame = false;
          }
          
          // method to simply load an image from a path
          public static BufferedImage loadImage(String ref)
          {
              BufferedImage bimg = null;
                 
              try
              {
                 bimg = ImageIO.read(new File(ref));
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
             
              return bimg;
          }
          
          // Run method for class
          public void run(DisplayMode dm)
           {     
              setBackground(Color.WHITE);
                s = new Screen();
              
              try
              {   
                  s.setFullScreen(dm, this);
              }
              catch (Exception ex)
              {
                  System.out.println("Error creating rendered tiles!");
              }
                
                while (!endGame)
              {
                  try
                  {
                      Thread.sleep(2);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
                  
                  try
                  {
                      myPlayer.animatePlayer();
                      myLevel.renderLevel();
                  }
                  catch (NullPointerException ex) 
                  { 
                      System.err.println("Game Update Error: " + ex);
                  }
                  
                  try
                  {
                      repaint();
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Repaint Error: " + ex);
                  }
              }
              
                s.restoreScreen();
           }
          
          // method to draw the tiles on the screen
          public void paint(Graphics g)
          {   
              // draw the level and then the player
              myLevel.drawLevel(gr, 0, 0);  
              
              myPlayer.drawPlayer(gr, (SCREEN_WIDTH / 2) - TILE_SIZE / 2, (SCREEN_HEIGHT / 2) - TILE_SIZE);
              
              g.drawImage(buffer, 0, 0, null);
          }  
          
          // method to handle inputs and adjust the player accordingly
          public void processKey(KeyEvent e)
          {
              int keyCode = e.getKeyCode();
              boolean moved = false;
              int xDisplace, yDisplace;
              
              // termination key
              if (keyCode == KeyEvent.VK_ESCAPE)
              {
                  endGame = true;
              }
              
              // 1 - up
              // 2 - left
              // 3 - right
              // 4 - down
              // 5 - jump
              
              if (keyCode == KeyEvent.VK_UP)
              {
                  try
                  {
                      myPlayer.updatePlayer(0);
                      myLevel.updateLevel(0);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_LEFT)
              {
                  try
                  {
                      myPlayer.updatePlayer(1);
                      myLevel.updateLevel(1);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_RIGHT)
              {
                  try
                  {
                      myPlayer.updatePlayer(2);
                      myLevel.updateLevel(2);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_DOWN)
              {
                  try
                  {
                      myPlayer.updatePlayer(3);
                      myLevel.updateLevel(3);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_SPACE)
              {
                  try
                  {
                      myPlayer.updatePlayer(4);
                      myLevel.updateLevel(4);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
          }
          
          // method to handle inputs and adjust the player accordingly
          public void processRelease(KeyEvent e)
          {
              int keyCode = e.getKeyCode();
              boolean moved = false;
              int xDisplace, yDisplace;
              
              // 1 - up
              // 2 - left
              // 3 - right
              // 4 - down
              // 5 - jump
              
              if (keyCode == KeyEvent.VK_UP)
              {
                  try
                  {
                      myPlayer.updatePlayer(0);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_LEFT)
              {
                  try
                  {
                      myPlayer.updatePlayer(5);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_RIGHT)
              {
                  try
                  {
                      myPlayer.updatePlayer(6);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_DOWN)
              {
                  try
                  {
                      myPlayer.updatePlayer(3);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
              if (keyCode == KeyEvent.VK_SPACE)
              {
                  try
                  {
                      myPlayer.updatePlayer(4);
                  }
                  catch (Exception ex)
                  {
                      System.err.println("Error: " + ex);
                  }
              }
          }
      }
      And then here's the other class that is calling the drawLevel method that the compiler is pointing me in the direction of (where it's saying the NullPointerException is stemming from):
      /* The purpose of this class will be to load and manage a level, including its camera. */
      
      import java.awt.image.*;
      import java.io.*;
      import javax.imageio.*;
      import java.awt.*;
      
      public class Level
      {
          //
          // CONSTANTS
          //
          
          private final int TILE_SIZE = 14;
          private final int SCREEN_WIDTH = 1280;
          private final int SCREEN_HEIGHT = 768;
          
          //
          // END OF CONSTANTS
          //
          
          // stores the pixel image of the current level
          private BufferedImage levelImage;
          
          // stores the width and height of the level
          private int width, height;
          
          // stores the name of the level
          private String levelName;
          
          // stores collision map for level
          private LevelCollisions myCollisions;
          
          // stores the tile types in an array as assigned by colors
          private int levelTiles[][];
          
          // image used as the sheet for the level's tiles
          private BufferedImage tileSheet;
          
          // image array used to store the different tiles
          private BufferedImage[] tiles;
          
          // the image which represents the current view of the level
          private BufferedImage cameraImage;
          
          // Graphics context of the camera image
          private Graphics cameraG;
          
          // variables to represent the level's offset from the top left corner while moving
          private int offsetX, offsetY;
          
          // variables to represent the level's pixel map coordinate
          private int coordX, coordY;
          
          // 
          // STATIC COLOR VARIABLES
          //
          
          private static final int SPACE_COLOR = 0xFF000000;
          private static final int WALL_COLOR = 0xFFFFFFFF;
          
          //
          // END OF STATIC COLOR VARIABLES
          //
          
          //
          // CONSTRUCTOR
          //
          public Level(String level)
          {
              // load level image and collision map
              levelName = level;
              levelImage = loadImage(level + ".png");
              myCollisions = new LevelCollisions(level + "Collision");
              levelTiles = loadLevel();   
              
              // create blank camera canvas
              cameraImage = new BufferedImage(1280, 768, BufferedImage.TYPE_INT_ARGB);
              cameraImage.createGraphics();
              cameraG = cameraImage.getGraphics();
              
              // offsets start at 0
              offsetX = offsetY = 0;
              
              // coordinate starts at bottom right
              coordX = 700;
              coordY = 400;
              
              // fill tile images
              tileSheet = loadImage("obstacletiles.png");
              tiles = splitImage(tileSheet, 1, 2);
              
              this.renderLevel();
          }
          
          // method to load the color values into an array
          public int[][] loadLevel()
          {
              height = levelImage.getHeight();
              width = levelImage.getWidth();
              
              int levelValues[][] = new int[width][height];
              
              // fill array with color values layer by layer
              for (int y = 0; y < height; y++)
              {
                  for (int x = 0; x < width; x++)
                  {
                      levelValues[x][y] = levelImage.getRGB(x, y);
                  }   
              }
              
              return levelValues;
          }
          
          // method to get the tile color from a given tile
          public int getTile(int x, int y)
          {
              return levelTiles[x][y];
          }
          
          // method to draw the current camera view of the level on the screen
          public void drawLevel(Graphics gr, int x, int y)
          {
              gr.drawImage(cameraImage, x, y, null);
          }
          
          // method to render the actual image before drawing it
          public void renderLevel()
          {
              // keeps track of graphics coordinate
              int x, y;
              
              // keeps track of tile to draw
              int tileX, tileY;
              
              tileY = coordY;
              
              // draw all the tiles based on offsets, layer by layer
              for (y = offsetY; y < SCREEN_HEIGHT + offsetY; y += TILE_SIZE)
              {
                  tileX = coordX;
                  for (x = offsetX; x < SCREEN_WIDTH + offsetX; x += TILE_SIZE)
                  {
                      // determine which tile to draw based on tile color in array
                      switch (this.getTile(tileX, tileY))
                      {
                          case SPACE_COLOR:
                              cameraG.drawImage(tiles[0], x, y, null);
                              break;
                              
                          case WALL_COLOR:
                              cameraG.drawImage(tiles[1], x, y, null);
                              break;
                      }
                      
                      tileX++;
                  }
              }
              
              // steps to take in case of an offset
              if (offsetX > 0)
              {
              
              }
              
              if (offsetX < 0)
              {
              
              }
              
              if (offsetY < 0)
              {
              
              }
              
              if (offsetY > 0)
              {
              
              }
          }
          
          // method to update the level's current position for the camera
          public void updateLevel(int input)
          {
              switch (input)
              {
                  // up
                  case 0:
                      break;
                  // left
                  case 1:
                      // update offset to the left if not too far left
                      if (coordX > 30)
                      {
                          offsetX--;
                      }
                      
                      // if a tile has been moved, then offset becomes 0 and coordX is decreased
                      if (offsetX <= -TILE_SIZE)
                      {
                          offsetX = 0;
                          coordX--;
                      }
                      break;
                  // right
                  case 2:
                      // update offset to the right if not too far right
                      if (coordX < width - 30)
                      {
                          offsetX++;
                      }
                      
                      // if a tile has been moved, then offset becomes 0 and coordX is increased
                      if (offsetX >= TILE_SIZE)
                      {
                          offsetX = 0;
                          coordX++;
                      }
                      break;
                  // down
                  case 3:
                      break;
                  // jump
                  case 4:
                      break;
              }
          }
          
          // method to simply load an image from a path
          public static BufferedImage loadImage(String ref)
          {
              BufferedImage bimg = null;
                 
              try
              {
                 bimg = ImageIO.read(new File(ref));
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
             
              return bimg;
          }
          
          // method to create a tile array for tile sets
          public static BufferedImage[] splitImage(BufferedImage img, int cols, int rows)
          {
              int w = img.getWidth() / cols;
              int h = img.getHeight() / rows;
              int num = 0;
              
              BufferedImage imgs[] = new BufferedImage[w * h];
              
              for (int y = 0; y < rows; y++)
              {
                  for (int x = 0; x < cols; x++)
                  {
                      imgs[num] = new BufferedImage(w, h, img.getType());
                      
                      Graphics2D g = imgs[num].createGraphics();
                      g.drawImage(img, 0, 0, w, h, w * x, h * y, w * x + w, h * y + h, null);
                      g.dispose();
                      num++;
                  }
              }
              
              return imgs;
          }
          
          // image-loading method that will also alpha the color key for each tile
          public static BufferedImage makeColorTransparent(String ref, int color)
          {
              BufferedImage image = loadImage(ref);
              BufferedImage dimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
              Graphics2D g = dimg.createGraphics();
              g.setComposite(AlphaComposite.Src);
              g.drawImage(image, null, 0, 0);
              g.dispose();
              
              for (int i = 0; i < dimg.getHeight(); i++)
              {
                  for (int j = 0; j < dimg.getWidth(); j++)
                  {
                      if (dimg.getRGB(j, i) == color)
                      {
                          dimg.setRGB(j, i, 0x8F1C1C);
                      }
                  }
              }
              
              return dimg;
          }
      }
      Sorry for the long post, but since there are several objects involved in what could be the error, I didn't want to leave anything out of this one. Help is greatly appreciated! Thank you guys very much.

      Colton

      Edited by: coltonoscopy on Oct 2, 2011 11:57 PM
        • 1. Re: Can't Find Null Pointer Exception
          EJP
          Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
          at LevelRenderer.paint(LevelRenderer.java:160)
          ...    
          // method to draw the tiles on the screen
          public void paint(Graphics g)
          {   
          // draw the level and then the player
          myLevel.drawLevel(gr, 0, 0);  
          
          myPlayer.drawPlayer(gr, (SCREEN_WIDTH / 2) - TILE_SIZE / 2, (SCREEN_HEIGHT / 2) - TILE_SIZE);
          
          g.drawImage(buffer, 0, 0, null);
          }
          So one of those three lines is line 160, and whichever line it is, is dereferencing a null pointer. So one of 'myLevel', 'myPlayer', or 'g' is null. Probably not 'g' as you received it as a parameter from Swing. Pretty much cuts it down.

          There's nothing here you couldn't have worked out for yourself. The line number was all you needed.
          • 2. Re: Can't Find Null Pointer Exception
            875749
            EJP,

            Thank you for your reply. I realized it was actually something very silly. I declared a Level object where the attributes were and also within the LevelRenderer constructor and named them the same thing. Now the code is working perfectly. I appreciate your help.

            Colton