我正在学习用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,我不明白为什么。
感谢您的帮助
答案 0 :(得分:1)
Applet
的生命周期以init
开头,后来start
被调用。
您在start
之后调用了init
中的播放器,因此p
中的init
为空。
使用init
方法创建播放器。
请参阅Applet lifecycle: what's the practical difference between init() & start(), and destroy() & stop()?
答案 1 :(得分:0)
尝试进行这些更改:
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());
}