2014-08-30 25 views
1

我正在製作迷宮遊戲。迷宮每隔一段時間就會改變形狀。 此時,在迷宮重新創建之前,tilearray變空。 我在不同的時間間隔後收到NPE錯誤,並在一段時間後停止遊戲。 可能因爲某些方法在實際重新創建之前嘗試訪問。 我試圖把if(...!= null)放在某些地方,甚至試圖同步一些部分(我並不十分熟悉)。AWT-EventQueue-1無效例外指針

編輯:感謝您爲Arvind指出問題。我設法解決這個問題,但我仍然會提供一些更多的幫助,因爲它不是我認爲最好也是最整潔的解決方案。 在某些情況下,tile t等於null。我只是檢查它並繼續; 進入for循環以避免錯誤。

非常感謝您提前給予任何幫助和建議!

因爲這個錯誤的遊戲仍然運行:

Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException 
at shiftingmaze.Game.paintTiles(Game.java:161) 
at shiftingmaze.Game.paint(Game.java:115) 
at shiftingmaze.Game.update(Game.java:107) 
at sun.awt.RepaintArea.updateComponent(Unknown Source) 
at sun.awt.RepaintArea.paint(Unknown Source) 
at sun.awt.windows.WComponentPeer.handleEvent(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$400(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) 

,過了一會兒就與此錯誤凍結:

Exception in thread "Thread-4" java.lang.NullPointerException 
at shiftingmaze.Game.updateTiles(Game.java:153) 
at shiftingmaze.Game.run(Game.java:86) 
at java.lang.Thread.run(Unknown Source) 

下面是代碼的某些部分:

@Override 
public void start() { 

    hero = new Hero(); 

    Timer t = new Timer(); 

    t.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      tilearray.clear(); 
      shiftMaze(); 
     } 
    }, 0, 1000); 

    Thread thread = new Thread(this); 
    thread.start(); 
} 

@Override 
public void stop() { 

} 

@Override 
public void destroy() { 

} 

@Override 
public void run() { 

    while (true) { 
     hero.update(); 
     updateTiles(); 
     repaint(); 
     try { 
      Thread.sleep(17); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

@Override 
public void update(Graphics g) { 

    if (image == null) { 
     image = createImage(this.getWidth(), this.getHeight()); 
     second = image.getGraphics(); 
    } 

    second.setColor(getBackground()); 
    second.fillRect(0, 0, getWidth(), getHeight()); 
    second.setColor(getForeground()); 
    paint(second); 
    g.drawImage(image, 0, 0, this); 
} 

@Override 
public void paint(Graphics g) { 

    g.drawImage(background, 0, 0, this); 
    paintTiles(g); 
    // g.drawRect((int)Hero.rect.getX(), (int)Hero.rect.getY(), 
    // (int)Hero.rect.getWidth(), (int)Hero.rect.getHeight()); 
    // g.drawRect((int)Hero.bigRect.getX(), (int)Hero.bigRect.getY(), 
    // (int)Hero.bigRect.getWidth(), (int)Hero.bigRect.getHeight()); 
    g.drawImage(character, hero.getHeroX(), hero.getHeroY(), this); 
} 

public void shiftMaze() { 

    final int MAZEROW = 24; 
    final int MAZECOL = 40; 

    for (int i = 0; i < MAZEROW * MAZECOL/2; i++) { 
     int n = rand.nextInt(MAZECOL - 2) + 1; 
     int m = rand.nextInt(MAZEROW - 2) + 1; 
     if (!(n == 1 && m == 1) && !(n == MAZECOL - 2 && m == MAZEROW - 2)) { 
      Tile t = new Tile(n, m); 
      tilearray.add(t); 
     } 
    } 

    for (int i = 0; i < MAZECOL; i++) { 
     for (int j = 0; j < MAZEROW; j++) { 
      if (i == 0 || i == MAZECOL - 1 || j == 0 || j == MAZEROW - 1) 
       if (!(i == 1 && j == 0) 
         && !(i == MAZECOL - 2 && j == MAZEROW - 1)) { 
        Tile t = new Tile(i, j); 
        tilearray.add(t); 
       } 
     } 
    } 
} 

public void updateTiles() { 

    for (int i = 0; i < tilearray.size(); i++) { 
     Tile t = (Tile) tilearray.get(i); 
     t.update(); 
    } 
} 

public void paintTiles(Graphics g) { 

    for (int i = 0; i < tilearray.size(); i++) { 
     Tile t = (Tile) tilearray.get(i); 
     g.drawImage(t.getTileImage(), t.getTileX(), t.getTileY(), this); 
    } 
} 

這是來自瓷磚類:

public Tile(int x, int y) { 

    tileX = x * 20; 
    tileY = y * 20; 
    tileImage = Game.getWall(); 

    r = new Rectangle(); 
} 

public void update() { 

    r.setBounds(tileX, tileY, 20, 20); 
    if (r.intersects(Hero.bigRect)) 
     checkCollision(Hero.rect); 
} 
+0

請檢查瓷磚是空的位置:'馬賽克T =(瓦)tilearray.get(I);'方法updateTiles()內 – Arvind 2014-08-30 06:48:18

+0

凡'tilearray'聲明和初始化?也許這是空的。嘗試調試您的代碼。 – Jens 2014-08-30 06:51:16

+0

@Arvind:我查了一下,是的,它爲空時,它拋出AWT-EventQueue的-1 – Kokufuu 2014-08-30 08:00:51

回答

0

問題是這裏:

public void updateTiles() { 
    for (int i = 0; i < tilearray.size(); i++) { 
     Tile t = (Tile) tilearray.get(i);//<-- tile is null in some cases 
     t.update(); 
    } 
} 

有很多選擇,以避免這樣的:

選項1:子類ArrayList和重寫方法Add()和的addAll()與空檢查。

選項2:填充tilearray後,使用該行

tilearray.removeAll(Collections.singleton(null)); 

編輯

如果您正在尋找第二個選項,那麼你應該試試這個刪除空值:

public void shiftMaze() { 
    //<-- to do here 
    tilearray.removeAll(Collections.singleton(null));//<-- at the end 
} 
+0

我應該在哪裏插入它?我試過但仍然收到錯誤... shiftMaze()方法後?這是在清除它之後它被填充的地方。 – Kokufuu 2014-08-31 06:51:07

+0

@Kokufuu,請查看我的更新 – Arvind 2014-09-01 04:35:52

+0

謝謝!我仍然收到錯誤,但至少我知道在哪裏搜索它。在填充數組後,我檢查了使用removeAll刪除的元素的數量,並且它始終爲0.因此,問題在此之後。在我的解決方案下面,遊戲仍然可以運行,在凍結數百次之前調用shiftMaze。 – Kokufuu 2014-09-01 06:30:03

0

謝謝你的幫助,我嘗試了那個,但它仍然有一些空值。 與此同時,我做了以下來擺脫錯誤。它幾乎一直工作,但很少我仍然得到NPE或指數超出界限的錯誤... 我加快了遊戲到100毫秒的娛樂,以獲得長期的錯誤檢查。

for (int i = 0; i < tilearray.size(); i++) { 
    Tile t = (Tile) tilearray.get(i); 
    if (t == null && i < tilearray.size() - 1) { 
     System.out.println("t = null @ updateTiles(), moving to next element"); 
     continue; 
    } 
    if (t == null && i >= tilearray.size()) { 
     System.out.println("t = null @ updateTiles(), no elements left"); 
     break; 
    } 
    t.update();