Reddish Reddish - 1 month ago 5
Java Question

Java Graphics NullPointerException When The Exact Same Thing Works Somewhere Else

I'm currently making a simple game with java Graphics and using multiple menus as well. Such as Help, Main, the Game itself, Lose, and Win. All menus have their own render functions that are called depending on the state of the game. All of the menus work, except for the 'Win' menu. There is the 'Lose' and the 'Win' menu both posted. They're pretty much the same thing but 'Win' will not work.

Render in main game:

private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);

if(GameState == STATE.Game) {
handler.render(g);
hud.render(g);
} else if(GameState == STATE.Menu) {
menu.render(g);
} else if(GameState == STATE.Help) {
help.render(g);
} else if(GameState == STATE.EndMenu) {
endMenu.render(g);
} else if(GameState == STATE.Win) {
win.render(g);
}

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


Win:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

public class Win {

public Win(){}

public void render(Graphics g) {
g.setColor(Color.WHITE);
g.setFont(new Font("SansSerriff", Font.BOLD, 100));
g.drawString("YOU WIN!!!", Game.WIDTH/2 - 280, Game.HEIGHT/2 - 50);

g.setFont(new Font("SansSerriff", Font.PLAIN, 60));
g.drawString("Player Again", 360, 600);
g.drawRect(250, 535, 500, 100);
}
}


Lose:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

public class EndMenu {

public EndMenu() {}

public void render(Graphics g) {
g.setColor(Color.WHITE);
g.setFont(new Font("SansSerriff", Font.BOLD, 100));
g.drawString("YOU LOSE!!", Game.WIDTH/2 - 280, Game.HEIGHT/2 - 50);

g.setFont(new Font("SansSerriff", Font.PLAIN, 60));
g.drawString("Play Again", 360, 600);
g.drawRect(250, 535, 500, 100);
}

}


Error Message:

Exception in thread "Thread-2" java.lang.NullPointerException
at Main.Game.render(Game.java:132)
at Main.Game.run(Game.java:86)
at java.lang.Thread.run(Unknown Source)


All help is greatly appreciated. Thank you!

EDIT

Game:

package Main;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;

public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 2287623113957789623L;

public static final int WIDTH = 1000, HEIGHT = WIDTH/12 * 9;
private Thread thread;
public static boolean running = false;
private Handler handler;
private HUD hud;
private Spawner spawner;
private Menu menu;
private Help help;
private EndMenu endMenu;
private Win win;
public static STATE GameState = STATE.Win;

//----------Game()----------//
//---------------------------------------------------------------------------
public Game() {
handler = new Handler();
menu = new Menu(this, handler);
help = new Help();
endMenu = new EndMenu();
this.addKeyListener(new KeyInput(handler));
this.addMouseListener(menu);

new Window(WIDTH, HEIGHT, "Wave", this);
hud = new HUD();
spawner = new Spawner(handler, hud);
}

//----------Game Modes----------//
//---------------------------------------------------------------------------
public enum STATE {
Menu,
Game,
Help,
EndMenu,
Win,
}

//----------start()----------//
//---------------------------------------------------------------------------
public synchronized void start() {
thread = new Thread(this);
thread.start();
running = true;
}

//----------stop()----------//
//---------------------------------------------------------------------------
public synchronized void stop() {
try {
thread.join();
running = false;
}catch(Exception e) {
e.printStackTrace();
}
}

//----------run()-----------//
//---------------------------------------------------------------------------
public void run() {
this.requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
long timer = System.currentTimeMillis();
int frames = 0;
while(running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
tick();
delta--;
}
if(running)
render();
frames++;
if(System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println("FPS: " + frames);
frames = 0;
}
}
stop();
}

//----------tick()----------//
//---------------------------------------------------------------------------
private void tick() {
if(GameState == STATE.Game) {
handler.tick();
hud.tick();
spawner.tick();
}
if(HUD.HEALTH <= 0 && HUD.HEALTH2 <= 0) {
GameState = STATE.EndMenu;
}
}

//----------render()----------//
//---------------------------------------------------------------------------
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if(bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);

if(GameState == STATE.Game) {
handler.render(g);
hud.render(g);
} else if(GameState == STATE.Menu) {
menu.render(g);
} else if(GameState == STATE.Help) {
help.render(g);
} else if(GameState == STATE.EndMenu) {
endMenu.render(g);
} else if(GameState == STATE.Win) {
win.render(g);
}

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

//----------clamp()----------//
//--------------------------------------------------------------------------
public static float clamp(float var, float min, float max) {
if(var >= max)
return var = max;
else if(var < min)
return var = min;
else
return var;
}

//----------main()----------//
//--------------------------------------------------------------------------
public static void main(String args[]) {
new Game();
}
}





Game.java.132: win.render(g);
Game.java.86: render();

Answer

You're getting an NPE on this line:

win.render(g);

because win is null. You've defined it, but haven't assigned a value to it.

Based on your code, you should update your Game constructor to include the following line:

win = new Win();