我一直在研究詹姆斯·乔的“初学者指南到Android游戏开发”一书,一切都很好,直到第5章。我完成了这一章,一切都很好,但当我试图运行应用程序时想出了两个我以前从未见过的NullPointerExceptions。我通过将它与可下载的源代码进行比较来仔细检查我的代码,它完全相同,但我仍然得到错误。
这是我运行应用程序时控制台所说的内容
/usr/lib/jvm/default-java/bin/java -Didea.launcher.port=7543 -Didea.launcher.bin.path=/home/jake/IntelliJ/idea/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/default-java/jre/lib/jsse.jar:/usr/lib/jvm/default-java/jre/lib/javazic.jar:/usr/lib/jvm/default-java/jre/lib/management-agent.jar:/usr/lib/jvm/default-java/jre/lib/jce.jar:/usr/lib/jvm/default-java/jre/lib/compilefontconfig.jar:/usr/lib/jvm/default-java/jre/lib/rt.jar:/usr/lib/jvm/default-java/jre/lib/resources.jar:/usr/lib/jvm/default-java/jre/lib/rhino.jar:/usr/lib/jvm/default-java/jre/lib/charsets.jar:/usr/lib/jvm/default-java/jre/lib/ext/dnsns.jar:/usr/lib/jvm/default-java/jre/lib/ext/java-atk-wrapper.jar:/usr/lib/jvm/default-java/jre/lib/ext/localedata.jar:/usr/lib/jvm/default-java/jre/lib/ext/pulse-java.jar:/usr/lib/jvm/default-java/jre/lib/ext/zipfs.jar:/usr/lib/jvm/default-java/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/default-java/jre/lib/ext/sunpkcs11.jar:/home/jake/Git/LoneBall/out/production/LoneBall:/home/jake/IntelliJ/idea/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain com.jakevw.game.main.GameMain
Loaded Successfully
Entered MenuState
Exception in thread "Game Thread" java.lang.NullPointerException
at com.jakevw.game.state.PlayState.update(PlayState.java:35)
at com.jakevw.game.main.Game.run(Game.java:67)
at java.lang.Thread.run(Thread.java:745)
Process finished with exit code 0
这是我的PlayState课程:
package com.jakevw.game.state;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import com.jakevw.game.main.GameMain;
import com.jakevw.game.main.Resources;
import com.jakevw.game.model.Ball;
import com.jakevw.game.model.Paddle;
public class PlayState extends State {
private Paddle paddleLeft, paddleRight;
private static final int PADDLE_WIDTH = 15;
private static final int PADDLE_HEIGHT = 60;
private Ball ball;
private static final int BALL_DIAMETER = 20;
private int playerScore = 0;
private Font scoreFont;
@Override
public void init() {
paddleLeft = new Paddle(0, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
paddleRight = new Paddle(785, 195, PADDLE_WIDTH, PADDLE_HEIGHT);
scoreFont = new Font("SansSerif", Font.BOLD, 25);
ball = new Ball(300, 200, BALL_DIAMETER, BALL_DIAMETER);
}
@Override
public void update() {
paddleLeft.update();
paddleRight.update();
ball.update();
if (ballCollides(paddleLeft)) {
playerScore++;
ball.onCollideWith(paddleLeft);
Resources.hit.play();
} else if (ballCollides(paddleRight)) {
playerScore++;
ball.onCollideWith(paddleRight);
Resources.hit.play();
} else if (ball.isDead()) {
playerScore -= 3;
ball.reset();
}
}
@Override
public void render(Graphics g) {
// Draw Background
g.setColor(Resources.darkBlue);
g.fillRect(0, 0, GameMain.GAME_WIDTH, GameMain.GAME_HEIGHT);
g.setColor(Resources.darkRed);
g.fillRect(GameMain.GAME_WIDTH / 2, 0, GameMain.GAME_WIDTH / 2,
GameMain.GAME_HEIGHT);
// Draw Separator Line
g.drawImage(Resources.line, (GameMain.GAME_WIDTH / 2) - 2, 0, null);
// Draw Paddles
g.setColor(Color.white);
g.fillRect(paddleLeft.getX(), paddleLeft.getY(), paddleLeft.getWidth(),
paddleLeft.getHeight());
g.fillRect(paddleRight.getX(), paddleRight.getY(),
paddleRight.getWidth(), paddleRight.getHeight());
// Draw Ball
g.drawRect(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
// Draw UI
g.setFont(scoreFont); // Sets scoreFont as current font
g.drawString("" + playerScore, 350, 40); // Draws String using current
// font
}
@Override
public void onClick(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void onKeyPress(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
paddleLeft.accelUp();
paddleRight.accelDown();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
paddleLeft.accelDown();
paddleRight.accelUp();
}
}
@Override
public void onKeyRelease(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP
|| e.getKeyCode() == KeyEvent.VK_DOWN) {
paddleLeft.stop();
paddleRight.stop();
}
}
private boolean ballCollides(Paddle p) {
return ball.getRect().intersects(p.getRect());
}
}
这是我的游戏课程:
package com.jakevw.game.main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Graphics;
import javax.swing.JPanel;
import com.jakevw.game.state.LoadState;
import com.jakevw.game.state.State;
import com.jakevw.framework.util.InputHandler;
@SuppressWarnings("serial")
public class Game extends JPanel implements Runnable {
private int gameWidth;
private int gameHeight;
private Image gameImage;
private volatile State currentState;
private volatile boolean running;
private InputHandler inputHandler;
public Game(int gameWidth, int gameHeight) {
this.gameWidth = gameWidth;
this.gameHeight = gameHeight;
setPreferredSize(new Dimension(gameWidth, gameHeight));
setBackground(Color.BLACK);
setFocusable(true);
requestFocus();
}
public void setCurrentState(State newState){
System.gc();
currentState = newState;
newState.init();
inputHandler.setCurrentState(currentState);
}
private void initInput() {
inputHandler = new InputHandler();
addKeyListener(inputHandler);
addMouseListener(inputHandler);
}
@Override
public void addNotify() {
super.addNotify();
initInput();
setCurrentState(new LoadState());
initGame();
}
private void initGame() {
running = true;
Thread gameThread = new Thread(this, "Game Thread");
gameThread.start();
}
@Override
public void run() {
while (running) {
currentState.update();
prepareGameImage();
currentState.render(gameImage.getGraphics());
repaint();
try {
Thread.sleep(14);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.exit(0);
}
private void prepareGameImage() {
if (gameImage == null) {
gameImage = createImage(gameWidth, gameHeight);
}
Graphics g = gameImage.getGraphics();
g.clearRect(0, 0, gameWidth, gameHeight);
}
public void exit() {
running = false;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (gameImage == null) {
return;
}
g.drawImage(gameImage, 0, 0, null);
}
}
如果有人需要查看任何其他代码,您可以查看我的GutHub:
https://github.com/JakeVdub/LoneBall
希望有人可以帮我解决这个问题,请提前感谢您花时间帮助像我这样的初学者!
答案 0 :(得分:1)
在游戏课程中,您应该先将newState
初始化,然后再将其设为currentState
!
public void setCurrentState(State newState) {
System.gc();
currentState = newState;
newState.init();
inputHandler.setCurrentState(currentState);
}
应该是:
public void setCurrentState(State newState){
System.gc();
newState.init();
currentState = newState;
inputHandler.setCurrentState(currentState);
}
如果您有任何其他问题,请在本书的论坛上告诉我。 jamescho7.com/forum