2016-09-16 107 views
1

我正在使用Intellij來編程Java。Java遊戲在運行約2分鐘後不斷崩潰(Intellij)

我目前正在嘗試製作一個自頂向下的基於平鋪的射手。我的問題是,大約2分鐘後,我的遊戲崩潰,彈出窗口顯示「Java(TM)Platform SE Binary已停止工作,我記錄了它花費3次的時間:1m57s,1m59s, 1m58s。

現在遊戲處於非常簡單的狀態,我不知道什麼可能導致崩潰。所有相關的代碼只有兩個類:GameFrame.java(擴展JFrame)和GamePanel.java (其擴展JPanel)

GameFrame.java:

package net.magnusfrater.tds.game; 

    import javax.swing.*; 

    public class GameFrame extends JFrame { 

     public static final int width = 1000; 
     public static final int height = width/16 * 10; 

     private GamePanel gp; 

     public GameFrame() { 
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      setSize(width,height); 
      setResizable(false); 
      setLocationRelativeTo(null); 

      setTitle("Time Based Fast Paced Top Down Shooter Demo"); 

      gp = new GamePanel(); 
      add(gp); 

      setVisible(true); 
     } 

     public static void main (String[] args) { 
      GameFrame gf = new GameFrame(); 
     } 
    } 

GamePanel.java

package net.magnusfrater.tds.game; 

    import net.magnusfrater.tds.input.Keyboard; 

    import javax.swing.*; 
    import java.awt.*; 

    public class GamePanel extends JPanel implements Runnable { 

     //panel 
     private Thread thread; 
     private static boolean running; 
     private boolean fpsLock; 

     //input 
     private Keyboard kb; 

     //game 
     private Game game; 

     public GamePanel() { 
      //panel 
      thread = new Thread(this, "Time Based Fast Paced Top Down Shooter Demo"); 
      running = true; 
      fpsLock = true; 

      //input 
      //kb = new Keyboard(); 
      //addKeyListener(kb); 

      //game 
      //game = new Game(1); 

      thread.start(); 
     } 

     public void run() { 
      long iTimeNS = System.nanoTime(); 
      int tickRate = 60; 
      long ns = 1000000000/tickRate; 

      int ups = 0; 
      int fps = 0; 

      long iTimeS = System.nanoTime(); 
      long s = 1000000000; 

      while (running) { 

       long fTimeNS = System.nanoTime(); 
       if (fTimeNS - iTimeNS >= ns){ 
        iTimeNS = System.nanoTime(); 

        tick(); 
        ups++; 

        if (fpsLock){ 
         repaint(); 
         fps++; 
        } 
       } 

       if (!fpsLock){ 
        repaint(); 
        fps++; 
       } 

       long fTimeS = System.nanoTime(); 
       if (fTimeS - iTimeS >= s){ 
        iTimeS = System.nanoTime(); 

        System.out.println("ups: " + ups + "\tfps: " + fps); 

        ups = 0; 
        fps = 0; 
       } 

      } 

      System.exit(0); 
     } 

     public void tick() { 
      if (kb != null) 
       kb.tick(); 

      if (game != null) 
       game.tick(); 
     } 

     @Override 
     public void update (Graphics g) { 
      paint(g); 
     } 

     @Override 
     public void paint (Graphics g) { 

      g.setColor(Color.WHITE); 
      g.fillRect(0,0,GameFrame.width, GameFrame.height); 

      //if (game != null) 
       //game.paint(g); 
     } 

     public static void quitGame() { 
      running = false; 
     } 
    } 

我原本以爲,這個問題是因爲,我是裝的spritesheets圖像或者也許我是加載文本文件關卡設計的方式方法,但返工這兩項後,問題仍存在。

這讓我好奇,有點厭倦,所以我試着找出更多關於崩潰的解釋。首先,我讀從彈出以上,但它並沒有說什麼有用的:(見下文)

其次,我看着通過的IntelliJ給出的退出代碼:(見下文)

我擡頭什麼退出碼255但沒有任何有用的東西。我能找到的最好的解釋是,退出代碼255意味着真正的退出代碼超出範圍:(見下文)

我在這個時候沒有想法,所以我開始簡單地用Google搜索所有我能想到的。 「Java(TM)Platform SE Binary停止工作」的問題是幾乎所有建議的鏈接都是關於Minecraft的問題。將我的搜索限制爲Stack Overflow讓我獲得了一些結果,但沒有任何結論。我發現的一些修補程序是我已經嘗試過的東西(比如沒有正確處理輸入流,沒有正確處理緩衝讀取器,不處理元素等)。我發現這些鏈接,但他們都不是真正與我的問題:

  1. (見下文)

  2. (見下文)

  3. (見下文)

  4. (見下)

  5. (見下)

  6. (見下文)

最後修復我想是重新安裝Java SE開發工具包8u101和Java SE開發工具包8u102。然後我重新啓動了Intellij。然後我重新啓動了我的電腦。

沒有工作。

在這一點上,我認爲我只是愚蠢的。我忽略了一些我可以分辨的東西。我錯過了什麼?因爲如果我運行我的遊戲時幾乎沒有任何內容,fps沒有鎖定到60,我每秒得到的幀數非常荒謬,我不認爲這是一個可能相關的問題。 fps高達700萬是可能的我想我不知道我有沒有編程錯誤以及這是我的ups/fps輸出的相關圖片:[見下文])

(看到這裏)因此堆棧溢出不允許成員的分數超過2個鏈接,並且絕對不允許發佈圖像。因此,這裏是一個谷歌文檔的鏈接了所有我上面提到的鏈接和圖片的: https://docs.google.com/document/d/1XrBuVio19GmkFz0EfRzXVp5AJmM5zPfVO6vK3oS3Eaw/edit?usp=sharing

+0

您可能想要在該循環中進行睡眠,否則只會連續調用System.nanoTime()來超載CPU。 –

+0

我幾乎總是在fps鎖定在60的時候運行它(尤其是因爲這個問題)。快速的問題,但我很難通過運行傷害我的CPU嗎? –

+0

我懷疑你是否在傷害你的CPU,但你幾乎肯定會讓你的JVM崩潰。每幀運行循環的頻率是否超過一次?如果不是的話,可以考慮在那裏睡大約1/60秒。 –

回答

1

嘗試和你的-Xmx設置爲像2G,看看它是否運行更長的時間。如果是這樣,某事正在分配內存,也許你有其他的設置集退出,而不是由於某種原因收集垃圾。

此外,請嘗試更改您的代碼以使用Guava's RateLimiter來限制事物。

… 
// class level 
final RateLimiter frameLimiter = RateLimiter.create(60.0); 
final RateLimiter outputLimiter = RateLimiter.create(1.0); 
… 
// in run method 
while (running) { 
    frameLimiter.acquire(); 
    repaint(); 
    fps++; 
    if (outputLimiter.tryAcquire()){ 
    System.out.println("fps: " + fps); 
    fps = 0; 
    } 
} 

我已經刪除upstick()。你應該在重新粉刷後做你的工作,我認爲你不想爲下一幀做更多的工作,最快的時間應該是你的最大速度。稍後,您需要添加邏輯來處理幀跳過時跳過工作。我可以更有意義地在repaint內增加fps。 如果同步fps的增量和重置,則可以將輸出置於其自己的線程中,並且僅限acquire限制器。