2012-01-16 86 views
1

我正在將一款遊戲從Ruby移植到C++。有一個主要的渲染循環來更新和繪製內容。現在讓我們說,在遊戲中,你想要選擇一個項目另一個屏幕。在原始代碼中完成的方式是做Item item = getItemFromMenu();getItemFromMenu是一個函數,它將打開菜單,並有自己的更新/渲染循環,這意味着在整個過程中玩家有另一個屏幕打開,你在嵌套渲染循環。我覺得這是一個不好的方法,但我不知道爲什麼。另一方面,它非常方便,因爲我可以用一個函數調用打開菜單,所以代碼是本地化的。 任何想法,如果這是一個糟糕的設計或沒有? 我毫不猶豫地張貼在gamedev,但由於這是主要是一個設計問題我張貼在這裏嵌套渲染循環是不好的做法嗎?

編輯:一些僞代碼給你一個想法:

通常的循環中的主要部分代碼:

while(open) { 
    UpdateGame(); 
    DrawGame(); 
} 
現在

內UpdateGame()我會做這樣的事情:

if(keyPressed == "I") { 
    Item& item = getItemFromInventory(); 
} 

而且getItemFromInventory()

while(true) { 
    UpdateInventory(); 

    if(item_selected) return item; 
    DrawInventory(); 
} 
+1

我一直掙扎在VB.NET應用了類似的事實是,在渲染循環,以保持GUI從凍結和崩潰和死亡,但也避免了污穢樣-的「進度窗口」執行'DoEvents'引入線程。這意味着我的進度窗口中只有一個會一次更新。我並不介意,而且它可以避免線程。但它感覺噁心。我離開它現在... – 2012-01-16 22:23:49

+0

一個壞事,我可以用這個看到的是在你有這樣的遊戲循環,取決於它是如何做的所有的地方可能重複的代碼。 – Xeo 2012-01-16 23:04:14

+0

你可以顯示你想要的僞代碼嗎? – 2012-01-16 23:08:32

回答

2

來處理這樣的事情將是取代DrawInventory()調用的東西,如InvalidateInventory(),這將標誌着庫存過時的當前的圖形狀態,並要求其到下一幀渲染時重繪的一個好辦法(當主循環到達DrawGame()時,會很快發生)。

通過這種方式,您可以繼續運行主循環,但屏幕上唯一被查看重繪的部分是已被無效的部分,並且在正常的遊戲過程中,您可以使您的(2/3) D環境作爲處理的正常部分,但是在庫存內部,您始終只能將庫存資產標記爲需要重新繪製,這可以最大限度地降低開銷。

你的內循環的另一部分,UpdateInventory(),可以是UpdateGame()的一部分,如果你使用一個標誌來指示當前的遊戲狀態,這樣的:

UpdateGame() 
{ 
    switch(gameState) 
    { 
     case INVENTORY: 
      UpdateInventory(); 
      break; 

     case MAIN: 
     default: 
      UpdateMain(); 
      break; 
    } 
} 

如果你真的願意,你也可以應用此圖紙:

DrawGame() 
{ 
    switch(gameState) 
    { 
     case INVENTORY: 
      DrawInventory(); 
      break; 

     case MAIN: 
     default: 
      DrawMain(); 
      break; 
    } 
} 

但我認爲圖形應該被封裝,你應該告訴它的屏幕的哪一部分,而不是該遊戲的單獨的區域,需要繪製。

0

你用你的嵌套渲染循環創建的功能是一個狀態機(因爲大多數遊戲渲染循環往往是)。嵌套循環的問題在於,你需要多次在嵌套循環中完成與外循環相同的操作(處理輸入,處理IO,更新調試信息等)。

我發現最好有一個渲染循環,並使用有限狀態機(FSM)來表示您的實際狀態。你的國家可能是這樣的:

  • 主菜單狀態
  • 選項菜單狀態
  • 庫存狀態
  • 世界視圖狀態

您掛鉤狀態之間的轉換在它們之間移動。玩家點擊一個按鈕可能觸發可以播放動畫的轉換,否則轉到新的狀態。隨着FSM你的循環可能看起來像:

while (!LeaveGame()) { 
    input = GetInput(); 
    timeInfo = GetTimeInfo(); 

    StateMachine.UpdateCurrentState(input, timeInfo); 
    StateMachine.Draw(); 
} 

一個完整的FSM可以是一個小遊戲,有點重量級的,所以你可以使用遊戲狀態的堆棧嘗試簡化狀態機。每當用戶執行一個操作以轉換到新狀態時,您都會將狀態推入堆棧。同樣,當他們離開一個狀態時,你會彈出它。只有堆疊的頂部通常會接收輸入,並且堆疊上的其他物品可能/不可能繪製(取決於您的偏好)。這是一種常見的方法,取決於你與誰交談,有一些好處和壞處。

所有最簡單的選擇是僅拋出一個switch語句中挑選要使用的渲染功能(類似於darvids0n的答案)。如果你正在編寫一款街機克隆版或者一款小型益智遊戲,那就太好了。