2014-04-23 101 views
0

我正在製作太空入侵者類型的遊戲,並且我正在嘗試實施碰撞檢測,以便如果擊中目標,目標將從框架中移除。但是我在下面的標記行中得到一個空指針異常(我也會發布異常跟蹤)。問題是因爲我沒有正確設置拍攝對象的y座標嗎?我試圖解決這個問題,但沒有發生任何事情,儘管我可能沒有以適當的方式做到這一點。嘗試獲取對象的y座標時無法解決NullPointerException

這裏有兩個相關的課程,我可以張貼更多,如果必要的:

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) 
+4

我強烈懷疑'shot'是空的。由於您正在訪問一個靜態變量,因此您不會在上一行中發現它,因此可以更好地將其寫爲'Shot.staticXLauncherCoord',以清楚說明'shot'的*值*不相關。它確實沒有幫助,每次你捕捉到一個異常,你吞下* no *日誌記錄或其他體面的處理。 –

+0

@JonSkeet是的,你是對的。我是愚蠢的,必須在我的構造函數中意外粘貼addShot()調用。謝謝,對不起,浪費時間! – Ben

回答

1

你在哪裏/何時調用addShot?這是shot初始化的唯一邏輯(通過shot = new Shot())。

從您的堆棧跟蹤,似乎actionPerformed電話componentMove這就要求collisionDetected,但是這些都曾經呼籲addShot等你的公共靜態shot從未初始化,併爲空(因此除外)。

請注意,訪問shot的公共靜態staticXLauncherCoord不是問題,因爲它是靜態的,並且與Shot的實例無關。

+0

謝謝!當我在複製新的東西時,我必須在我的構造函數中意外地粘貼了addShot()。那是愚蠢的我不能看到,我被扔掉了,因爲我把鏡頭的staticXLauncherCoord字段變成靜態的,我正在被愚蠢和忘記。 – Ben

1

你沒有初始化出手。可能是因爲collisionDetected()在addShot()之前被調用。

+0

你是對的,我是愚蠢的,沒有注意到。我一定在意外時在我的構造函數中粘貼了我的addShot()調用。謝謝,對不起,浪費時間! – Ben

相關問題