2010-02-12 59 views
4

我正在製作一款遊戲,並且我終於完成了它的遊戲性方面,但現在是我創建菜單和高分屏幕的時候了。我不完全確定該怎麼做,遊戲將處於不同的狀態(MENU_STATE,GAMEPLAY_STATE,SCORESCREEN_STATE),並且在每種狀態下我想要在屏幕上繪製不同的東西,對我來說做這樣的事情可以嗎?然後?將遊戲邏輯放在繪圖函數中可以嗎?

draw function() 
{ 
    if MENU_STATE 
     draw menu 
    if GAMEPLAY_STATE 
     draw game 
    if SCORESCREEN_STATE 
     draw scores 
} 

我一直在關注抽獎功能沒有嚴格的邏輯和它一直不錯,但我實在想不出用不同的方式來做到這一點。

+0

規則不是「繪圖函數中沒有邏輯」,而是「繪圖函數中沒有遊戲邏輯」。每個功能都會有一些邏輯。只要確保你所做的決定是在程序的正確部分完成的。 – Kylotan 2010-02-14 11:36:37

回答

0

絕對不是不是確定把遊戲邏輯放在繪圖函數中。

但是,如果它在這種特殊情況下讓你的生活更輕鬆,那麼無論如何它都可以。

如果它變得混亂,你可以隨時更改它。

3

您正在調用該例程中的一些繪圖功能,但這並不意味着
您必須命名它繪製

也許這是你的情況更爲合適:

// pseudocode 
on_game_state function(state) 
{ 
    select (state): 
     MENU_STATE: 
     draw menu 
     GAMEPLAY_STATE: 
     draw game 
     SCORESCREEN_STATE: 
     draw scores 
} 
+0

這仍然是繪圖功能中的邏輯,不是嗎? – 2010-02-12 17:19:59

+0

+1表示這不一定是繪圖函數,或者它不一定是。還要注意的是,如果在函數的後面有實際的繪圖,那麼如果你想嚴格保持遊戲邏輯不在任何繪圖函數之外,那麼它可以被踢到一個不同的函數(這實際上是一個繪圖函數)。 – 2010-02-12 17:20:23

+1

@Andrew Aylett:不一定。如果這只是函數中的全部內容,那麼它所做的只是調用其他函數來進行實際繪圖,而不是執行任何繪圖本身。 (編輯:我想我只是假設「繪製菜單」等是分開的函數調用) – 2010-02-12 17:21:07

5

您可以使用單獨的類爲三種狀態,實現一個通用的接口,而非設定恆定的狀態,設定的一個實例類:

interface IState { 
    void draw(); 
} 

class Menu implements IState { 
    void draw() { 
     // Draw menu 
    } 
} 

class Game implements IState { 
    void draw() { 
     // Draw game 
    } 
} 

void draw() { 
    state.draw(); 
} 

這仍是不理想(你真的不希望在您的狀態下畫出的代碼,你想要的東西多一點獨立的),但是抽象是常見的一種,可能是相關的(如果不知道m,很難再提供建議你的建築的礦石)。

+0

+1這正是虛擬函數(或者C函數指針)存在的原因。 – 2010-02-13 07:33:24

+0

@BlueRaja,以及爲什麼在遊戲中使用虛擬函數來做這件事通常是一個壞主意,即我有100,000個對象需要更新和繪製 - 調用一個虛擬函數100,000次,這基本上是一個表查找會很快破壞我的表現 – zebrabox 2010-02-13 11:50:43

1

使用狀態機可以使這個更簡單。每個狀態都有自己的一組更新和繪圖函數,它們在狀態堆棧頂部時被調用。您可以使用Game_Draw(),Menu_Draw(),HighScoreScreen_Draw()等等,而不是使用內部狀態切換的繪圖函數。類似地,您的更新函數可以被分離出來。

static void StateMachine_DrawTopState() 
{ 
    switch(stateMachine_topState) 
    { 
     case STATE_GAMEPLAY: 
     { 
      Gameplay_Draw(); 
     } 
     break; 
     case STATE_MENU: 
     { 
      Menu_Draw(); 
     } 
     break; 
    } 
} 
0

是的,這很好,遊戲程序員被允許彎曲性能提升的規則。遊戲世界的觀點和模型經常是同一件事,以避免視圖和模型分離而產生延遲。

沒有理由不能讓菜單和高分對象成爲遊戲世界的一部分,這已經在很多遊戲中完成了。

1

Andrew Aylett's answer並假設一個面向對象的語言相似,也許你可以這樣做:

Interface IState { 
    void init(); 
    void update(); 
    void draw(); 
} 

class GameplayScene implements IState { 
    void init() { 
     // initialize gameplay 
    } 
    void update() { 
     // update game logic 
    } 
    void draw() { 
     // draw game 
    } 
} 

class MenuScene implements IState { 
    void init() { 
     // initialize menu 
    } 
    void update() { 
     // update menu logic 
    } 
    void draw() { 
     // draw menu 
    } 
} 

class ScoresScene etc... 

class TitleScene etc... 

// Somewhere else, probably in the Game class 
void Main() { 
    // Init game 
    Scene currentScene = new TitleScene; 
    while (Scene != null) { 
     Scene.init(); 
     Scene.update(); 
     Scene.draw(); 
    } 
    // Exit game 
} 

您還需要考慮如何處理場景之間的過渡。你可以讓每個場景類有一個叫nextScene的成員變量,主函數在循環開始時查詢它切換到合適的場景。

如果您沒有使用面向對象的編程語言(如C++,Java,C#,Python等)的奢華。),Colin'sNick D's的答案可能會有所幫助,但我試圖在一個地方使用switch語句(比如說一個大的game_update函數),以允許通過在一個地方進行更改來添加新狀態。或者,您可以在Colin的狀態機設計上構建更通用的東西,並且不需要硬編碼的switch語句。 (雖然說實話我現在想不出一個好辦法)