Search code examples
javaslick2d

Slick2d Map NullPointerException


I have been looking for the null pointer for a few hours, and it feels like I've been wasting away staring at the same screen.

So, I'm attempting to open a SpriteSheet and get an image from that sheet, unfortunately at my best attempts it returns an error.

I believe the Map is the problem; I have a Map that documents the title and directory of a sprite sheet. When I try to access the specified SpriteSheet it returns a NullPointerException.

Anyways, getting to the code:

package main;

import java.util.HashMap;
import java.util.Map;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;

public class Resources {

    public static Map<String, SpriteSheet> sprites;
    public static Map<String, Image> images;

    public Resources(){
        sprites = new HashMap<String, SpriteSheet>();
        images = new HashMap<String, Image>();

        try {
            sprites.put("Tiles", getSpriteSheet("Tiles.png", 32, 32));
        } catch (SlickException e) {
            e.printStackTrace();
        }

    }

    private static SpriteSheet getSpriteSheet(String image, int w, int h) throws SlickException{
        return new SpriteSheet("/res/" + image, w, h);
    }

    public static Image getImage(String image, int x, int y) throws SlickException{
        Image img = sprites.get("Tiles").getSubImage(x, y);

        if(img != null){
            return img;
        }else{
            System.out.println("ERROR LOADING IMAGE");
            return null;
        }
    }

}

Solution

  • Without seeing the stack trace, I'm going to guess that the problem occurs on this line:

    Image img = sprites.get("Tiles").getSubImage(x, y);
    

    This is because you're only assigning a value to sprites if you call the constructor, so you would get a NullPointerException if you call this static method before you happen to have called the constructor.

    You can assign a value to the static fields like this:

    public static Map<String, SpriteSheet> sprites = new HashMap<>();
    public static Map<String, Image> images = new HashMap<>();
    

    and then remove the assignments in the constructor.

    You might also want to consider making the static fields private and final, in order to minimize visibility, and avoid accidental reassignment respectively.

    If you want to put the Tiles.png sprite sheet into those static maps, you can do this using a static initializer block:

    static {
      try {
        sprites.put("Tiles", getSpriteSheet("Tiles.png", 32, 32));
      } catch (SlickException e) {
        // ...
      }