您好,登錄后才能下訂單哦!
回合制戰(zhàn)斗的技能實現(xiàn)
The limits of my language means the limits of my world ---- Ludwig Wittgenstein
我們游戲的邏輯部分是放在服務器端進行處理的,實際上前端所處理的僅僅是一個表現(xiàn)效果,可以說只是一個播放器。但實際上完全可以在本地加上一個邏輯模塊,將全部的邏輯放在本地處理。
一般來說,邏輯模塊處理技能之后,display模塊會得到如下數(shù)據(jù)
1.技能id
2.主動角色:戰(zhàn)場中的哪個角色釋放了技能 (實際上,這個擁有多個角色,實現(xiàn)出類似于合體技的效果,但是我們的項目沒有這類的需求,故只處理了一個)
3.被動角色組:戰(zhàn)場中哪些角色被主動角色發(fā)動的技能施加了影響 (是傷害?還是治療?還是增加了一個buff?)
我們先看一下我們第一版的戰(zhàn)斗技能實現(xiàn)方式,最原始的版本,這里以近戰(zhàn)和遠程***為例
1.通過技能id讀表獲得此技能的類型 (是近戰(zhàn)還是遠程,還是全體)
2.卡牌移動到目標前方
3.卡牌播放***動作
4.卡牌播放動作同時,在卡牌前播放特效
5.特效的傷害幀播放受擊卡牌的受傷動畫
6.卡牌歸位,下一輪
遠程***
1.卡牌播放放波動作
2.特效從我方卡牌飛向目標卡牌(可能有多個)
3.特效關(guān)鍵幀觸發(fā)后,被擊卡牌播放受傷動畫
4.卡牌動作歸位,下一輪
全體***同上,只是取敵方陣正中央播放一個全體特效
......
這個原始版本有如下的幾個弊端
1.每類技能都需要單獨了一套實現(xiàn),類似于飛行時間此類的細節(jié)可以通過增加技能參數(shù)來實現(xiàn),但是實現(xiàn)類似于打橫排,打豎排之類就需要新增加一種技能類型,big class bang!
2.即便是同類***,也需要處理很多小的細節(jié)。
例如:
某遠程技能需要在釋放時,先播放一個特效,然后再將飛彈打出去。
某近戰(zhàn)技能需要在目標卡牌前播放一個蓄力動畫再發(fā)動***。
某全體技能需要釋放者先走到屏幕中央,然后再播技能特效,而另一個技能則是走到敵方陣營的正中央
......
3.修改怎么辦?如果某些技能需要改變,策劃們會屁顛屁顛地跑過來,很開心得指出你的細節(jié)問題,然后各種不相關(guān)的人也過來巴拉巴拉巴拉....能tm把人給煩死,這種痛苦大家都懂得
以上幾個重大缺陷最終迫使我放棄了第一版的戰(zhàn)斗實現(xiàn),雖然當時的戰(zhàn)斗復雜程度已經(jīng)和目標游戲《放開那三國》差不多了,但是實在是可擴展性極差,不得已,推倒原設(shè)計轉(zhuǎn)入了第二版。
第二版的設(shè)計目標
經(jīng)歷了第一版的慘痛經(jīng)歷,我為第二版設(shè)定了如下的設(shè)計目標
1.策劃可以通過配表,獨立實現(xiàn)技能權(quán)利 (沒事不準來煩我?。?/p>
2.高度抽象,將全部的實現(xiàn)抽象為幾個類,避免繼續(xù)第一版類爆炸 (功能內(nèi)聚)
3.針對特性編程,不針對實現(xiàn)編程,不搞特殊化技能的代碼實現(xiàn) (給你工具,自己實現(xiàn))
實際上這幾個需求的目標是完全一致的,即,實現(xiàn)一個技能的工具箱,策劃通過獨立組合卡牌和特效的動態(tài)效果,來獨立配置技能。先重新分析下第一版的戰(zhàn)斗。
近戰(zhàn)戰(zhàn)斗
1.通過技能id讀表獲得此技能的類型 (...)
2.卡牌移動到目標前方 (卡牌移動了)
3.卡牌播放***動作 (卡牌播放了一個動作)
4.卡牌播放動作同時,在卡牌前播放特效 (卡牌播放了一個動作,產(chǎn)生了一個特效)
5.特效的傷害幀播放受擊卡牌的受傷動畫 (產(chǎn)生了一個特效)
6.卡牌歸位,下一輪 (卡牌移動了,技能結(jié)束了)
抽象地語義分析一下,這里面有這么幾個簡單的過程:
1.卡牌移動了
2.卡牌播放動作了
3.產(chǎn)生了技能特效
4.技能結(jié)束了
進一步分析會發(fā)現(xiàn):卡牌移動和卡牌播放動作完全可以合并成同一個,卡牌動作
我們可以視
卡牌原地不動播放做動作是卡牌動作的一個特例
卡牌移動但是不播放動作也是卡牌動作的一個特例
這樣過程就抽象為
1.卡牌動作
2.產(chǎn)生了技能效果
3.技能結(jié)束
這三個過程
這時候再分析遠程
遠程***
1.卡牌播放放波動作 (卡牌動作)
2.特效從我方卡牌飛向目標卡牌(產(chǎn)生了技能特效,技能特效移動了)
3.特效關(guān)鍵幀觸發(fā)后,被擊卡牌播放受傷動畫 (卡牌動作,產(chǎn)生了一個技能特效)
4.卡牌動作歸位,下一輪 (卡牌動作,技能結(jié)束)
同上面的分析,我們會發(fā)現(xiàn),技能特效的產(chǎn)生和移動同樣可以合并成一個,即技能效果,靜止技能是移動技能的一個特例
所以最終我們的技能工具箱里只剩下了三個抽象工具
1.卡牌動作 (移動和動作)
2.技能效果 (創(chuàng)建和動作)
3.技能結(jié)束 (技能結(jié)束)
也就是說,近戰(zhàn)***和遠程***都是由這三個過程組合而成的,之前沒有提到的全體技能也可以進行此類分析
1.卡牌播放了施法動作 -> 卡牌動作
2.卡牌上方播放了施法特效 -> 技能效果
3.目標卡牌組上播放全體特效 -> 技能效果
4.目標卡牌組上播放受傷特效 -> 技能效果
5.技能結(jié)束 -> 技能結(jié)束
使用工具箱中的三種描述,是完全有可能實現(xiàn)的!
在這里我們假象一種相對復雜的技能:
主動卡釋放了一組飛彈,命中了全體敵人,然后移動到敵方陣營正中央,釋放了一個全屏幕特效的全體技能,最后從屏幕的最后方,召喚了一只老鷹(特效),飛到敵人后方且***了全部敵人
分析如下:
1.主動卡施法動作 -> 卡牌動作
2.釋放一組飛彈-> 技能效果
3.主動卡移動到敵方陣營正中間 -> 卡牌動作
4.敵方正中央播放全體技能特效 -> 技能效果
5.特效觸發(fā)幀,敵方全體卡牌播放受傷動畫 -> 卡牌動作
6.創(chuàng)建老鷹特效,從我方屏幕后方移動到敵方后方 -> 技能效果
7.老鷹特效觸發(fā)幀播放受傷特效 -> 卡牌動作
8.主動卡歸位 -> 卡牌動作
9.技能結(jié)束 -> 技能結(jié)束
可以看到基本滿足了要求,所以我們可以從語義上對回合制游戲的大部分技能進行完全的抽象描述了
接下來,就是對下面三個工具的實現(xiàn)描述
表結(jié)構(gòu)
依上所述,卡牌動作主要分兩部分,一個是卡牌的動畫動作,另外一個是卡牌執(zhí)行的位移。
卡牌動畫動作
我們使用的是cocostudio實現(xiàn)的動畫,每個卡牌的動畫都是封裝好的,執(zhí)行某個動作策劃只需要將當前卡牌執(zhí)行的動作名填表即可
卡牌的位移
位移相對麻煩一些,因為我們不可能讓策劃詳細填寫坐標吧?但是實際上,卡牌位移可能出現(xiàn)的起始位置是一個有限集,是完全可以預定義的,如下
1.主動卡原位置
2.目標卡位置(目標卡一般是個卡組,這個返回的是第一個)
3.目標卡組列位置 (取第一張卡,然后根據(jù)位置算出當前的列位置)
4.目標卡組行位置 (同上)
5.屏幕正中央
6.我方后方
7.敵方后方
8.敵方正中央
....
以上列舉一些可能卡牌位置,具體實現(xiàn)時,可以靈活添加。
舉一個實際的例子,某個卡牌動作是,從主動卡原位置移動到屏幕正中央(0.5秒),且播放移動動作(walk),策劃填卡牌動作表如下,move代表的是起始位置
cardMove.xlsx
id | act | move | time |其他 ...
---------------------------
1 | walk | [1,5] | 0.5 |其他 ...
*這里的act下填寫的是卡牌的動作名稱
這樣當技能的狀態(tài)機執(zhí)行到這兒的時候,就知道該如何移動了
同理,一個老鷹特效從屏幕后方飛刀敵方中央(0.5),策劃填表特效表如下
effect.xlsx
id | file | move | time |其他 ...
---------------------------
1 | eagle| [6,8] | 0.5 |其他 ...
*這里的file下填寫的使用的動畫文件的名字
技能狀態(tài)機依次讀取對應的結(jié)構(gòu)然后播放就可以了....
等等! 還沒有講調(diào)用!
是的!
調(diào)用也很簡單
cardMove.xlsx
id | act | move | time | callback | ...
--------------------------------------------
1 | walk | [1,5] | 0.5 | [effect,1] |
id | act | move | time | callback | ...
--------------------------------------------
2 | walk | [5,1] | 0.5 | [over,1] |
effect.xlsx
id | file | move | time | callback |
--------------------------------------------
1 | eagle| [6,8] | 0.5 | [cardMove,2] |
簡單的流程就是:
cardMove[1] -> effect[1] -> cardMove[2] -> over
這個的實現(xiàn)方式有點類似于鏈表,callback指定了技能狀態(tài)機下一個執(zhí)行的函數(shù),一直執(zhí)行到 over 為止,技能狀態(tài)機開始執(zhí)行下一個技能。
實際上的cardMove表和effect表遠比這要復雜,在實際的項目中,我們的callback是一個帶延遲時間的數(shù)組 如下:
[[1.5,[cardMove,2]],[1.5,[effect,2]],[1.0,[effect,3]]]
這條callback延時調(diào)用了三個函數(shù),實現(xiàn)了一個卡牌移動和兩個技能特效,而前面的數(shù)值則是延遲調(diào)用的時間,這種多重調(diào)用可以制造天女散花類的效果
大家可以考慮下下面這個技能效果如何通過配表實現(xiàn)
主動卡發(fā)射了一個飛彈,命中了屏幕正中央,引發(fā)一次爆炸特效,之后從爆炸特效發(fā)射出六個飛彈命中了敵方的六個目標。
后期有時間會把示例代碼發(fā)出來,基于quick cocos2dx的 lua實現(xiàn)。
應某友要求,接下來將會嘗試使用此套類似的機制,嘗試實現(xiàn)LOL中的部分技能效果,使策劃能夠自由配置想要的技能效果。
個人認為,只要能夠用語言描述出來的技能,必然能夠配置實現(xiàn)。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。