I am just starting to get into graphics and when I am trying to get the graphics, I get the error"run:
Exception in thread "Thread-2" java.lang.NullPointerException
at gamedev.Display.render(Display.java:97)
at gamedev.Display.run(Display.java:108)
at java.lang.Thread.run(Thread.java:724)"
and I have no clue on what is going on! Any help is greatly appreciated.
//The display class for the game
//Crated: 10-30-2013
//Last Modified: 10-30-2013
package gamedev;
import gamedev.Graphics.Render;
import gamedev.Graphics.Screen;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
public class Display extends Canvas implements Runnable {
public static final int GAMEWIDTH = 600;
public static final int GAMEHEIGHT = 600;
private static Thread thread;
private static boolean running = false;
private Render render;
private Screen screen;
private BufferedImage img;
private int[] pixels;
public static void main(String[] args) {
System.out.println("display.main");
Display gameWindow = new Display();
JFrame gameFrame = new JFrame();
gameFrame.add(gameWindow);
gameFrame.setResizable(false);
gameFrame.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
gameFrame.setLocation(dim.width / 2 - gameFrame.getSize().width / 2, dim.height / 2 - gameFrame.getSize().height / 2);
gameFrame.setSize(GAMEWIDTH, GAMEHEIGHT);
gameFrame.setTitle("Game Frame");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameWindow.start();
}
public Display() {
System.out.println("display.Display");
screen = new Screen(GAMEWIDTH, GAMEHEIGHT);
img = new BufferedImage(GAMEWIDTH, GAMEHEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
}
private void start() {
System.out.println("display.Started");
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private String stop() {
System.out.println("display.Stopped");
if (!running) {
System.out.println("running");
running = false;
try {
thread.join();
} catch (Exception e) {
System.exit(0);
return e.getStackTrace().toString();
}
return "Program Stopped";
} else {
return "Program Not Stopped";
}
}
private void tick() {
}
private void render() {
System.out.println("display.render");
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
}
for (int i = 0; i < GAMEWIDTH * GAMEHEIGHT; i++) {
pixels[i] = screen.PIXELS[i];
}
screen.Render();
Graphics g = bs.getDrawGraphics();
g.drawImage(img, 0, 0, GAMEWIDTH, GAMEHEIGHT, null);
g.dispose();
bs.show();
}
#Override
public void run() {
System.out.println("display.run");
while (running) {
tick();
render();
}
}
}
Change this:
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
}
to:
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
bs = this.getBufferStrategy();
}
The problem is that if bs is null, you create a buffer strategy but don't assign anything to bs.
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I've been trying to make a 3d game and for some reason my code is throwing a NullPointerException. The error I'm getting is:
Exception in thread "Thread-3"
java.lang.NullPointerException
at Display_3d.render(Display_3d.java:73)
at Display_3d.run(Display_3d.java:55)
at java.lang.Thread.run(Unknown Source)
This program is supposed to just display pixels of a random color as a test in order to make 3d graphics later. There are two other classes it uses and even though those two don't throw errors they still could be the issue so I'll post them as well. The class Below is the one that throws the errors
import java.awt.Canvas;
import javax.swing.JFrame;
import java.awt.image.BufferedImage;
import java.awt.image.BufferStrategy;
import java.awt.image.DataBufferInt;
import java.awt.Graphics;
public class Display_3d extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static final int width = 800;
public static final int height = 600;
public static final String title = "Scott's Game Pre-Alpha 0.01";
private Thread thread;
private Screen screen;
private BufferedImage img;
private boolean running = false;
private Render render;
private int[] pixels;
public Display_3d(){
Screen screen = new Screen(width,height);
img = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
}
private void start(){
if (running){
return;
}
running = true;
Thread thread = new Thread(this);
thread.start();
System.out.println("start() has been called sucessfully");
}
private void stop(){
if (true != running){
return;
}
running = false;
try {
thread.join();
}catch (Exception e){
e.printStackTrace();
System.exit(0);
}
}
public void run(){
while (running){
tick();
/*Line 55*/render();
}
}
private void tick(){
}
private void render(){
BufferStrategy bs = this.getBufferStrategy();
if (bs == null){
this.createBufferStrategy(3);
return;
}
/*Line 73*/ screen.render();
for (int i = 0; i<width*height-1; i++){
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(img,0,0,width,height,null);
g.dispose();
bs.show();
}
public static void main(String[] args){
Display_3d game = new Display_3d();
JFrame frame = new JFrame();
frame.add(game);
frame.pack();
frame.setTitle(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(width,height);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
System.out.println("Running...");
game.start();
}
}
My Render Class
public class Render{
public final int width;
public final int height;
public final int[] pixels;
public Render (int width, int height){
this.width = width;
this.height = height;
pixels = new int[width * height];
}
public void draw(Render render, int xOffset, int yOffset){
for (int y = 0; y<render.height; y++){
int yPix = y + yOffset;
for (int x = 0; x<render.width; x++){
int xPix = x + xOffset;
pixels[xPix + yPix * width] = render.pixels[x+y * render.width];
}
}
}
public static void main (String[] args){}
}
My Screen Class
import java.util.Random;
public class Screen extends Render{
private Render test;
public Screen(int width, int height){
super(width,height);
Random random = new Random();
test = new Render(256,256);
for (int i = 0; i <256*256; i++){
test.pixels[i] = random.nextInt();
}
}
public void render() {
draw(test,0,0);
}
public static void main (String[] args){}
}
In you coonstructor you create local variable
public Display_3d(){
Screen screen = new Screen(width,height); //<-------------
img = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
}
Instead assign to the field
public Display_3d(){
this.screen = new Screen(width,height); //<-------------
img = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
}
The following:
if (bs == null){
this.createBufferStrategy(3);
will create a "buffer strategy", but it will not affect the value of bs, which has just been proven to be null. Therefore, your attempt to use bs further down is guaranteed to fail.
My Java program won't display a black screen when I tell it to. I can just see a greyish window with 0 FPS.
Here is my code:
package com.none.rain;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
private boolean running = false;
private JFrame frame;
private Thread thread;
public Game() {
Dimension size = new Dimension(width*scale, height*scale);
setPreferredSize(size);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (running) {
}
}
public void update() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("Rain");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
Making the display black is something you do in your render() method, but you never call it.
If I take your code and add a call to render() in the run() method I get a frame with a black background:
public void run() {
while (running) {
render();
}
}
I'm trying to make a 2D tile based game. I have been encountering an issue when attempting to draw new graphics and the old ones don't seem to have been removed.
If anyone knows why g.dispose isn't clearing the graphics then please help.
Here's my "Main" class:
package Main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Main extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private JFrame frame;
static int size = 40;
static int tilesX = 20;
static int tilesY = 20;
static int width = size * 10;
static int height = size * 10;
private boolean running = false;
public static STATE state = STATE.MENU;
public static PLAYER type = PLAYER.ARCHER;
private Thread thread;
static tileMap grid = new tileMap();
tile[][] map = tileMap.map;
public Main() {
addKeyListener(new controls());
addMouseListener(new mouse());
Dimension wSize = new Dimension(width, height);
setPreferredSize(wSize);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "game");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public enum STATE {
MENU, GAME
}
public enum PLAYER {
ARCHER, KNIGHT
}
public static void main(String[] args) {
Main game = new Main();
game.frame = new JFrame("Game");
game.frame.add(game);
game.frame.setResizable(false);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setVisible(true);
game.start();
}
public void run() {
while (running) {
if (state == STATE.MENU) {
menu();
} else if (state == STATE.GAME) {
tick();
render();
}
try {
Thread.sleep(16);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void menu() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(2);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawRect(Main.width / 8, 20, Main.width / 3, 200);
g.drawString("Archer", Main.width / 8, 20);
g.drawRect((Main.width - Main.width / 3) - Main.width / 8, 20,
Main.width / 3, 200);
g.drawString("Knight", (Main.width - Main.width / 3) - Main.width / 8,
20);
g.dispose();
bs.show();
}
private void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D d = (Graphics2D) g;
camera.setCam();
g.translate(-camera.camX, -camera.camY);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
d.setColor(map[i][j].getC());
d.fillRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
d.setColor(Color.BLACK);
d.drawRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
}
}
map[player.p.getX()][player.p.getY()].setC(player.p.getC());
if (type == PLAYER.ARCHER) {
d.drawString("Archer", 5, 15);
} else if (type == PLAYER.KNIGHT) {
d.drawString("Knight", 5, 15);
}
g.dispose();
bs.show();
}
static public void moved() {
tileMap.map[player.p.getX()][player.p.getY()].setC(Color.GREEN);
}
private void tick() {
if (player.p == null) {
player.createP();
}
}
}
Graphics#dispose releases any internal resources that the Graphics context may be holding, reducing the memory overhead, it does not "clear" the context.
From the JavaDocs
Disposes of this graphics context and releases any system resources that it is using. A Graphics object cannot be used after dispose has been called.
What it doesn't do is effect the underlying content, that would be, well, annoying, as using a copy of a Graphics object is a good and easy way to make complex changes without effecting the original context.
To "clear" the context you could use fillRect to paint a color/background before you performing you next cycle of painting. Do this just after Graphics g = bs.getDrawGraphics();
what is wrong with this code?
I keep getting the error
Exception in thread "Thread-2" java.lang.NullPointerException
at GUI.render(GUI.java:68)
at GUI.run(GUI.java:51)
please help
import graphics.*;
import javax.swing.*;
import java.awt.*;
import java.awt.Canvas;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
public class GUI extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
final static String LABEL_TEXT = "Game";
public static final int Width = 1020;
public static final int Height = 680;
private Thread thread;
private Screen screen;
private Render render;
private BufferedImage img;
private boolean running = false;
private int[] pixels;
public void display() {
screen = new Screen(Height, Width);
vimg = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
}
private void start() {
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private void stop() {
if(!running)
return;
running = false;
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void run() {
while (running){
tick();
render();
}
}
public void tick() {
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();;
if(bs == null) {
createBufferStrategy(3);
return;
}
screen.render();
for (int i = 0; i <Width*Height; i++){
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(img, 0, 0, Width, Height, null);
g.dispose();
bs.show();
}
/**
* Create and show the GUI.
*/
public static void main(String[] args) {
/*Create Canvas*/
GUI game = new GUI();
/*Create and set up the frame*/
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*Add content pane to frame*/
frame.add(game);
/*Size and then display the frame.*/
frame.setSize(Width, Height);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
game.start();
}
}
package graphics;
public class Render {
public final int width;
public final int height;
public int[] pixels;
public Render(int height, int width) {
this.width = width;
this.height = height;
pixels = new int[width*height];
}
public void draw(Render render, int xOffset, int yOffset) {
for (int y =0; y<height; y++) {
int yPix = y + yOffset;
for (int x =0; x<width; x++) {
int xPix = x + xOffset;
pixels[xPix+yPix*width] = pixels[x+y*width];
}
}
}
}
package graphics;
import java.util.Random;
import graphics.Render;
public class Screen extends Render{
private Render test;
public Screen(int width, int height) {
super(width, height);
Random rand = new Random();
test = new Render(256, 256);
for (int i =0; i< 256*256; i++){
test.pixels[i] = rand.nextInt();
}
}
public void render() {
draw(test, 0, 0);
}
}
You haven't called display() to initialize your variables before you use them.
I decided to start understanding BufferStrategy for my graphics.
I'm not sure if using my jframe in a static form is what's cause this, but it looks alright to me. What am I missing?
Main.java
package Main;
import java.awt.Toolkit;
public class Main implements Runnable {
private Thread gameThread;
private Game game;
private boolean running = false;
public static ClientFrame frame;
public static Toolkit kit;
public static int WIDTH = 300, HEIGHT = WIDTH*16/9, SCALE = 3;
public Main() {
game = new Game();
frame = new ClientFrame(game);
kit = frame.getToolkit();
frame.setVisible(true);
start();
}
public synchronized void start() {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
public synchronized void stop() {
running = false;
gameThread.interrupt();
}
public void run() {
long startTime = System.nanoTime();
double nanoSec = 1000000000/60;
double delta = 0;
while(running) {
long currentTime = System.nanoTime();
delta += (currentTime - startTime)/nanoSec;
while(delta >= 1) {
game.update();
delta--;
}
game.render();
startTime = currentTime;
}
}
public static void main(String[] args) {
new Main();
}
}
Game.java
package Main;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JPanel;
public class Game extends JPanel {
Player player;
int tileArea = 32;
public Game() {
player = new Player();
setPreferredSize(new Dimension(Main.WIDTH*Main.SCALE, Main.HEIGHT*Main.SCALE));
}
public void update() {
}
public void render() {
BufferStrategy bs = Main.frame.getBufferStrategy();
if(bs == null)
Main.frame.createBufferStrategy(3);
Graphics g = bs.getDrawGraphics();
player.paint(g);
g.dispose();
bs.show();
}
}
My Player.java only contains one method:
public void paint(Graphics g) {
g.fillRect(25, 25, 50, 50);
}
ERROR:
Exception in thread "Thread-2" java.lang.NullPointerException
at Main.Game.render(Game.java:30)
at Main.Main.run(Main.java:52)
at java.lang.Thread.run(Unknown Source)
You do not try to get the buffer strategy after you have created it:
BufferStrategy bs = Main.frame.getBufferStrategy();
if(bs == null)
Main.frame.createBufferStrategy(3);
// if bs was null before, it still is null
Graphics g = bs.getDrawGraphics();
Also note the point by #MadProgrammer that the buffer strategy belongs to a different component. If your intent is to create an AWT game (I'd recommend swing instead), you should probably use Canvas, and its createBufferStrategy().
try replacing
if(bs == null)
Main.frame.createBufferStrategy(3);
with
if (bs == null) {
Main.frame.crcreateBufferStrategy(3);
return;
}