初学者Android开发指南中的NullPointerException [第5章]

时间:2014-10-26 04:36:15

标签: java nullpointerexception null

我一直在研究詹姆斯·乔的“初学者指南到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

希望有人可以帮我解决这个问题,请提前感谢您花时间帮助像我这样的初学者!

1 个答案:

答案 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