在遊戲開發中使用命令模式的一個例子html
在每一個遊戲中都有一塊代碼讀取用戶的輸入——按鈕按下,鍵盤敲擊,鼠標點擊,諸如此類。 這塊代碼會獲取用戶的輸入,而後將其變爲遊戲中有意義的行爲。編輯器
一種簡單死了的實現會是這樣:函數
void InputHandler::handleInput(){工具 if (isPressed(BUTTON_X)) jump();編碼 else if (isPressed(BUTTON_Y)) fireGun();設計 else if (isPressed(BUTTON_A)) swapWeapon();3d else if (isPressed(BUTTON_B)) lurchIneffectively();htm }對象 |
這個函數一般在遊戲循環中每幀調用一次,我確信你能夠理解它作了什麼。這代碼在咱們想將用戶的輸入和程序行爲硬編碼在一塊兒時能夠正常工做,可是許多遊戲容許玩家設定按鍵的功能。爲了支持這點,須要將這些對jump()和fireGun()的直接調用轉化爲能夠更換的東西。 「更換」聽起來有點像聲明變量,所以咱們須要表示遊戲行爲的對象。進入:命令模式。blog
先實現命令:
class JumpCommand: ICommand { public void execute() { //這此方法可能來自另外的類,這裏只是表達一下調用的意思。 jump(); } }
class FireCommand : ICommand { public void execute() { fireGun(); } } ///下面省略幾千行 |
構造一個控制器,在輸入控制器,爲每一個鍵存儲一個指向命令的引用,至關於前面說的Invoker:
class InputHandler { private ICommand commandX; private ICommand commandY; private ICommand commandA; private ICommand commandB;
//處理輸入的操做 public void handleInput() { if (isPressed(BUTTON_X)) commandX.execute(); else if (isPressed(BUTTON_Y)) commandY.execute(); else if (isPressed(BUTTON_A)) commandA.execute(); else if (isPressed(BUTTON_B)) commandB.execute(); }
//這是另一個使用方式,與上面的是同樣的,這裏把command傳出去 ICommand InputHandler::handleInput() { if (isPressed(BUTTON_X)) return commandX; if (isPressed(BUTTON_Y)) return commandY; if (isPressed(BUTTON_A)) return commandA; if (isPressed(BUTTON_B)) return commandB;
// Nothing pressed, so do nothing. return NULL; } }
|
這是命令模式的簡短使用。若是你可以看出它的好處,能夠接着往下看了。
在實踐中,這並非經常使用的功能,可是這常常會有相似的用例跳出來。到目前爲止,咱們只考慮了玩家控制的角色,可是遊戲中的其餘角色呢?它們被遊戲AI控制。咱們能夠在AI和角色之間使用相同的命令模式;AI代碼只是簡單的放出Command對象。在選擇命令的AI和展示命令的遊戲角色間解耦給了咱們很大的靈活度。 咱們能夠對不一樣的角色使用不一樣的AI,或者爲了避免同的行爲而混合AI。 想要一個更加有攻擊性的同伴?插入一個更加有攻擊性的AI爲其生成命令。 事實上,咱們甚至能夠爲玩家角色加上AI, 這在原型階段,遊戲須要自動駕駛員是頗有用的。把控制角色的命令變爲第一公民對象,去除直接方法調用中嚴厲的束縛。 取而代之的是,將其視爲命令隊列,或者是命令流:
一些代碼(輸入控制器或者AI)產生一系列指令而後將其放入流中。 另外一些指令(調度器或者角色自身)消耗指令並調用他們。 經過在中間加入了一個隊列,咱們解耦了消費者和生產者。
撤銷和重作
這個例子是這種模式最廣爲人知的使用狀況。若是一個命令對象能夠作一件事,那麼它亦能夠撤銷這件事。在一些策略遊戲中使用撤銷,這樣你就能夠回滾那些你不喜歡的操做。在人們創造遊戲時,這是必不可少的工具。不能撤銷肥手指致使的錯誤的編輯器,確定會讓遊戲設計者恨你。
沒有了命令模式,實現撤銷很是困難,有了它,就是小菜一碟。假設咱們在製做單人回合制遊戲,想讓玩家能撤銷移動,這樣他們就能夠集中注意力在策略上而不是猜想上。咱們已經使用了命令來抽象輸入控制,因此每一個玩家的舉動都已經被封裝其中。舉個例子,移動一個單位的代碼可能以下: