2014-05-19 187 views
1

我目前正在爲android開發一個多人遊戲卡遊戲,並將libgdx作爲遊戲引擎。我的問題是更多基因壽。模型視圖控制器和回調

我不確定在這個架構中處理回調的最佳做法是什麼。我的控制器是一個很大的狀態機,它通過gameengine的render()方法從beeing中調用一遍又一遍地檢查輸入。

我有兩個主要回調,gui的userinput和android google play服務部分的網絡回調。

目前這些回調方法設置成員變量,它通過控制器/狀態機的getter方法進行檢查,例如我一遍又一遍地從控制器調用它,檢查它是否爲!= null,如果它是。

@Override 
public Boolean allPlayersConnected() { 
    Boolean allConnected = null; 
    if (startGame != null) { 
     allConnected = startGame; 
     startGame = null; 
    } 
    return allConnected; 

} 

startGame「flag」beeing由來自谷歌播放服務api的回調設置。

我不知道這是不是很好的做法,看起來不像。

我可以從設置控制器成員變量的谷歌播放服務回調中調用控制器方法,並在每個渲染循環中檢查這一點,但那只是移動變量。

我也可以設計控制器作爲這些事件的觀察者,但是如果發生事件,我將在控制器內部的更新方法中做什麼。我不認爲我想在這些變化統計,即使我可以訪問currrent狀態。我用這個遍佈各地的狀態代碼,一些在巨大的更新方法的不同部分,一些在實際的狀態機代碼中。在update方法中設置一個成員變量與上面的想法非常相似。

另一件事是直接從回調方法改變控制器狀態。這將是更少的代碼,更少的變量和更快的速度,但我想我會摧毀MVP的概念,因爲我從控制器中拿走了控制器,並讓GUI改變了控制器的狀態。

對此的任何輸入?

編輯:

我越去想它,我越覺得觀察者和命令模式的組合是要走的路。

所以我確實可以削減當前狀態機的很大一部分並將它打包到觀察者的update()方法中。我可以用可用的信息創建命令對象,而不是通過一個大的命令枚舉來發送命令,並將它們傳遞給觀察者(控制器),在那裏我檢查命令是否可行,然後用執行所需的信息來調用執行,例如模型界面。

回答

2

首先,我認爲你的命令是枚舉還是命令對象與這裏的主要問題無關 - 這就是如何將用戶和網絡輸入連接到狀態管理。

我見過的最常見的遊戲體系結構是一個更新循環,用於檢查輸入,迭代遊戲模擬,然後渲染幀。在MVC世界中,這種結構只是同步這些步驟;你仍然有一個封裝的視圖和數據模型,控制器(遊戲循環)充當這兩個世界之間的橋樑。

無論是來自本地用戶還是來自網絡的輸入,通常被視爲修改遊戲狀態的請求。也就是說,控制器(作爲其循環的第一部分)讀入待處理的輸入消息並對其進行處理,並在狀態發生變化時進行修改。這樣,改變狀態的代碼就在一個地方:那個控制器。你是對的,在整個應用程序中傳播狀態修改代碼是一種不好的做法;基本上,這不是MVC。

換句話說,所有的回調應該將輸入轉換爲命令並將它們粘貼到隊列中。您不想將控制器(負責修改狀態的控制器)與這些輸入回調進行同步。你不知道什麼時候輸入會發生在遊戲循環中,所以最好將它們分開。將輸入處理與遊戲模擬序列化應該也會使你的邏輯更簡單。

您在如何將回調連接到控制器方面有一些選擇;一個共享隊列(一邊寫入,另一邊讀出)是一個強大的模式,並且易於使線程安全。

+0

問題的答案,現在一切似乎都更清楚了。我認爲最重要的部分是同步部分。我不希望回調(觀察員更新方法)立即執行該命令,因爲我不知道當前進程在哪裏工作以及何時輸入發生。也許還有一個問題:除了命令隊列之外,我填入觀察者更新方法,並且控制器在其時間使用命令時,我還有什麼其他選項可以保持一切同步,並且控制器在控制中? – Kedu

+0

這實際上取決於您擁有的命令,但是命令隊列用於大量地點,包括Windows。您可以搜索「事件驅動的編程」獲取更多信息。運行有限輸入系統的系統(如遊戲手柄或工業等價物)通常只會將鍵盤的狀態存儲在一個對象中,並讓控制器決定如何解釋它。 – AndrewS