2012-11-21 49 views
0

我一直在研究一個簡單的遊戲引擎。一切進展順利,我的基礎已經完成。我的意思是,遊戲設置了用戶定義的顯示設置,初始化東西,並啓動遊戲循環。除非我在Windowed模式和全屏模式下都有問題,否則一切都很好:屏幕有時在遊戲開始空白

在窗口模式下,有時屏幕會顯示爲空白,直到調整窗口大小或最小化窗口。

在全屏幕中,如果我使用默認顯示分辨率,我只會看到空白屏幕。大多數其他決議似乎很好。

下面是一些與顯示屏幕代碼:

這是當使用壓在顯示設置播放按鈕進行對話框

public void actionPerformed(ActionEvent e) { 
      DisplayMode dm = modes[resolutionBox.getSelectedIndex()]; 
      boolean fs = fullscreenBox.getSelectedItem().equals ("Fullscreen"); 
      boolean vs = vSyncCheckBox.isSelected(); 

      game.initScreen (dm, fs, vs); 
      runGame (game); 

      f.dispose(); 
     } 
    }); 

private final void runGame(EGame g) 
{ 
    Thread t = new Thread (g); 
    t.start(); 
} 

這是EGame類

的run方法
public final void run() { 
    start(); 
    isRunning = true; 
    gameLoop(); 
    endGame(); 
} 

引擎的用戶將在start()方法中調用方法setGameCanvas()。其他的事情可以在開始去()方法,但是對於我的測試遊戲,它只是方法:

protected final void setGameCanvas(EGameCanvas c) 
{ 
    screen.remove (canvas); 
    canvas = c; 
    canvas.addKeyListener (keyboard); 
    screen.add (canvas); 
} 

最後,這裏是gameLoop:

private final void gameLoop() 
{ 
    // Final setup before starting game 
    canvas.setBuffer (2); 
    screen.addKeyListener (keyboard); 
    canvas.addKeyListener (keyboard); 

    int TARGET_FPS = screen.getTargetFps(); 
    final long OPTIMAL_TIME = 1000000000/TARGET_FPS; 

    long lastLoopTime = System.nanoTime(); 

    long now = 0; 
    long lastFpsTime = 0; 
    long updateLength = 0; 
    double delta = 0; 

    int fps = 0; 

    while (isRunning) 
    { 
     now = System.nanoTime(); 
     updateLength = now - lastLoopTime; 
     lastLoopTime = now; 
     delta = updateLength/((double) OPTIMAL_TIME); 

     lastFpsTime += updateLength; 
     fps++; 

     if (lastFpsTime >= 1000000000) 
     { 
      screen.setFps (fps); 
      lastFpsTime = 0; 
      fps = 0; 
     } 

     keyboard.poll(); 
     keyboardEvents(); 

     update (delta); 

     render(); 

     try { 
      Thread.sleep((lastLoopTime-System.nanoTime() + OPTIMAL_TIME)/1000000); 
     } 
     catch (Exception ex) {} 
    } 
} 

現在,請記住,我的問題都不存在,直到我添加了run方法並將其運行在單獨的線程中。我可以保證它是一個線程問題。

但是,我不是專家,所以任何意見,將不勝感激。

回答

0

我認爲問題在於您試圖在事件派發線程之外修改GUI相關組件 - 這是允許修改圖形界面的唯一線程,否則您可能會遇到類似這樣的問題。

要檢查這個嘗試,如果下面的解決了這個問題:

try { 
    if (!SwingUtilities.isEventDispatchThread()) { 
     SwingUtilities.invokeAndWait(new Runnable() { 
      @Override 
      public void run() { 
       // Do rendering and other stuff here... 
      } 
     }); 
    } 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} catch (InvocationTargetException e) { 
    e.printStackTrace(); 
} 

是否有幫助,我建議你服用的Concurrency in Swing tutorial看看。

+0

感謝您的迴應!只是關於你的代碼的幾個問題:你究竟在哪裏要求我說出來?另外,我應該保持我的另一個線程調用run()方法嗎? – Troncoso

+0

不幸的是,當你不在* Event Dispatch Thread *中並且想操縱一些Swing組件時,你將需要這個地方。其實,我剛剛看到你使用的是EGameCanvas,所以如果這是問題,我可能會錯。 – rlegendi

+0

是的。 EGameCanvas擴展了Canvas類,這就是我完成繪圖/渲染的地方。就像我在OP中所說的那樣,每次我運行它時,屏幕都會出現並完美畫出。也就是說,直到我把run()方法放在一個單獨的線程中。 – Troncoso