我目前正在为我的计算机科学课编写Snake游戏。但是,我遇到了很多困难(因为我是我唯一一个单独工作的人),我不得不重新启动。
现在我只是想从我制作的第二个类(Segment)中创建一个对象数组(名为Snake)。
我在第26行得到一个NullPointerException:g.fillRect(xValue, yValue, size, size);
我应该在哪里获得一个Graphics实例来调用此方法?
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);
}
}
}
但是,我不断收到错误,例如
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)
答案 0 :(得分:1)
您声明Graphics g;
并且不实例化它。因此,您将null
值传递给drawSegment(Graphics g)
并尝试在该g.fillRect(xValue, yValue, size, size);
个对象上调用null
。
您正在使用的java.awt.Graphics课程只是一个抽象课程。该对象需要通过一些实现来实例化 - 无论是您还是框架。
由于您正在使用继承了Component的Applet,请尝试使用Component.getGraphics()来获取图形对象。
private Graphics g = getGraphics();
然后,在构造函数中调用绘图方法。这不是一个好习惯。实例化一个对象(这里是一个小程序)并绘制它是不一样的。
此外,这里的每个类都有自己的Graphics变量。似乎应该将单个实例用于所有绘图,并传递给每个可绘制对象。
答案 1 :(得分:1)
从自定义绘制组件的Graphics
或paint(Graphics)
方法中获取paintComponent(Graphics)
个对象。那个时候(当JVM要求这样做时)是应该绘制AWT / Swing GUI的时间。有关详细信息和工作来源,请参阅Performing Custom Painting。
Panel
,Canvas
或JPanel
中进行自定义渲染会更好,而不是容器本身。这更容易适应,因为我们可能会在小程序,框架,对话框或另一个面板的布局约束中显示面板。还有其他优点。SnakeGame
应该是applet。 Segment
类应该知道如何在被要求时将自己绘制到{{1}}对象。然后Graphics
可以存储SnakeGame
个对象的列表,并且(在请求时)依次绘制每个对象。Segment
方法中“仅在第一次”执行所有操作。但严重的是,避免使用applet,因为它们是一种过时的技术,除了头痛之外什么也不会给你带来任何麻烦。