不廢話妖混,開始分析FantasyWarrior3D結(jié)構(gòu)

假設(shè)大家都了解Cocos(3.3rc0),以及用過Cocos Code IDE(1.01)轮洋。這篇文章主要的內(nèi)容是這個游戲的的實現(xiàn)思路制市,具體細節(jié)會暫時(就)跳(是)過(懶)。

游戲總共有四個場景弊予,分別是

圖1-1

我們著重講一下BattleScene這個場景的結(jié)構(gòu)

BattleScene的層次

圖2-1

這個層次還是比較簡單的祥楣。一個Scene加一個Layer,其他元素都是AddChild到Layer上汉柒,包括英雄和怪物误褪。其中比較特殊的是camera,這是一個攝像機對象碾褂,用來控制畫面遠近兽间、視角等,另外uiLayer是掛在camera上的(我們在攝像機跟蹤一節(jié)解釋這個做法)

然后絕大部分邏輯由gameController這個定時器函數(shù)來控制正塌,其中包括碰撞檢測嘀略、攻擊指令、攝像頭跟蹤乓诽、以及游戲主邏輯帜羊。這個定時器函數(shù)每一幀都會被引擎調(diào)用。

圖2-2

最后currentLayer支持觸摸鸠天,這個用來觸發(fā)英雄的特殊技能和控制鏡頭讼育。

碰撞檢測

collisionDectect是gameController內(nèi)第一個被調(diào)用的函數(shù),用來檢查所有游戲中的所有角色稠集。如果角色離的太近奶段,會讓他們’推‘開;如果超過游戲場景邊緣巍杈,會把他們’挪‘回來忧饭。

每一個游戲角色有一個圓形區(qū)域,這個區(qū)域大小由_radius決定筷畦;另外它有重量词裤,由_mass決定;

所有有效的游戲角色都被放入了HeroManager和MonsterMananger內(nèi)鳖宾,所以碰撞檢測的邏輯就是:取出每一個角色吼砂,與剩下的角色進行計算距離,小于兩者半徑之和判定為發(fā)生‘碰撞’鼎文;按兩者中心點的直線方向渔肩,計算應(yīng)該后退的距離,設(shè)置新的位置坐標(由重量決定后退的比例)拇惋。

碰撞檢測結(jié)束后周偎,會順便檢測角色是否超過預(yù)先設(shè)定的場景邊緣位置抹剩,這在isOutOfBound內(nèi)實現(xiàn)。

注意蓉坎,碰撞檢測不會處理已經(jīng)‘死亡’的游戲角色澳眷,碰撞檢測中HeroManager和MonsterManager會移除死亡的游戲角色。

攝像機跟蹤

在我們的游戲中蛉艾,攝像機有兩種跟蹤方式:

第一種跟隨三個主角所在位置自動移動钳踊,同時根據(jù)玩家手指移動稍微改變位置,第二種是游戲角色釋放特殊技能時切換特殊的視角勿侯。

這兩種攝像機跟蹤都在同一個函數(shù)moveCamera內(nèi)實現(xiàn)拓瞪,核心邏輯是通過setPosition3D不斷改變攝像機的位置,同時通過lookAt讓攝像機‘看’向正確的位置助琐。你可以想象一支筆的兩端祭埂,一端是攝像頭位置,一端是它‘看’的位置弓柱。

另外沟堡,由于攝像機位置需要從A點改變到B點,看的位置從a點到b點矢空,我們不能直接setPosition3D(B)和lookAt(b)航罗,而是需要計算從A到B,以及從a到b的差值位置屁药。在游戲中我們通過cc.pLerp(A, B)來計算得到需要逐步移動的位置粥血。

在BattleScene的onTouchMoved函數(shù)內(nèi),玩家通過觸摸改變cameraOffset的值酿箭,攝像機位置會隨這個值改變复亏,于是實現(xiàn)了玩家在限制范圍內(nèi)控制攝像機位置的功能。

最后缭嫡,我們把uiLayer掛在攝像頭上(addChild)缔御,就是由于攝像機位置一直變化。如果放在currentLayer上妇蛀,攝像機一移動耕突,UI界面就看不到了。現(xiàn)在uiLayer會隨著攝像機移動改變位置评架,所以我們就能一直看到UI界面眷茁,這就像你帶了一副眼鏡,不管你怎么轉(zhuǎn)頭纵诞,眼鏡架還是在你鼻梁上上祈。

最后用幾張圖來表示攝像機在3D空間的位置和移動的方式

圖2-3

左圖是引擎默認情況下,攝像機的位置。左圖的綠色紅色箭頭是x軸登刺,藍色箭頭是y軸籽腕,綠色箭頭為z軸。通過閱讀Camera::initDefault源碼塘砸,可以知道节仿,在3D模式下晤锥,攝像機是位于(winSize.width/2, winSize.height/2, getZEye)掉蔬,并向(winSize.width/2, winSize.height/2)方向看。

右圖是游戲中攝像機的位置矾瘾,在運行時女轿,它會根據(jù)英雄當前所在的位置不斷調(diào)整x軸和y軸坐標,而z軸坐標不變壕翩。

UI層

這一層用來顯示游戲角色頭像蛉迹、血量、憤怒值放妈,角色受到攻擊頭像會震動北救,角色死亡后會變成黑白色,可以觸摸角色頭像觸發(fā)特殊技能攻擊敵人芜抒,勝利時顯示成功界面珍策。

值得一說的是,我們把UI層邏輯和游戲邏輯拆分開宅倒,用注冊消息\函數(shù)回調(diào)的方式來解決數(shù)據(jù)傳輸?shù)膯栴}攘宙。

在BattleScene中,我們注冊了BLOOD_MINUS拐迁,ANGRY_CHANGE消息蹭劈,用來接收血量變化、憤怒值變化线召,通過回調(diào)函數(shù)boodMinus铺韧,angryChange,調(diào)用uiLayer改變血量缓淹,憤怒值哈打。

角色類結(jié)構(gòu)

游戲角色類都放在actors文件夾下,它們的關(guān)系如下

圖2-4

每個游戲角色在創(chuàng)建的時候割卖,都擁有一個自身update函數(shù)前酿,運行時每幀調(diào)用一次。這個update函數(shù)負責調(diào)用如下邏輯:

圖2-5

baseUpdate函數(shù)鹏溯,它負責定時執(zhí)行角色的AI邏輯(具體內(nèi)容我們在角色AI一節(jié)解釋)罢维。

stateMachineUpdate函數(shù),它負責根據(jù)目前角色狀態(tài)值讓角色表現(xiàn)對應(yīng)狀態(tài)的動作、動畫肺孵。

movementUpdate函數(shù)匀借,它負責兩件事情,一是在不斷改變自己的位置平窘,讓角色在游戲中移動吓肋;二是改變旋轉(zhuǎn)角度,讓角色面向目標方向瑰艘。

角色的狀態(tài)機

角色的狀態(tài)在GlobalVariables.lua文件中定義是鬼,由下圖幾個狀態(tài)組成

圖2-6

角色的狀態(tài)被stateMachineUpdate控制,不斷的在以上六種狀態(tài)中切換紫新,切換的邏輯如下圖:

圖2-7

walkUpdate的邏輯是:如果角色已經(jīng)有一個目標(角色AI中實現(xiàn))均蜜,如果目標在攻擊范圍內(nèi),就切換到attackMode芒率;如果不在攻擊范圍囤耳,繼續(xù)移動過去。如果沒有目標偶芍,繼續(xù)往右走充择,如果右邊不能再走了,就停在那里發(fā)呆(移動在movementUpdate里實現(xiàn))匪蟀。

attackUpdate的邏輯是:每次攻擊需要花一定時間椎麦,首先判斷是否到了下一次攻擊的時間;如果是萄窜,根據(jù)概率發(fā)出普通攻擊或者特殊攻擊铃剔,然后播放攻擊動畫。特殊攻擊的時候做三件事情查刻,一键兜、除了發(fā)技能的角色意外的游戲畫面全部暗下來(通過發(fā)送SPECIAL_PERSPECTIVE消息,調(diào)用回調(diào)函數(shù)實現(xiàn))穗泵;二普气、讓攝像頭移動,形成特寫效果佃延;三慢哈、通過setTimeScale降低scheduler的速度浑吟,形成慢動作效果喷面。此外無論是特殊攻擊還是普通攻擊扣蜻,會生成攻擊環(huán)(這個在攻擊指令一節(jié)中說明)。

knockingUpdate的邏輯是:每次被擊中需要一定時間播放受擊動畫尺棋,首先判斷被攻擊動畫是否播放結(jié)束封锉;如果是,判斷目標是否在自己的攻擊范圍內(nèi),如果是成福,進入attackMode碾局,如果不是,切換到walkMode奴艾。

角色AI

角色的AI是被baseUpdate驅(qū)動的净当,每個角色有自己的_AIFrequency。所以AI的基本邏輯是:首先判斷是否到了下一次執(zhí)行AI的時間蕴潦,如果是像啼,執(zhí)行AI。

AI邏輯主要是尋找攻擊目標品擎,如果沒有找到目標埋合,根據(jù)當前狀態(tài)切換到walkMode或者idleMode;如果找到目標萄传,判斷目標是否在自己的攻擊范圍內(nèi),如果是蜜猾,切換到attackMode秀菱,如果不是,切換到walkMode去靠近目標蹭睡。

攻擊指令

攻擊指令是一個獨立類衍菱,它的baseClass是BasicCollider,結(jié)構(gòu)如下:

圖2-8

其中的sp變量就是游戲中我們看到的冰錐肩豁、冰球脊串、箭支,分別是一個sprite或者sprite3D對象實例清钥。

但是真正起到攻擊作用的琼锋,是BasicCollider的攻擊區(qū)域,它可能是一個扇形祟昭、圓形或者圓環(huán)缕坎,如圖

minRange決定攻擊最小半徑,可以為0篡悟;maxRange大于minRange谜叹;angle決定了扇形圓心角,值的范圍在(0, 360]搬葬;facing決定方向荷腊;這幾個屬性決定了攻擊區(qū)域的大小。例如A和B急凰,唯一的差別是A的minRange=0女仰,當目標在A或者B區(qū)域內(nèi),都會受到傷害。

攻擊指令在創(chuàng)建時董栽,就被加入到AttackManager里(BasicCollider:initData)码倦。而solveAttacks(還記得在哪里調(diào)用嗎)中會循環(huán)遍歷AttackManager,每次取出一個攻擊指令锭碳,判斷它與游戲角色是否發(fā)生碰撞袁稽,如果沒有,就繼續(xù)與其他游戲角色比較擒抛;如果有推汽,調(diào)用onCollide,播放攻擊特效歧沪、聲效歹撒,調(diào)用被攻擊角色的hurt函數(shù);在循環(huán)結(jié)束前诊胞,從AttackManager移除已經(jīng)無效的攻擊指令(無效是指curDuration > duration)暖夭。

攻擊指令中還有兩種特殊指令,一種是可以移動的攻擊指令撵孤,比如飛行的冰球迈着、箭支,一種是DOT(Damage over time邪码,在一段時間內(nèi)不斷對目標造成傷害)裕菠,只有這種指令才有curDOTTime和DOTTimer屬性。在solveAttacks的循環(huán)結(jié)束前闭专,有一個attack:onUpdate函數(shù)被調(diào)用奴潘,這個函數(shù)會不斷改變攻擊指令的位置,以實現(xiàn)‘飛行’的效果影钉;另外画髓,這函數(shù)會改變curDOTTime的值,這樣斧拍,當curDOTTime > DOTTimer時雀扶,onCollide就會對處于攻擊范圍內(nèi)的目標產(chǎn)生傷害。

游戲主邏輯

主邏輯靠GameMaster:update驅(qū)動肆汹,這個函數(shù)在BattleScene中g(shù)ameController中被調(diào)用愚墓。

游戲主邏輯包含二個功能:第一,創(chuàng)建英雄和怪物昂勉;第二浪册,在合適的時機顯示怪物和界面。

值得一說的是岗照,在游戲進行中村象,創(chuàng)建怪物會導致游戲卡頓笆环,所以我們在創(chuàng)建的時候就把所有的怪物放在了對應(yīng)的pool里,同時也addChild到了currentLayer上厚者,同時設(shè)置為隱藏躁劣;在游戲進行中,我們才把pool里的怪物拿出來库菲,放到MonsterManager里面账忘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市熙宇,隨后出現(xiàn)的幾起案子鳖擒,更是在濱河造成了極大的恐慌,老刑警劉巖烫止,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒋荚,死亡現(xiàn)場離奇詭異,居然都是意外死亡馆蠕,警方通過查閱死者的電腦和手機期升,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來荆几,“玉大人吓妆,你說我怎么就攤上這事《种” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵祖秒,是天一觀的道長诞吱。 經(jīng)常有香客問我,道長竭缝,這世上最難降的妖魔是什么房维? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮抬纸,結(jié)果婚禮上咙俩,老公的妹妹穿的比我還像新娘。我一直安慰自己湿故,他們只是感情好阿趁,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著坛猪,像睡著了一般脖阵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墅茉,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天命黔,我揣著相機與錄音呜呐,去河邊找鬼。 笑死悍募,一個胖子當著我的面吹牛蘑辑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坠宴,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼洋魂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了啄踊?” 一聲冷哼從身側(cè)響起忧设,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颠通,沒想到半個月后址晕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡顿锰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年谨垃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硼控。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡刘陶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出牢撼,到底是詐尸還是另有隱情匙隔,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布熏版,位于F島的核電站纷责,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏撼短。R本人自食惡果不足惜再膳,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曲横。 院中可真熱鬧喂柒,春花似錦、人聲如沸禾嫉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夭织。三九已至吭露,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尊惰,已是汗流浹背讲竿。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工泥兰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人题禀。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓鞋诗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親迈嘹。 傳聞我的和親對象是個殘疾皇子削彬,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

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

  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 3,794評論 0 9
  • 本教程旨在教會大家如何為YGOPro編寫或修改一個AI腳本。前幾節(jié)是新手指引秀仲,而接下來的章節(jié)涵蓋了一些更深入的知識...
    e26h閱讀 13,190評論 2 9
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,321評論 25 707
  • 111. [動畫系統(tǒng)]如何將其他類型的動畫轉(zhuǎn)換成關(guān)鍵幀動畫融痛? 動畫->點緩存->關(guān)鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 13,063評論 3 90
  • 假如我能遇見你 也是不言語 可我只看見了自己 便有了滿腹言語 轉(zhuǎn)角低頭千百次 低下的卻是勇氣
    風起2015閱讀 199評論 3 1