游戲代碼淺讀室/#2 命令模式
一、概述
本系列專欄為筆者學(xué)習(xí)體會(huì)隨筆 沒(méi)有絕對(duì)專業(yè)性,主要內(nèi)容為對(duì)游戲設(shè)計(jì)模式及其他內(nèi)容的理解和應(yīng)用實(shí)例。
注:設(shè)計(jì)模式只是一種簡(jiǎn)單的設(shè)計(jì)思路,我們應(yīng)該活用思路而不是按圖索驥,適當(dāng)修改能更好地應(yīng)用于自己的游戲中。
在GoF(Gang of Four,四人組)的定義下,設(shè)計(jì)模式一共有23種常見(jiàn)的模式,這些設(shè)計(jì)模式分為三大類:創(chuàng)建型模式(Creational Pattern)、結(jié)構(gòu)型模式(Structural Pattern)和行為型模式(Behavioral Pattern)。我們今天的主角就是行為型模式中的?命令模式(Command Pattern)。
二、初識(shí)命令模式
命令模式可以說(shuō)是我在游戲設(shè)計(jì)中最喜歡的模式了,合理地使用命令模式在你的游戲項(xiàng)目中,可以讓你的代碼更加的優(yōu)雅,系統(tǒng)更具有拓展性,例如 你可以使用命令模式去設(shè)計(jì)你的角色的技能,這樣子你在后續(xù)想要添加更多技能的時(shí)候都可以隨意添加。
“ 命令就是一個(gè)對(duì)象化(實(shí)例化)的方法調(diào)用?!?/strong>
簡(jiǎn)單來(lái)說(shuō),命令模式就是將一個(gè)方法包裝成了一個(gè)對(duì)象,也就是“對(duì)象化的方法調(diào)用”。在一款RPG游戲中,我們的玩家可以在戰(zhàn)斗中對(duì)自己的角色進(jìn)行操作,這些操作包括 移動(dòng)、攻擊、技能、防御、道具、逃跑等等,而這些角色動(dòng)作就是一系列的指令對(duì)象,當(dāng)玩家指揮一名角色進(jìn)行攻擊的時(shí)候 就是在為這名角色發(fā)布指令,這名角色將會(huì)接收指令并執(zhí)行 對(duì)敵人進(jìn)行進(jìn)攻。

因此在命令模式中,一般會(huì)有四種類,分別為:
1.Command (指令類):定義一個(gè)基類來(lái)代表一個(gè)可觸發(fā)的游戲命令,一般會(huì)將其定義為一個(gè)抽象類或者接口(ICommand)。
2.ConcreteCommand(具體指令類):對(duì)Command類進(jìn)行具體的實(shí)現(xiàn),主要內(nèi)容是定義該指令的具體內(nèi)容。
3.Invoker (指令調(diào)用者類):負(fù)責(zé)觸發(fā)調(diào)用命令,通知對(duì)象進(jìn)行命令執(zhí)行。
4.Receiver (指令接收類者):負(fù)責(zé)接收命令并調(diào)用命令,執(zhí)行命令內(nèi)容。

三、動(dòng)動(dòng)手
在你了解過(guò)命令模式的邏輯后,現(xiàn)在就可以動(dòng)動(dòng)手為你的角色編寫指令了。
首先來(lái)編寫Command基類,這里筆者的建議是將其設(shè)計(jì)為一個(gè)Interface而不是抽象類,這樣子的設(shè)計(jì)能夠讓指令實(shí)現(xiàn)更具拓展性,通過(guò)實(shí)現(xiàn)接口而不是繼承結(jié)構(gòu) 讓具體指令將能實(shí)現(xiàn)更多的功能,同時(shí)避免了復(fù)雜或較深的繼承結(jié)構(gòu),也就是 組合優(yōu)于繼承(Prefer Composition Over Inheritance)的思想。
于是,我們就可以實(shí)現(xiàn)一個(gè)具體的攻擊指令,可以看到這里因?yàn)?ICommand 的接口特性,我們可以將具體指令包裝成一個(gè)SO 并實(shí)現(xiàn)指令內(nèi)容,在實(shí)現(xiàn)指令的時(shí)候 我們的推薦做法是將接收者對(duì)象作為參數(shù)傳入指令當(dāng)中,并在執(zhí)行方法中 對(duì)接收者對(duì)象進(jìn)行操作,這樣以便將角色和命令解耦,我們的命令內(nèi)容將會(huì)是?“xxx將進(jìn)行進(jìn)攻” 而不是 “只負(fù)責(zé)進(jìn)攻”,當(dāng)然這里只是演示 不一定是最佳做法:
讓我們?cè)賹懸粋€(gè)防御指令:
我們還可以考慮將攻擊和防御種種能力再抽象出來(lái)成一個(gè)Interface,這樣子只有具備?IAttack?或?IDefence?能力的?Receiver?才能使用這些指令,這里就不繼續(xù)拓展了。
接著,我們就需要一個(gè)調(diào)用者(Invoker)來(lái)發(fā)布指令,一個(gè)接收者(receiver)來(lái)接收并執(zhí)行指令:
到此為止,一個(gè)較為完整的簡(jiǎn)單命令模式就寫好了,思路也是比較清晰的。
四、更強(qiáng)大的
你以為命令模式的功能只有現(xiàn)在這一種嗎?那你就小瞧了強(qiáng)大的命令模式了。我們可以依據(jù)命令模式的特性 來(lái)實(shí)現(xiàn)取消命令 回溯的功能,而這只需要我們?yōu)槊钕到y(tǒng)加上一點(diǎn)記憶的功能。
總之命令模式是一個(gè)相當(dāng)有趣且好用的設(shè)計(jì)模式,我們可以使用這個(gè)模式豐富自己系統(tǒng)的拓展性,推薦大家使用并且研究出適合自己游戲的命令系統(tǒng)。
還有一種有關(guān)于命令模式的思想,大概是將各種命令作為能力賦予給角色,詳情可以看這個(gè)視頻:
