I am currently coding the game of Snake for my computer science class. However, I ran into a lot of difficulties (since I am the only one in my block that is working alone) and I had to restart.
Right now I am just trying to make an array of objects (named Snake) from the second class (Segment) I made.
I get a NullPointerException on line 26: g.fillRect(xValue, yValue, size, size);
Where should I get an instance of Graphics to call this method on?
import java.awt.*;
import java.applet.*;
public class Segment extends Applet
{
private Graphics g;
private int xValue;
private int yValue;
private int size;
public Segment () {}
public Segment(int x, int y)
{
xValue = x;
yValue = y;
size = 10;
drawSegment(g);
}
public void drawSegment(Graphics g)
{
g.fillRect(xValue, yValue, size, size);
}
}
import java.awt.*;
import java.applet.*;
public class SnakeGame extends Applet
{
private Segment[] snake;
private Graphics g;
private int length;
private int sxValue;
private int syValue;
public SnakeGame()
{
length = 6;
snake = new Segment[length];
sxValue = 100;
syValue = 100;
for (int c = 0; c < snake.length; c++)
{
snake[c] = new Segment(sxValue, syValue);
sxValue = sxValue + 10;
}
drawSnake(g);
}
public void drawSnake(Graphics g)
{
for(int counter = 0; counter < length; counter++)
{
snake[counter].drawSegment(g);
}
}
}
However, I keep getting errors such as
java.lang.NullPointerException
at Segment.drawSegment(Segment.java:26)
at Segment.<init>(Segment.java:21)
at SnakeGame.<init>(SnakeGame.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.Class.newInstance(Class.java:433)
at sun.applet.AppletPanel.createApplet(AppletPanel.java:799)
at sun.applet.AppletPanel.runLoader(AppletPanel.java:728)
at sun.applet.AppletPanel.run(AppletPanel.java:378)
at java.lang.Thread.run(Thread.java:745)
You declare Graphics g;
and do not instantiate it. So you pass a null
value to drawSegment(Graphics g)
and try to call g.fillRect(xValue, yValue, size, size);
on that null
object.
The java.awt.Graphics class you're using is just an abstract class. The object needs to be instantiated with some implementation - either by you or the framework.
Since you're using an Applet , which inherits the Component, try Component.getGraphics() to get a graphics object.
private Graphics g = getGraphics();
Then, you call drawing methods in constructors. That's not a good practice. Instantiating an object (an applet, here) and drawing it is not the same.
Also, each class here has its own variable for Graphics. It seems that a single instance should be used for all drawing, passed to each drawable object.
Get a Graphics
object from within the paint(Graphics)
or paintComponent(Graphics)
method of the custom painted component. That time (when requested to do so by the JVM) is the time that an AWT/Swing GUI should be painted. See Performing Custom Painting for more details and working source.
Panel
, Canvas
or JPanel
that is added to the top level container, rather than the container itself. This is more easily adaptable in that we might show the panel in an applet, frame, dialog or a layout constraint of another panel. There are also other advantages. SnakeGame
should be an applet. The Segment
class should instead just know how to draw itself to a Graphics
object when asked to do so. Then SnakeGame
can store a list of Segment
objects and (when requested) draw each in turn. init()
method. But seriously, avoid applets as they are an obsolescent technology that will give you nothing but headaches.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.