MVP Pattern: Part 4 黑白棋範例 之二

我們在Part 3已經實作了棋盤最基礎的2個功能,下子與翻子。
我們在這一篇要做的是加入黑白棋的遊戲規則。

Part 3用標準的MVP模式製作了基礎棋盤架構。

我們不直接在原有的架構內進行修改,而是從外部進行操作與事件監聽。

起始盤面設置

我們讓Game在初始化時就呼叫BoardModel的PlaceDisk函式進行擺盤。
這部分應該沒有什麼問題。

管控使用者的輸入

由於動畫撥放、訊息顯示,或是其它就是不應該讓玩家在特定時間進行操作的原因,管控使用者的輸入是很常見且重要的需求。

我們先來看看目前的控制流程

使用者透過BoardView輸入後,由BoardModel處理完直接同步回去。但BoardModel並沒有能夠判斷遊戲邏輯的能力,因此我們需要將使用者的操作轉換成”請求事件”傳遞至Game,由代表遊戲邏輯的Game類別來處理。

下圖才是我們想要的控制流程

將使用者輸入轉送到遊戲邏輯

因此現在要來改寫BoardModel與Game,程式碼如下。

完整的遊戲邏輯

以上的程式碼改動,只是將原本BoardModel的邏輯轉移到Game之內,順便做個顏色切換的邏輯。實際上根據黑白棋的規則,不應該直接切換顏色,因為會出現同一方連續下子的情況。

每次收到下子請求,我們需要處理下列事項:
1. 此步是否合法
2. 哪些棋子需要被翻面
3. 下一步由哪一方來下
4. 遊戲是否結束

遊戲邏輯本身其實算簡單,而且在目前的架構下只需要修改Game即可達到目的。由於跟架構沒有關係,因此就直接列出完整程式碼。(跟上面的版本做比較,會發現根本只改了ValidPlacement的邏輯內容而已)

到目前為止,我們已經可以做出下圖的狀況了。

看起來已經像個可玩版本了,但好像缺了什麼?嗯,對了,就是遊戲介面。

第二個MVP架構

需要與遊戲邏輯相關的介面有2個:
1. 分數
2. 勝敗結果

這2個介面看起來就隸屬於不同物件,基本上我不太想讓Game類別去煩惱如何管控這些介面。這時候應該要有個專門管理這些介面顯示的類別,然後藉由Game發出的事件來判斷如何顯示。

嗯,所以這是另一個MVP架構了。

我們可以看到MVP架構之間,是透過Model來進行連接。
這樣寫有2個明顯的好處。

首先,我們知道實際上所有的邏輯都集中在上圖右上角的Game與BoardModel,實際上即使沒有視覺表現,僅僅只有這2個類別就能夠透過程式碼來執行黑白棋。換句話說,我們可以幾乎無痛的寫測試,而不需要去模擬(mock)視覺介面

第二,邏輯分層,下層是基底的行為,上層是決定如何控制基底的遊戲邏輯。我們都知道遊戲設計在開發過程中會不斷的變化,將變化頻率較高的類別與較低的類別分開,降低了修改的風險。修改的風險指的是修改困難的風險、寫出bug的風險、debug困難的風險,或是破壞原有邏輯的風險。

寫到這邊,遊戲邏輯那一層的MVP怎麼寫應該就不需要解釋了。
完成後加上自動執行,結果如下。

結論

1. 在開發遊戲時,可以透過MVP模式,將程式邏輯與視覺面分離,進而達到方便測試與改動的目的。
2. MVP架構之間可以透過Model來進行連接,進而達到邏輯分層的目的。
3. 程式的進入點其實是Presenter,而不是Model

最後,MVP作為遊戲開發中一個泛用的設計模式,仍然得看情況使用。一樣不要陷入為了使用而使用的狀況。

 

發佈留言