我們剛剛定義的命令類適用於前面的例子,但是它們有很大的侷限性。問題在於,它們假設了存在著jump()、firegun()等等這樣的隱含地知道如何找到玩家的角色並像操縱傀儡般操縱它的頂層函式。
這種假定的耦合限制了這些命令的用途。jumpcommand可以使其跳躍的東西只有玩家。讓我們來放寬這個限制。我們將我們想要對其發號施令的物件作為乙個引數傳遞進去,而非呼叫一些靠自己去找到被命令的物件的函式:
class command
virtual void execute(gameactor& actor) = 0;
};
這裡,gameactor是我們代表遊戲世界中的乙個角色的「遊戲物件」類。我們把它傳遞進execute()中,以便繼承的命令可以對我們自己選擇的actor呼叫這些方法,就像這樣:
class jumpcommand : public command
};
現在,我們可以用這個類來讓遊戲中的任何角色跳來跳去了。我們現在只缺少連線輸入處理器和取得這個命令(就是前面的輸入處理器——譯者注)並在正確的物件上呼叫它的命令的乙個環節。首先,我們修改handleinput()使得它返回命令:
command* inputhandler::handleinput()
現在還不能立即執行命令,因為還不知道應該傳遞進哪個actor。這裡就是我們利用了「命令是乙個實體化的函式呼叫」這一優勢的地方——我們可以延遲執行呼叫的時機。
然後,我們需要**來取得這個命令,然後在代表著玩家的actor身上執行它。比如像這樣:
command* command = inputhandler.handleinput();
if (command)
假設actor是指向玩家的角色的乙個引用,那麼上述**就會基於使用者的輸入而正確地驅使他,所以我們就回到了上乙個例子中的同樣行為。但是在命令和執行該命令的actor之間增加乙個間接層給了我們乙個整潔的小功能(a neat little ability):我們現在可以通過改變我們對其執行命令的actor而讓玩家控制遊戲中的任何actor。
在實踐中,這不是乙個常見的特性,但是有乙個確實經常出現的相似的使用案例。到目前為止,我們僅僅考慮了玩家驅動的角色,但是遊戲世界中所有那些其他的actor呢?這些是被遊戲的ai所驅動的。我們可以使用同樣的命令模式作為連線ai引擎和這些actor的介面;這些ai**只不過是傳送出(emit)command物件罷了。
在選擇命令的ai和執行這些命令的actor**之間的解耦給了我們很多的靈活性。我們可以為不同的actor使用不同的ai模組。或者,我們可以為不同種類的行為混合、匹配ai。想要乙個更具有攻擊性的對手嗎?那就插入乙個更加具有攻擊性的ai來為其生成命令吧。事實上,我們甚至可以將ai運用於玩家的角色,而這在演示模式(其中遊戲需要靠自動駕駛的方式來執行)等事情中會派上用場。
通過把控制乙個actor的命令變成第一類的物件,我們去掉了直接的方法呼叫這樣的緊密耦合。相反,把它想象為命令的乙個佇列(queue)或者流(stream)吧:
關於佇列化(queueing)能夠為你做什麼的詳細資訊,參看事件佇列(event queue)。
為什麼當初我感覺需要為你們畫乙個「流」的圖呢?為什麼它看起來像是乙個管道呢?
一些**(輸入處理器或者ai)產生命令並將其放入流中。另一些**(傳送者(dispatcher)或者actor本身)消費(consume)命令並呼叫之。通過將這個佇列固定在中間,我們解耦了產生者和消費者,讓它們位於兩端。
如果我們取得這些命令並使其可序列化(serializable),我們可以將它們組成的流傳送到網路上。我們取得使用者的輸入、通過網路將其轉到另外一台機器上、然後對其重演(replay)。這是製作乙個基於網路的多人遊戲的乙個關鍵部分。
遊戲程式設計模式 命令模式
最近深感 設計對於軟體開發過程中的重要性,所以重新拾起了設計模式,以前學的比較鬆散,理解不夠,這一次本著learning,try,teaching的精神,重新認識和學習設計模式。這一次參考robert nystrom 著的 遊戲程式設計模式 一書,與原先的gof所著的24種設計模式不同,但思想是相通...
遊戲程式設計模式 雙緩衝模式
我們先看乙個典型的例子,每個遊戲引擎都要處理的問題 渲染。當引擎渲染出使用者看到的世界時,在同一時間它只渲染一塊 遠處山峰 欺負的丘陵 樹木,這些輪流渲染 假如使用者也逐步的觀察視窗的渲染過程,那麼看到的將是破碎的世界。這是我們不能接受的,場景比如平滑快速的更新,每一幀必須被完整的顯示。如何解決這個...
遊戲程式設計模式 框架 效能 遊戲
恢復內容開始 好的設計意味著當我們做出乙個改動時,就好像整個程式都在期待它一樣。我們可以呼叫少量可選的函式來完美地解決乙個問題,而不會為軟體帶來其他的多餘的 只管寫我們自己的 框架會幫我們收拾一切!關鍵部分 框架意味著變化。衡量乙個設計好壞的方法就是看它應對變化的靈活性。好的改變,是在下乙個人在新增...