【问题标题】:adding keylistener returns null pointer exception添加keylistener返回空指针异常
【发布时间】:2016-01-05 20:00:03
【问题描述】:

我学习用 java 编写 2d 游戏已经有一段时间了。在我最近的游戏中,我尝试创建一个私有类来处理 Player 类中的关键事件,我是这样做的:

package game;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Player {

    final private int MOVEMENTSPEED = 4;
    final private int BOOST = 8;
    final private EventHandler HANDLER = new EventHandler();

    private int x, y;
    private int speedX, speedY;

    public Player(int x, int y){
        this.x = x;
        this.y = y;
    }

    public void update(){
        x += speedX;
        y += speedY;
    }

    public int getSpeedX() {
        return speedX;
    }

    public int getSpeedY() {
        return speedY;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public EventHandler getHandler(){
        return HANDLER;
    }

    private class EventHandler implements KeyListener{

        @Override
        public void keyPressed(KeyEvent e) {
            switch(e.getKeyCode()){
            case KeyEvent.VK_W: speedY = -MOVEMENTSPEED;
                break;
            case KeyEvent.VK_S: speedY = MOVEMENTSPEED;
                break;
            case KeyEvent.VK_A: speedX = -MOVEMENTSPEED;
                break;
            case KeyEvent.VK_D: speedX = MOVEMENTSPEED;
                break;
            }

        }

        @Override
        public void keyReleased(KeyEvent e) {
            switch(e.getKeyCode()){
            case KeyEvent.VK_W: speedY = 0;
            case KeyEvent.VK_S: 
                break;
            case KeyEvent.VK_A: speedX = 0;
            case KeyEvent.VK_D: 
                break;
            }   
        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }
    }

在这里我尝试将 eventHandler 类添加到处理游戏循环、绘画等的类中:

public class FrameWork extends Applet implements Runnable {

private URL base;
private Graphics second;

private Image image;

public static Player p;


@Override
public void start() {
    p = new Player(400, 400);
    Thread thread = new Thread(this);
    thread.start();
}

@Override
public void init() {
    setSize(1000, 600);
    setFocusable(true);
    Frame frame = (Frame) this.getParent().getParent();
    frame.setTitle("Assassin");
    frame.setResizable(false);
    **this.addKeyListener(p.getHandler());**
}

我已经使用过 keylistener,但要么没有额外的类(在游戏循环的同一类中实现方法),要么创建了一个完全不同的类并使用它的实例。

无论如何,我尝试以不同的方式进行操作,因为它看起来更舒服,但它总是返回错误 java.lang.NullPointerException,我不明白为什么。

感谢您的帮助

【问题讨论】:

标签: java nullpointerexception keyevent


【解决方案1】:

Applet 的生命周期从 init 开始,然后调用 start。 您在start 中初始化播放器,它在init 之后调用,因此init 中的p 为空。

init 方法中创建播放器。

Applet lifecycle: what's the practical difference between init() & start(), and destroy() & stop()?

【讨论】:

  • p 不应该在 init 方法中创建,因为它是静态的(尽管这可能是错误的)。
  • 在这种情况下,可以在创建Player 之后和启动线程之前将键侦听器的注册移到start 方法中。
【解决方案2】:

尝试进行以下更改:

  • 使您的 Player 变量为非静态变量。
  • init() 方法而不是start() 方法中初始化此变量。
  • public Player p; //changed this to be an instance variable (non-static)
    
    
    @Override
    public void start() {     
                    //moved initialization of player to init() method
        Thread thread = new Thread(this);
        thread.start();
    }
    
    @Override
    public void init() {
        setSize(1000, 600);
        setFocusable(true);
        Frame frame = (Frame) this.getParent().getParent();
        frame.setTitle("Assassin");
        frame.setResizable(false);
    
        p = new Player(400, 400); //initialize Player here
        this.addKeyListener(p.getHandler());
    }
    

    【讨论】:

    • 感谢您的帮助,它成功了。我从一些指南中学习了如何使用小程序,其中变量是在 start() 中创建的(我猜是因为它在那里并不重要)。
    • @user3917631 很高兴它成功了。如果您想通过单击左侧的绿色勾号来接受此答案。我会得到一些分数,你也会得到一些分数:)
    猜你喜欢
    • 2014-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多