0
\$\begingroup\$

I'm sorry if this isn't the right place for this post, but I don't know where to go.

I'm trying to make a simple game loop but it's already failing

package main;

import javax.swing.JPanel;
import java.awt.*;
import java.awt.image.*;

public class Logic extends JPanel implements Runnable {

/**
 * 
 */
private static final long serialVersionUID = 1L;

// Main Game Stuff
private int gWidth = 800;
private int gHeight = 640;
private int scale = 2;

private int fps = 30;

private boolean running;

private Thread thread;
private BufferedImage image;
private Graphics2D g;

public Logic(){
    super();
    setPreferredSize(new Dimension(gWidth, gHeight));
    setFocusable(true);
    requestFocus();
}

public void addNotify(){
    if(thread==null)
    {
        thread=new Thread(this);
        thread.start();
    }
}

public void init()
{
    image = new BufferedImage(
            gWidth, gHeight, BufferedImage.TYPE_INT_RGB
        );
    g = (Graphics2D) image.getGraphics();
    System.out.println("Hello!");
    running = true;
}



private void update() //main logic
{
    //do stuff
}

private void render(Graphics2D g)
{
    g.setColor(Color.BLUE);
    g.fillRect(0, 0, gWidth, gHeight);
}

private void PaintCanvas(){
    Graphics g2 = getGraphics();
    g2.drawImage(image, 0, 0, null);
    g2.dispose();
}

public void run()
{
    init();

    int loops = 0;
    long startTime = System.nanoTime();
    float rate = 1000/fps;
    long lastTime = startTime;
    float waitTime = rate;


    while(running) // game loop
    {
         long currTime = System.nanoTime();
         if(currTime > (lastTime + waitTime))
         {
             waitTime = rate;
             if((currTime - lastTime) > rate)
                 waitTime = currTime - lastTime;


             //-- Paint Canvas --//
             PaintCanvas();

             //-- LOGIC -- //

                update();

             ////////////////
             //-- RENDER --//
             if(loops % 2 == 0)// draw every second frame
             {
                 render(g);
             }
             ////////////////
             loops++;

             lastTime = currTime;
         }

    }
}

}

I keep getting this error:

Exception in thread "Thread-2" java.lang.NullPointerException
at main.Logic.PaintCanvas(Logic.java:67)
at main.Logic.run(Logic.java:93)
at java.lang.Thread.run(Unknown Source)

Why is the image null? I can't for the life of me figure it out. I already declared it in the init() function.

\$\endgroup\$
9
  • \$\begingroup\$ are you sure that its image that is null, not g2? add a breakpoint and take a look \$\endgroup\$
    – benh
    Commented Feb 27, 2017 at 11:26
  • \$\begingroup\$ hmm you're right. I feel dumb. But why would g2 be null? \$\endgroup\$
    – KozzyMoto
    Commented Feb 27, 2017 at 14:42
  • \$\begingroup\$ it must be because getGraphics() is returning null, which is likely to be because the JPanel hasn't finished initializing, perhaps try adding a catch for the null pointer exception and see if it goes away after a few frames? Also, you never use waitTime to actually wait in your game loop \$\endgroup\$
    – benh
    Commented Feb 27, 2017 at 14:50
  • \$\begingroup\$ I did the try catch, it kept giving nullpointer errors even after about 50 frames. Also is it bad to have a waitTime? Why should I never use it? \$\endgroup\$
    – KozzyMoto
    Commented Feb 27, 2017 at 15:01
  • \$\begingroup\$ I meant that from your current code, you haven't actually used the value in waitTime anywhere yet. are you sure you're setting the jpanel to be visible and fully intialised? \$\endgroup\$
    – benh
    Commented Feb 27, 2017 at 15:06

1 Answer 1

2
\$\begingroup\$

Simply override paintComponent and use the Graphics object from parameter. Your way of using Graphics object is wrong.

@Override
public void paintComponent(Graphics g) {
  // draw.
}

And use repaint to do refresh.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .