我正在制作“太空侵略者”类型的游戏,目前正在尝试实现碰撞检测,以便如果镜头击中目标,则将目标从帧中删除。但是我在下面的标记行上得到了空指针异常(我还将发布异常跟踪)。这是因为我没有正确设置射击对象的y坐标吗?我尝试修复此问题,但是虽然可能没有采取适当的措施,但是没有任何反应。

这是两个相关的类,如有必要,我可以发布更多内容:

public class GamePanel extends JPanel {

Launcher launcher1;
Background bground1;
public static Shot shot;
public int shotCounter;
public int rCount;
public int cCount;
Timer timer;
Timer eTimer;
Timer rTimer;
Timer cTimer;
Russia russia;
China china;
public ArrayList<Object> enemies;


public GamePanel() throws IOException {
    super();
    enemies = new ArrayList<>();
    this.shotCounter = 0;
    launcher1 = new Launcher();
    bground1 = new Background();
    timer = new Timer(10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            componentMove(3);
            repaint();
        }
    });
    rTimer = new Timer(10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            componentMove(1);
            repaint();
        }
    });
    cTimer = new Timer(10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            componentMove(2);
            repaint();
        }
    });
    eTimer = new Timer(10, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            addEnemy();
            eTimer.setDelay(7000);
            repaint();
        }
    });
    eTimer.start();
}//end constructor

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(bground1.background, 0, 0, getWidth(), getHeight(), null);
    g.drawImage(launcher1.baldEagleImage, launcher1.getLxCoord(), launcher1.lyCoord, null);//paint the launcher
    if (rCount == 1) {
        g.drawImage(russia.image, russia.getXCoord(), russia.getYCoord(), null);
        rTimer.start();
    }
    if (cCount == 1) {
        g.drawImage(china.image, china.getXCoord(), china.getYCoord(), null);
        cTimer.start();
    }
    if (shotCounter == 1) {
        g.drawImage(shot.mcDShotImage, shot.staticXLauncherCoord, shot.getSyCoord(), null);
        timer.start();
    }
}//end paintComponent method

public void move(GamePanel gamePanel) {
    launcher1.moveX();
    repaint();
}//end move method

public void componentMove(int c) {
    if (c == 1) {
        do {
            russia.move();
        } while (!collisionDetected(russia));
    } else if (c == 2) {
        do {
            china.move();
        } while (!collisionDetected(china));
    } else if (c == 3) {
        shot.moveY();
    }
}

public boolean collisionDetected(Entity object) {
    // Create variables to hold temporary values to check for ball colision
    int oTempX = object.getXCoord();
    int oTempY = object.getYCoord();
    int oTempW = object.getImageWidth();
    int oTempH = object.getImageHeight();
    int sTempX = shot.staticXLauncherCoord;
    int sTempY = shot.getSyCoord();     // THIS IS THE EXCEPTION
    int sTempH = shot.mcDShotImage.getHeight();
    int sTempW = shot.mcDShotImage.getWidth();
    double xDiff = Math.pow((oTempX - sTempX), 2);
    double yDiff = Math.pow((oTempY - sTempY), 2);
    double hSum = Math.pow(oTempH + sTempH, 2);
    double wSum = Math.pow(oTempW + sTempW, 2);
    if (shotCounter == 1) {
        if ((xDiff + yDiff) <= hSum) {//use the ball heights to check if two balls intersect
            if ((xDiff + yDiff) <= wSum) {//use the ball widths to check if two balls intersect
                enemies.remove(this);
                repaint();
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    } else {
    return false;
    }
}

public void addShot() {
    try {
        shot = new Shot();
        shotCounter = 1;
        repaint();
    } catch (IOException ex) {
    }
}

public void addEnemy() {
    int enemy = (int) (Math.round(Math.random()));
    if (enemy == 0) {
        try {
            enemies.add(russia = new Russia());
            rCount = 1;
            repaint();
        } catch (IOException ex) {
        }
    } else {
        try {
            enemies.add(china = new China());
            cCount = 1;
            repaint();
        } catch (IOException ex) {
        }
    }
}

}//end GamePanel class


public class Shot {

public int syCoord;
public int sRise = 1;
public BufferedImage mcDShotImage;
GamePanel gPanel;
public static int staticXLauncherCoord;

public Shot() throws IOException {
    staticXLauncherCoord = Launcher.getLxCoord() + 10;
    syCoord = 381;
    mcDShotImage = ImageIO.read(new File("mcdonaldsarchesshot.jpg"));
}//end constructor

public void moveY() {
    do {
    syCoord -= sRise;
    setSyCoord(syCoord);
    } while (syCoord <= 1);
}//end moveY method

public void setSyCoord(int syCoord) {
    this.syCoord = syCoord;
}

public int getSyCoord() {
    return syCoord;
}

}//end Shot class


这是异常打印输出:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at GamePanel.collisionDetected(GamePanel.java:125)
at GamePanel.componentMove(GamePanel.java:112)
at GamePanel$3.actionPerformed(GamePanel.java:65)
at javax.swing.Timer.fireActionPerformed(Timer.java:312)
at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

最佳答案

您在哪里/什么时候调用addShot?这是显示shot初始化(通过shot = new Shot())的唯一逻辑。

从堆栈跟踪看来,actionPerformed调用了componentMove,后者又调用了collisionDetected,但是这些都不调用addShot,因此您的公共静态shot永远不会初始化并且为null(因此是例外)。

请注意,访问shot的公共静态staticXLauncherCoord是没有问题的,因为它是静态的,并且没有绑定到Shot的实例。

10-08 01:00