ExceptionInInitializerError - nie mogę znaleźć przyczyny

0

Witam serdecznie! Od wczoraj zmagam się z błędem, który wyskakuje i nie mogę dojść jego przyczyny.

Exception in thread "Thread-2" java.lang.ExceptionInInitializerError
	at Game.init(Game.java:100)
	at Game.run(Game.java:65)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
	at Map.loadMap(Map.java:19)
	at Map.<init>(Map.java:13)
	at Map.<clinit>(Map.java:8)
	... 3 more
 

To jest moja klasa, do której zmiennej statycznej chciałbym się odwołać

public class Map {
	private int width, height;
	public int[] tiles;

	public static Map currentMap = null;
	public static Map map1 = new Map(30, 20);

	public Map(int width, int height) {
		this.width = width;
		this.height = height;
		loadMap();
	}

	private void loadMap() {
		for (int i = 0; i < height; i++) {
			for (int j = 0; j < width; j++) {
				tiles[j + i * width] = ThreadLocalRandom.current().nextInt(4);
			}
		}
	}

	public Sprite getSprite(int xAbsolute, int yAbsolute) {
		int x = xAbsolute >> 4;
		int y = yAbsolute >> 4;
		int tile = tiles[xAbsolute + yAbsolute * width];
		if (tile == 0) return Sprite.grassTile;
		else
			return Sprite.waterTile;
	}

	public static void setCurrentMap(Map map) {
		currentMap = map;
	}
} 

Błąd ten pojawia się dopiero w momencie, kiedy w klasie mojej gry dodam tą linijkę:
Map.setCurrentMap(Map.map1);

I sytuacja jest o tyle dla mnie ciekawa, że tworząc drugi projekt i wklejając ten sam kod wszystko było w porządku, program działał i nie było błędu. Ale przy utworzeniu trzeciego, takiego samego projektu znowu nie działało ponownie. Proszę o pomoc jak zaradzić temu problemowi.

0

Pokaż klasę Game

0
public class Game extends Canvas implements Runnable {
	public static final int WIDTH = 300;
	public static final int HEIGHT = 168;
	public static final int SCALE = 3;
	private String title = "Bla bla bla";
	private JFrame frame;
	private boolean running = false;

	private Thread thread;
	private Graphics2D g;
	private BufferStrategy bs;

	private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
	public int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

	private Screen screen;
	private KeyManager keyManager;

	public int xOffset = 0, yOffset = 0;

	public Game() {
		frame = new JFrame(title);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.setResizable(false);

		setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
		frame.add(this);
		frame.pack();
		frame.setLocationRelativeTo(null);

		setFocusable(true);
		requestFocus();
	}

	public void start() {
		if (running) return;
		running = true;
		thread = new Thread(this);
		thread.start();
	}

	public void stop() {
		if (!running) return;
		running = false;
		try {
			thread.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public void run() {
		init();
		int fps = 60;
		double ticksPerSecond = 1000000000 / fps;
		double delta = 0;
		long now;
		long lastTime = System.nanoTime();
		int updates = 0;
		int frames = 0;
		long timer = System.currentTimeMillis();

		while (running) {
			now = System.nanoTime();
			delta += (now - lastTime) / ticksPerSecond;
			lastTime = now;
			if (delta > 1) {
				update();
				updates++;
				delta--;
			}
			render();
			frames++;
			if (System.currentTimeMillis() - timer > 1000) {
				timer += 1000;
				System.out.println("Updates: " + updates + "   Frames: " + frames);
				updates = 0;
				frames = 0;
			}
		}

	}

	public void init() {
		screen = new Screen(WIDTH, HEIGHT);
		keyManager = new KeyManager();
		addKeyListener(keyManager);
		Map.setCurrentMap(Map.map1); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                ///////////////To ta linijka
	}

	public void render() {
		bs = getBufferStrategy();
		if (bs == null) {
			createBufferStrategy(3);
			return;
		}
		g = (Graphics2D) bs.getDrawGraphics();
		g.clearRect(0, 0, WIDTH, HEIGHT);
		// screen.renderMap(xOffset, yOffset, Map.currentLevel);

		bs.show();
		g.dispose();
	}

	public void update() {
		keyManager.update();
	}

	public static void main(String[] args) {
		Game game = new Game();
		game.start();

	}
}
 
0

Dobra, znalazłem.
W konstruktorze Mapy dodaj:

tiles = new int[wymiarJakiChceszOtrzymac]

i będzie git.
Ale ten design trochę ssie imo

Generalnie polecam nauczenie się czytania stack trace, bo chodź bywają długie potrafią dać bardzo trafne odpowiedzi na to co poszło nie tak.

0

Dziękuję :). Nie wiem jakim cudem to przegapiłem. A co byś w designie zmienił? Jestem otwarty na dobre rady :).

0

Generalnie mój zarzut dotyczy głównie statycznych zmiennych.
Tutaj jest przyczyna moich wątpliwości http://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil
Warto od początku nauki uczyć się dobrych praktyk :)

0

Co do zmiennych statycznych, to polecam je stosować głównie dla constów, wtedy dodatkowo zmienna jest final
Statyczne czasami powinny być również metody - w przypadku jakichś utilsów, gdzie faktycznie output z metody zależy tylko i wyłącznie od argumentów, a nie od żadnego stanu jakiegokolwiek obiektu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1