Search code examples
javanullpointerexceptionjframebufferedimagebufferstrategy

Why is my BufferStrategy throwing a NullpointerException and how do I fix it?


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){}
}

Solution

  • 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();
    }