我的示例 Java 2D 游戏有点问题。一切都很好,直到出现了一些讨厌的 NullPointerException 错误,我真的不知道为什么会这样。
我试图自己调试它(我通常这样做),我设法找到了一条导致错误的行。
g.drawImage(character, survivor.getCenterX() - 18, survivor.getCenterY() - 18, this);
我知道那character
是空的,这会导致错误。但我不知道为什么它是 null 以及如何修复它。
这是错误日志:
Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at blugame.Blu.paint(Blu.java:97)
at blugame.Blu.update(Blu.java:90)
at sun.awt.RepaintArea.updateComponent(Unknown Source)
at sun.awt.RepaintArea.paint(Unknown Source)
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我正在使用这里的教程,而不是完全复制粘贴或重写它,所以我想这就是出现错误的原因。我只是将本教程用作一般游戏编程的参考,因为这是我的第一种方法。:)
现在 - 源代码。
蓝光类:
package blugame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
public class Blu extends Applet implements Runnable, MouseListener, KeyListener {
private final int WIDTH = 800;
private final int HEIGHT = 480;
private Map map;
private Survivor survivor;
private Image image, character;
private Graphics second;
private URL base;
public void init() {
setSize(WIDTH, HEIGHT);
setFocusable(true);
setBackground(Color.BLACK);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Blu Alpha");
frame.addMouseListener(this);
addMouseListener(this);
frame.addKeyListener(this);
addKeyListener(this);
try {
base = getDocumentBase();
} catch (Exception e) {
e.printStackTrace();
}
// Images:
try {
character = getImage(base, "data/survivor.png");
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
Thread thread = new Thread(this);
thread.start();
new Map(WIDTH, HEIGHT);
new Survivor(WIDTH / 2, HEIGHT / 2);
}
public void stop() {
}
public void destroy() {
}
@Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getHeight(), this.getWidth());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
@Override
public void paint(Graphics g) {
g.drawImage(character, survivor.getCenterX() - 18,
survivor.getCenterY() - 18, this);
}
@Override
public void mouseClicked(MouseEvent e) {
switch (e.getButton()) {
case MouseEvent.BUTTON1:
System.out.println("Action log: Mouse clicked at (" + e.getX()
+ ", " + e.getY() + ") with button 1.");
break;
case MouseEvent.BUTTON2:
System.out.println("Action log: Mouse clicked at (" + e.getX()
+ ", " + e.getY() + ") with button 2.");
break;
case MouseEvent.BUTTON3:
System.out.println("Action log: Mouse clicked at (" + e.getX()
+ ", " + e.getY() + ") with button 3.");
break;
}
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Action log: Mouse entered.");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Action log: Mouse exited.");
}
@Override
public void mousePressed(MouseEvent e) {
// TODO
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
System.out.println("Action log: key 'W' pressed.");
break;
case KeyEvent.VK_S:
System.out.println("Action log: key 'S' pressed.");
break;
case KeyEvent.VK_A:
System.out.println("Action log: key 'A' pressed.");
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
System.out.println("Action log: key 'W' released.");
break;
case KeyEvent.VK_S:
System.out.println("Action log: key 'S' released.");
break;
case KeyEvent.VK_A:
System.out.println("Action log: key 'A' released.");
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
班级幸存者:
package blugame;
public class Survivor {
private int centerX;
private int centerY;
private int speedX;
private int speedY;
private boolean jumped;
private boolean alive;
Survivor() {
this.centerX = 100;
this.centerY = 100;
this.speedX = 0;
this.speedY = 0;
this.jumped = false;
this.alive = true;
}
Survivor(int centerX, int centerY) {
this.centerX = centerX;
this.centerY = centerY;
this.speedX = 0;
this.speedY = 0;
this.jumped = false;
this.alive = true;
}
Survivor(int centerX, int centerY, int speedX, int speedY) {
this.centerX = centerX;
this.centerY = centerY;
this.speedX = speedX;
this.speedY = speedY;
this.jumped = false;
this.alive = true;
}
Survivor(int centerX, int centerY, int speedX, int speedY, boolean jumped,
boolean alive) {
this.centerX = centerX;
this.centerY = centerY;
this.speedX = speedX;
this.speedY = speedY;
this.jumped = jumped;
this.alive = alive;
}
public void update(Map m) {
// X movement.
if (speedX < 0) {
centerX -= speedX;
if (centerX < m.getScrollLeft() + 18) {
// Scroll to the left.
} else {
// Do not scroll yet.
}
} else if (speedX > 0) {
centerX += speedX;
if (centerX > m.getScrollRight() - 18) {
// Scroll the the right.
} else {
// Do not scroll yet.
}
} else {
// Do not scroll at all.
}
// Y movement.
if (centerY + speedY >= m.getGround() + 16) {
centerY = m.getGround();
} else {
centerY += speedY;
}
if (jumped == true) {
speedY += 1;
if (centerY + speedY >= m.getGround()) {
centerY = m.getGround() + 16;
speedY = 0;
jumped = false;
}
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void stop() {
speedX = 0;
}
public void jump() {
if(jumped == false) {
speedY = -15;
jumped = true;
}
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public boolean isJumped() {
return jumped;
}
public boolean isAlive() {
return alive;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public void setJumped(boolean jumped) {
this.jumped = jumped;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
}
最后是类 Map (尚未真正使用):
package blugame;
public class Map {
private int height;
private int width;
private int ground;
private int scrollLeft;
private int scrollRight;
Map(int height, int width) {
this.height = height;
this.width = width;
}
public int getHeight() {
return this.height - 1;
}
public int getWidth() {
return this.width - 1;
}
public int getGround() {
return this.ground - 1;
}
public int getScrollLeft() {
return this.scrollLeft - 1;
}
public int getScrollRight() {
return this.scrollRight - 1;
}
public void calcGround() {
this.ground = this.height - (this.height / 4);
}
public void calcScrollLeft() {
this.scrollLeft = this.width / 3;
}
public void calcScrollRight() {
this.scrollRight = this.width - (this.width / 3);
}
}
我知道这个character
对象很可能是一个空值(Captain Obvious!),但我不知道如果:
try {
base = getDocumentBase();
} catch (Exception e) {
e.printStackTrace();
}
// Images:
try {
character = getImage(base, "data/survivor.png");
} catch (Exception e) {
e.printStackTrace();
}
我的survivor.png
文件位于Blu/data/survivor.png
. 那么有什么问题呢?任何人?