我正在尝试为类创建一个java applet游戏,允许用户上下移动来移动"播放器"拍摄"僵尸"使用空格键。我有一个"子弹"我正在尝试使用KeyListener,以便当用户按下空格键时," bullet"图像显示在屏幕上的玩家当前位置并在屏幕上移动。但是,当按下空格时,我会收到运行时错误,并且不会显示项目符号图像。如果有人能告诉我如何解决这个问题,我将非常感激!
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class ZombieAttackMain extends Applet implements Runnable, KeyListener{
private Image background, normalZombie, fastZombie, tankyZombie,player,bullet, bloodSplat, cow;
private Graphics bufferGraphics;
private Graphics g;
private Image offScreen;
private final int POSITION_1_Y = 100;
private final int POSITION_2_Y = 255;
private final int POSITION_3_Y = 400;
private final int POSITION_4_Y = 550;
private final int PLAYER_X_POSITION = 250;
private int playerYPosition = POSITION_3_Y;
private int zombieStartingXPosition = 1000; //change to 1100 later
private final int NORMAL_ZOMBIE_DX = -2; //not final
private final int FAST_ZOMBIE_DX = -3; //not final
private final int TANKY_ZOMBIE_DX = -1; //not final
private int zombieYPosition; //depends on the zombieYPositionRandom
private int bulletStartingXPosition = 405;
private int bulletYPosition; //depends on player position
private final int BULLET_DX = 5; //not final
private int bloodSplatX, bloodSplatY; //depend on dead zombie position
//Called when applet starts
public void init(){
setSize(1100, 700);
normalZombie = getImage(getCodeBase(), "NormalZombie.png");
tankyZombie = getImage(getCodeBase(), "TankyZombie.png");
fastZombie = getImage(getCodeBase(), "FastZombie.png");
player = getImage(getCodeBase(), "Player.png");
bullet = getImage(getCodeBase(), "Bullet.png");
bloodSplat = getImage(getCodeBase(), "BloodSplat.png");
background = getImage(getCodeBase(), "Background.jpg");
cow = getImage(getCodeBase(), "Cow.png");
addKeyListener(this);
}
//Called after init, sets up thread and starts it
public void start() {
Thread thread = new Thread(this);
thread.start();
}
public void run() {
while(true){
repaint();
try {
Thread.sleep(17); //about 60 fps
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void update(Graphics g){
if(offScreen == null){
offScreen = createImage(this.getWidth(), this.getHeight());
bufferGraphics = offScreen.getGraphics();
}
bufferGraphics.setColor(getBackground());
bufferGraphics.fillRect(0,0,this.getWidth(),this.getHeight());
bufferGraphics.setColor(getForeground());
paint(bufferGraphics);
g.drawImage(offScreen,0,0,this);
}
public void paint(Graphics g){
g.drawImage(background,0,0,null);
g.drawImage(cow,-15,115,null);
g.drawImage(cow,-15,255,null);
g.drawImage(cow,-15,400,null);
g.drawImage(cow,-15,550,null);
g.drawImage(normalZombie,zombieStartingXPosition,100,null);
g.drawImage(tankyZombie,zombieStartingXPosition,400,null);
g.drawImage(fastZombie,zombieStartingXPosition,255,null);
g.drawImage(player,PLAYER_X_POSITION,playerYPosition, null);
//g.drawImage(bullet,bulletStartingXPosition,336,this);
g.drawImage(bloodSplat,bloodSplatX,bloodSplatY,null);
}
public void moveUp(Image player){
if(playerYPosition == POSITION_2_Y){
playerYPosition = POSITION_1_Y;
}
if(playerYPosition == POSITION_3_Y){
playerYPosition = POSITION_2_Y;
}
if(playerYPosition == POSITION_4_Y){
playerYPosition = POSITION_3_Y;
}
}
public void moveDown(Image player){
if(playerYPosition == POSITION_3_Y){
playerYPosition = POSITION_4_Y;
}
if(playerYPosition == POSITION_2_Y){
playerYPosition = POSITION_3_Y;
}
if(playerYPosition == POSITION_1_Y){
playerYPosition = POSITION_2_Y;
}
}
public void spawnBullet(){
g.drawImage(bullet,bulletStartingXPosition, playerYPosition,null);
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_UP:
moveUp(player);
break;
case KeyEvent.VK_DOWN:
moveDown(player);
break;
case KeyEvent.VK_SPACE:
spawnBullet();
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void stop() {
}
public void destroy() {
}
}
错误讯息:
Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at ZombieAttackMain.spawnBullet(ZombieAttackMain.java:118)
at ZombieAttackMain.keyPressed(ZombieAttackMain.java:130)
at java.awt.Component.processKeyEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
答案 0 :(得分:1)
您的问题是您从未初始化private Graphics g
。这可能一开始看起来不太明显,因为您的paint()
和update()
方法使用g
就好了,但在这些方法中,g
是完全不同的,本地的{{1}对象这会使您的全局Graphics
黯然失色。我的建议是删除g
,因为实际上没有必要让另一个private Graphics g;
对象浮动,并将Graphics
更改为:
spawnBullet()
但是,因为每次更新都会清除整个屏幕,所以这不会显示子弹......仅使用public void spawnBullet(){
bufferGraphics.drawImage(bullet, bulletStartingXPosition, playerYPosition, null);
}
方法绘制会更好,但这完全是另一个主题。
编辑:显示如何让子弹实际显示的示例
paint()