title: Exception in thread "main" java.lang.NullPointerException on developing games in java
body: <p>I'm trying make fonts for a game but whenever I load it I get this error:</p>
  
  <pre><code>Exception in thread "main" java.lang.NullPointerException
  at image.ImageFont.load(ImageFont.java:78)
  at image.ImageFont.&lt;init&gt;(ImageFont.java:47)
  at image.ImageFontTest.init(ImageFontTest.java:26)
  at image.GameCore.run(GameCore.java:65)
  at image.ImageFontTest.main(ImageFontTest.java:11)
  </code></pre>
  
  <p>I also have the files for it:</p>
  
  <p>ImageFontTest</p>
  
  <pre><code>public class ImageFontTest extends GameCore {
  
  public static void main(String[] args) {
      new ImageFontTest().run();
  }
  
  private static final long TOTAL_TIME = 6500;
  
  private ImageFont bigFont;
  private ImageFont medFont;
  private long remainingTime;
  private CharMovement[] charMovement;
  
  public void init() {
      super.init();
  
      remainingTime = TOTAL_TIME;
      // load image fonts
      bigFont = new ImageFont("fonts/big");
      medFont = new ImageFont("fonts/medium");
  
      String message = "Good Times!";
      int stringWidth = medFont.stringWidth(message);
      charMovement = new CharMovement[message.length()];
      for (int i=0; i&lt;message.length(); i++) {
          charMovement[i] = new CharMovement(message, i,
              (screen.getWidth() - stringWidth) / 2,
              screen.getHeight() / 2);
      }
  }
  
  public void update(long elapsedTime) {
      remainingTime -= elapsedTime;
      if (remainingTime &lt;= 0) {
          stop();
      }
  }
  
  public void draw(Graphics2D g) {
      // erase background
      g.setColor(Color.BLACK);
      g.fillRect(0,0,screen.getWidth(), screen.getHeight());
  
      // draw some aligned text
      medFont.drawString(g, "Left", 0, 0,
          ImageFont.LEFT | ImageFont.TOP);
      medFont.drawString(g, "Center", screen.getWidth()/2, 0,
          ImageFont.HCENTER | ImageFont.TOP);
      medFont.drawString(g, "Right", screen.getWidth(), 0,
          ImageFont.RIGHT | ImageFont.TOP);
  
      // draw seconds remaining
      String timeLeft = "" + (remainingTime / 1000);
      bigFont.drawString(g, timeLeft, 0, screen.getHeight());
  
      // draw moving characters
      double p = (double)(TOTAL_TIME - remainingTime) / TOTAL_TIME;
      for (int i=0; i&lt;charMovement.length; i++) {
          charMovement[i].draw(g, p);
      }
  }
  
  /**
      Simple animation class to animate a character along a
      path.
  */
  public class CharMovement {
      char ch;
      Point[] path;
  
      public CharMovement(String s, int charIndex, int x, int y) {
          int stringWidth = medFont.stringWidth(s);
          for (int i=0; i&lt;charIndex; i++) {
              x+=medFont.charWidth(s.charAt(i));
          }
          ch = s.charAt(charIndex);
  
          path = new Point[4];
  
          // start offscreen
          path[0] = new Point(x-2000, y);
  
          // move to the center of the screen and pause there
          path[1] = new Point(x, y);
          path[2] = path[1];
  
          // "explode" at a random angle far away
          double angle = Math.random() * 2 * Math.PI;
          double distance = 1000 + 1000*Math.random();
          path[3] = new Point(
              (int)Math.round(x + Math.cos(angle) * distance),
              (int)Math.round(y + Math.sin(angle) * distance));
      }
  
      /**
          Draws this character in the path, where p is the
          location in the path from 0 to 1.
      */
      public void draw(Graphics g, double p) {
          int points = path.length - 1;
          int index = (int)(p*points);
          p = p * points - index;
          Point start = path[index % path.length];
          Point goal = path[(index + 1) % path.length];
          int x = (int)Math.round(goal.x * p + start.x * (1-p));
          int y = (int)Math.round(goal.y * p + start.y * (1-p));
          medFont.drawChar(g, ch, x, y);
      }
  }
  }
  </code></pre>
  
  <p>ImageFont</p>
  
  <pre><code>/**
  The ImageFont class allows loading and drawing of text
  using images for the characters.
  
  Reads all the png images in a directory in the form
  "charXX.png" where "XX" is a decimal unicode value.
  
  Characters can have different widths and heights.
  */
   public class ImageFont {
  
  public static final int HCENTER = 1;
  public static final int VCENTER = 2;
  public static final int LEFT = 4;
  public static final int RIGHT = 8;
  public static final int TOP = 16;
  public static final int BOTTOM = 32;
  
  private char firstChar;
  private Image[] characters;
  private Image invalidCharacter;
  
  
  /**
      Creates a new ImageFont with no characters.
  */
  public ImageFont() {
      this(null);
      firstChar = 0;
      characters = new Image[0];
  }
  
  
  /**
      Creates a new ImageFont and loads character images from
      the specified path.
  */
  public ImageFont(String path) {
      if (path != null) {
          load(path);
      }
  
      // make the character used for invalid characters
      invalidCharacter =
          new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
      Graphics g = invalidCharacter.getGraphics();
      g.setColor(Color.RED);
      g.fillRect(0,0,10,10);
      g.dispose();
  }
  
  
  /**
      Loads the image files for each character from the
      specified path. For example, if "../fonts/large"
      is the path, this method searches for all the images
      names "charXX.png" in that path, where "XX" is a
      decimal unicode value. Not every character image needs
      to exist; you can only do numbers or uppercase letters,
      for example.
  */
  public void load(String path) throws NumberFormatException {
      // in this directory:
      // load every png file that starts with 'char'
      File dir = new File(path);
      File[] files = dir.listFiles();
  
      // find min and max chars
      char minChar = Character.MAX_VALUE;
      char maxChar = Character.MIN_VALUE;
      for (int i=0; i&lt;files.length; i++) {
          int unicodeValue = getUnicodeValue(files[i]);
          if (unicodeValue != -1) {
              minChar = (char)Math.min(minChar, unicodeValue);
              maxChar = (char)Math.max(maxChar, unicodeValue);
          }
      }
  
      // load the images
      if (minChar &lt; maxChar) {
          firstChar = minChar;
          characters = new Image[maxChar - minChar + 1];
          for (int i=0; i&lt;files.length; i++) {
              int unicodeValue = getUnicodeValue(files[i]);
              if (unicodeValue != -1) {
                  int index = unicodeValue - firstChar;
                  characters[index] = new ImageIcon(
                      files[i].getAbsolutePath()).getImage();
              }
          }
  
      }
  
  }
  
  
  private int getUnicodeValue(File file)
      throws NumberFormatException
  {
      String name = file.getName().toLowerCase();
      if (name.startsWith("char") &amp;&amp; name.endsWith(".png")) {
          String unicodeString =
              name.substring(4, name.length() - 4);
          return Integer.parseInt(unicodeString);
      }
      return -1;
  }
  
  
  /**
      Gets the image for a specific character. If no image for
      the character exists, a special "invalid" character image
      is returned.
  */
  public Image getImage(char ch) {
      int index = ch - firstChar;
      if (index &lt; 0 || index &gt;= characters.length ||
          characters[index] == null)
      {
          return invalidCharacter;
      }
      else {
          return characters[index];
      }
  }
  
  
  /**
      Gets the string width, in pixels, for the specified string.
  */
  public int stringWidth(String s) {
      int width = 0;
      for (int i=0; i&lt;s.length(); i++) {
          width += charWidth(s.charAt(i));
      }
      return width;
  }
  
  
  /**
      Gets the char width, in pixels, for the specified char.
  */
  public int charWidth(char ch) {
      return getImage(ch).getWidth(null);
  }
  
  
  /**
      Gets the char height, in pixels, for the specified char.
  */
  public int charHeight(char ch) {
      return getImage(ch).getHeight(null);
  }
  
  
  /**
      Draws the specified string at the (x, y) location.
  */
  public void drawString(Graphics g, String s, int x, int y) {
      drawString(g, s, x, y, LEFT | BOTTOM);
  }
  
  
  /**
      Draws the specified string at the (x, y) location.
  */
  public void drawString(Graphics g, String s, int x, int y,
      int anchor)
  {
      if ((anchor &amp; HCENTER) != 0) {
          x-=stringWidth(s) / 2;
      }
      else if ((anchor &amp; RIGHT) != 0) {
          x-=stringWidth(s);
      }
      // clear horizontal flags for char drawing
      anchor &amp;= ~HCENTER;
      anchor &amp;= ~RIGHT;
  
      // draw the characters
      for (int i=0; i&lt;s.length(); i++) {
          drawChar(g, s.charAt(i), x, y, anchor);
          x+=charWidth(s.charAt(i));
      }
  }
  
  
  /**
      Draws the specified character at the (x, y) location.
  */
  public void drawChar(Graphics g, char ch, int x, int y) {
      drawChar(g, ch, x, y, LEFT | BOTTOM);
  }
  
  
  /**
      Draws the specified character at the (x, y) location.
  */
  public void drawChar(Graphics g, char ch, int x, int y,
      int anchor)
  {
      if ((anchor &amp; HCENTER) != 0) {
          x-=charWidth(ch) / 2;
      }
      else if ((anchor &amp; RIGHT) != 0) {
          x-=charWidth(ch);
      }
  
      if ((anchor &amp; VCENTER) != 0) {
          y-=charHeight(ch) / 2;
      }
      else if ((anchor &amp; BOTTOM) != 0) {
          y-=charHeight(ch);
      }
      g.drawImage(getImage(ch), x, y, null);
  }
  }
  </code></pre>
  
  <p>I see it says the problem is at load in ImageFont but I dont know how to fix it. </p>