RPG游戲開(kāi)發(fā)日志2:生命值與魔法值

本項(xiàng)目同步上傳于github和coding上,國(guó)內(nèi)讀者可以通過(guò)在coding下載項(xiàng)目,注意本套開(kāi)發(fā)日志同步的是Tutorial分支,其他分支內(nèi)容可能與日志內(nèi)容不符。請(qǐng)注意

github地址:https://github.com/Liweimin0512/uRPG

coding地址:https://git.dev.tencent.com/JeremyBrett/uRPG.git

今天我們來(lái)搞定角色的生命值和魔法值,在此之前我們要解釋一個(gè)重要的概念——組件。

基于組件的游戲開(kāi)發(fā)

也許你聽(tīng)過(guò)“組合大于繼承”(沒(méi)聽(tīng)過(guò)就先去聽(tīng)一下),簡(jiǎn)單來(lái)講就是在游戲開(kāi)發(fā)中描述一個(gè)游戲物體有什么比描述它是什么更合理。

那么這里我想把生命值和魔法值做成組件,因?yàn)橛螒蛑谐送婕医巧螒蛑械腘PC、怪物甚至是一些“可交互物”都是有生命值的概念的。

起先,我想將生命值、魔法值作為兩個(gè)組件。但更深入的分析,我將這兩個(gè)數(shù)值抽象成一種叫做“狀態(tài)”的組件,這個(gè)組件本身負(fù)責(zé)維護(hù)角色的各種狀態(tài)數(shù)值,比如這里講的生命值和魔法值。如果我們要開(kāi)發(fā)一款類《饑荒》游戲,則這里的狀態(tài)就可以是生命值、饑餓值和san值。

閑話少說(shuō),我們開(kāi)始操作。

準(zhǔn)備工作

首先我們先新建一個(gè)枚舉藍(lán)圖,取名為E_Stats,有三個(gè)值,分別如下圖所示:

E_Stats

然后我們創(chuàng)建一個(gè)結(jié)構(gòu)體,保存最大、最小值、當(dāng)前值和回復(fù)時(shí)間、恢復(fù)速度等,取名為s_StateData。如下圖所示:

s_StateData

組件:BpC_StateManager

然后我們創(chuàng)建一個(gè)組件,也就是今天的主角:BpC_StateManager。這個(gè)組件負(fù)責(zé)儲(chǔ)存、管理其所在Actor上的所有State,并在需要的時(shí)候通過(guò)事件調(diào)度器完成回調(diào),這個(gè)我們會(huì)在之后講到。

正如上文所說(shuō),我們需要儲(chǔ)存狀態(tài),所以這里我們新建一個(gè)Map類型的變量,取名為StatDatas:

StatDatas

這個(gè)組件需要幾個(gè)函數(shù),我們一個(gè)一個(gè)新建

首先是GetStateData,很簡(jiǎn)單,獲取狀態(tài)數(shù)據(jù):

GetStateData

其次就是設(shè)置狀態(tài)數(shù)據(jù),SetStateData:

SetStateData

這里調(diào)用了UpdateStat這個(gè)事件調(diào)度器,這個(gè)我們?cè)谥笾v。此外,為了方便設(shè)置當(dāng)前值,這里還寫(xiě)了一個(gè)函數(shù)ModifyStat:

ModifyStat( 左)

這個(gè)函數(shù)需要傳入狀態(tài)類型、更改的值。先將這兩個(gè)值作為局部變量存儲(chǔ)起來(lái)(主要為了代碼的整潔)。然后判斷當(dāng)前Animated?是否為真。為真則直接返回。否則:

ModifyStat( 左)

通過(guò)SetStatData設(shè)置狀態(tài)數(shù)據(jù),設(shè)置的方式就是先獲取當(dāng)前值,然后加上傳入的值,并且保證在最大、最小值之間(Clamp)。

部分狀態(tài)可能需要自動(dòng)回復(fù),這部分我的做法是創(chuàng)建一個(gè)自定義事件,Actor調(diào)用這個(gè)事件,就會(huì)通過(guò)SetTimerByFuncitonName節(jié)點(diǎn)來(lái)周期性調(diào)用狀態(tài)恢復(fù)函數(shù),具體代碼如下圖所示:

SetupStatRegenerations左

首先便利StatDatas,其中的項(xiàng)。先判斷RateValue和RegenValue都不為零。然后:

SetupStatRegenerations右

RateValue就是SetTimerByFuncitonName調(diào)用的時(shí)間,具體的函數(shù)名依據(jù)StatType確認(rèn),然后調(diào)用上文中編寫(xiě)的SetStatData函數(shù)即可。

Actor

首先就是給Bp_CharacterBase這個(gè)Actor添加BpC_StateManager組件,并設(shè)置組件的值如下圖所示:

BpC_StateManager數(shù)據(jù)

如果你跟著一步步操作到現(xiàn)在,應(yīng)該已經(jīng)意識(shí)到StatType中“/”的作用,這里就不再多說(shuō)了。

還記得上文中所說(shuō)的事件調(diào)度器么?這里我們要在Bp_CharacterBase中調(diào)用它。就在BeginPlay事件中,添加如下節(jié)點(diǎn):

綁定事件到UpdateStat

上圖代碼的含義,就是其BpC_StateManager組件調(diào)用UpdateStat狀態(tài)時(shí)候,也會(huì)調(diào)用下方的SetupStaBar函數(shù),這里之所以如此實(shí)現(xiàn),是因?yàn)椴煌腁ctor對(duì)于UpdateState事件的處理方式是不同的,比如主角是要顯示在主界面UI上,而怪物則是顯示在頭頂版血條上。

并且需要注意的就是,在最后調(diào)用BpC_StateManager的SetupStatRegeneration事件。

現(xiàn)在我們需要讓狀態(tài)變化的結(jié)果顯示在UI上,創(chuàng)建一個(gè)Weiget,并取名W_Main。添加兩個(gè)ProgressBar。就可以關(guān)掉了。

在Bp_CharacterBase中創(chuàng)建W_Main并添加到ViewPort上:

創(chuàng)建 W_Main

雖然UE4為我們提供了關(guān)于ProgessBar中很多參數(shù)很方便的綁定,但這并不是我們學(xué)習(xí)的重點(diǎn)。仔細(xì)思考發(fā)現(xiàn),我們并不需要每幀檢測(cè)State數(shù)值的變化,而只需要在UpdateState時(shí)候更改ProgessBar上的顯示即可,所以函數(shù)SetupStatBar的實(shí)現(xiàn)如下圖所示:

SetupStatBar

Debug

又到了愉快的Debug時(shí)間,這次的Debug方式依然簡(jiǎn)單,在Bp_CharacterBase的事件圖表中添加如下事件:

debug

然后運(yùn)行游戲,試著改變Mana,然后將StatType修改為Health試試。好的,搞定,完美!

下集預(yù)告

之后的幾期,我們將陸續(xù)開(kāi)發(fā)一個(gè)可擴(kuò)展的技能系統(tǒng)。這個(gè)技能系統(tǒng)盡可能地由數(shù)據(jù)驅(qū)動(dòng),但我并不會(huì)直接創(chuàng)造一個(gè)這樣的系統(tǒng),而是由最“笨”的方法不斷改進(jìn)、重構(gòu),最終得到的,這個(gè)過(guò)程也將記錄下來(lái),可以更好地和同學(xué)們分享。那我們下期再見(jiàn)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 178,672評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,965評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 56,019評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 43,188評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,252評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,590評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過(guò)事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,526評(píng)論 1 11
  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,264評(píng)論 0 4
  • 作為一個(gè)合格的開(kāi)發(fā)者,不要只滿足于編寫(xiě)了可以運(yùn)行的代碼。而要了解代碼背后的工作原理;不要只滿足于自己的程序...
    六個(gè)周閱讀 8,481評(píng)論 1 33
  • 第3章 基本概念 3.1 語(yǔ)法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡(jiǎn)單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,149評(píng)論 0 21
  • 持久化 當(dāng)我們?cè)诩合到y(tǒng)中,一臺(tái)機(jī)器向另一臺(tái)機(jī)器發(fā)送一段數(shù)據(jù),負(fù)責(zé)接收的機(jī)器在接收數(shù)據(jù)前突然宕機(jī),就會(huì)造成數(shù)據(jù)丟失...
    mango_knight閱讀 4,564評(píng)論 0 4