添加 keylistener returns 空指针异常
adding keylistener returns null pointer exception
我在 java 中学习 2d 游戏编程已经有一段时间了。在我最近的游戏中,我尝试创建一个私人 class 来处理来自玩家 class 的关键事件,我是这样做的:
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
}
}
这里是我尝试将事件处理程序 class 添加到处理游戏循环、绘画等的 class 的地方:
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,但是要么没有额外的 class(在相同的 class 游戏循环中实现这些方法),要么创建一个完全不同的 [=25] =] 并使用它的实例。
无论如何,我尝试了不同的做法,因为它看起来更舒服,但它总是 returns 错误 java.lang.NullPointerException 我不明白为什么。
感谢帮助
Applet
的生命周期从 init
开始,然后 start
被调用。
您在 start
中初始化播放器,它在 init
之后调用,因此 init
中的 p
为空。
在 init
方法中创建播放器。
见Applet lifecycle: what's the practical difference between init() & start(), and destroy() & stop()?
尝试进行这些更改:
让你的 Player 变量 non-static.
在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());
}
我在 java 中学习 2d 游戏编程已经有一段时间了。在我最近的游戏中,我尝试创建一个私人 class 来处理来自玩家 class 的关键事件,我是这样做的:
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
}
}
这里是我尝试将事件处理程序 class 添加到处理游戏循环、绘画等的 class 的地方:
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,但是要么没有额外的 class(在相同的 class 游戏循环中实现这些方法),要么创建一个完全不同的 [=25] =] 并使用它的实例。
无论如何,我尝试了不同的做法,因为它看起来更舒服,但它总是 returns 错误 java.lang.NullPointerException 我不明白为什么。
感谢帮助
Applet
的生命周期从 init
开始,然后 start
被调用。
您在 start
中初始化播放器,它在 init
之后调用,因此 init
中的 p
为空。
在 init
方法中创建播放器。
见Applet lifecycle: what's the practical difference between init() & start(), and destroy() & stop()?
尝试进行这些更改:
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());
}