包含6節(jié)視頻教程
關(guān)注8.2萬(wàn)次
本系列使用Unity3D制作一個(gè)完整的像素鳥游戲,這種2d游戲是最常見(jiàn)的橫版過(guò)關(guān)游戲,老師通過(guò)簡(jiǎn)潔易懂的語(yǔ)言,很完美的詮釋了這一過(guò)程。即使是你不會(huì)編程,不會(huì)美工,仍然可以把這個(gè)游戲制作出來(lái),做完之后你可以應(yīng)用這些技術(shù)制作類似的游戲,馬上來(lái)學(xué)習(xí)吧!
1. 客戶端地圖格子的相關(guān)知識(shí)
在2.5D的MMO游戲里,角色是通過(guò)3D的方式渲染,2D的地圖是通過(guò)2D的方式顯示,所以在客戶端一般會(huì)有三個(gè)坐標(biāo)系:
a) 3D坐標(biāo)系:所有需要3D渲染的角色和光效,都以3D坐標(biāo)系中定位。
b) 2D坐標(biāo)系:用來(lái)定位和繪制固定的2D地圖元素,比如草皮、馬路等。
c) 3D坐標(biāo)里的格子坐標(biāo)系:用來(lái)實(shí)現(xiàn)打掩碼、自動(dòng)尋路和進(jìn)行一些坐標(biāo)配置(比如NPC和怪物初始的位置)。使用格子坐標(biāo),一是為了方便打掩碼和進(jìn)行自動(dòng)尋路的計(jì)算(經(jīng)典的A*尋路),二是為了更方便查找坐標(biāo)的具體位置。
端游使用的格子大小一般為(64, 32),手游的精確度要求低一些,可以用(100, 50),即3D坐標(biāo)系里長(zhǎng)為100寬為50的矩形,即是格子坐標(biāo)系里的一個(gè)坐標(biāo)。示例圖如下:
MMO游戲里,玩家要能看到地圖上所有角色的行為,這就需要將其它玩家的動(dòng)作都通過(guò)網(wǎng)絡(luò)數(shù)據(jù)同步過(guò)來(lái)。同步一般使用9宮格來(lái)確定,哪些玩家的數(shù)據(jù)要同步過(guò)來(lái),然后自己的行為要同步給哪些玩家。
服務(wù)器大格子的大小,以3*3的格子要總比客戶端顯示范圍要大一點(diǎn)為原則。比客戶端大一點(diǎn),是為了預(yù)留資源加載的時(shí)間。
如下圖所示,綠色表示手機(jī)客戶端的顯示區(qū)域,當(dāng)角色A在格子6中時(shí),他可以看到1,2,3,5,6,7,9,10,11這9個(gè)格子里的內(nèi)容,那么當(dāng)他的狀態(tài)發(fā)生變化時(shí),就需要同步給在這9個(gè)格子里的所有玩家;同樣,當(dāng)這9個(gè)格子里的有玩家或者怪物的狀態(tài)改變時(shí),也需要都同步給角色A。
當(dāng)角色A移動(dòng)到角色B所在的格子(7),則他將不再看到1,5,9這三個(gè)格子里的內(nèi)容(玩家和怪物),同時(shí)他將新看到4,8,12這三個(gè)格子里的地圖內(nèi)容。所以這個(gè)過(guò)程中,服務(wù)器要下發(fā)消息,刪除角色A所在的客戶端里的1,5,9這三個(gè)格子里的地圖內(nèi)容,同時(shí)下發(fā)消息新增4,8,12這三個(gè)格子里的地圖內(nèi)容(類型一)。
推薦大格子具體的大小,按客戶端iPhone4S的960*640分辨來(lái)制定,取屏幕長(zhǎng)寬的1/2大一些,可以定為640*360。
地圖上角色的同步可以分為位移的同步和行為(比如放技能)的同步。這里主要討論位移的同步方式。
位移同步的目的是為了將自己的位置變化發(fā)給服務(wù)器,然后由服務(wù)器通過(guò)9宮格的方式轉(zhuǎn)發(fā)給周圍的其他玩家。
有的端游是以客戶端格子的基本單位進(jìn)行同步,當(dāng)玩家從一個(gè)格子移動(dòng)到了另一個(gè)格子時(shí),就發(fā)消息通知給服務(wù)器。這種方式的缺點(diǎn)就是:
一、同步的延遲。玩家從一個(gè)格子開始移動(dòng),移動(dòng)到另一個(gè)格子后,才發(fā)消息給服務(wù)器,服務(wù)器再轉(zhuǎn)發(fā)給其它客戶端,那其它客戶端的玩家位置,總會(huì)有一點(diǎn)延后。
二、當(dāng)網(wǎng)絡(luò)不穩(wěn)定的時(shí)候,很容易看到其它玩家不是均速的移動(dòng),比如玩家位置沒(méi)動(dòng),然后一下子瞬移到了下一個(gè)格子。
我們采用的方式,是同步狀態(tài)的變化,然后由客戶端來(lái)觸發(fā)服務(wù)器對(duì)大格子跨越的判斷:
d) 當(dāng)玩家點(diǎn)擊地圖上某個(gè)地方,或者改變了搖桿方向,玩家的運(yùn)行狀態(tài)就變化了,即向某個(gè)坐標(biāo)點(diǎn)移動(dòng)。狀態(tài)變化的時(shí)候,客戶端就立即給服務(wù)器發(fā)消息,然后服務(wù)器進(jìn)行轉(zhuǎn)發(fā)。這樣如果忽略了網(wǎng)絡(luò)的延遲,那這個(gè)角色在所有客戶端上,幾乎是同時(shí)開始移動(dòng)。
如果移動(dòng)過(guò)程中沒(méi)有其它變化,則整個(gè)移動(dòng)過(guò)程中只有一次消息同步。這里需要處理一個(gè)問(wèn)題,就是服務(wù)器需要知道這個(gè)角色什么時(shí)候跨越了服務(wù)器的同步大格子,當(dāng)角色跨越了同步大格子時(shí),服務(wù)器就需要進(jìn)行第二節(jié)里(類型一)的操作。
e) 如何判斷角色的移動(dòng)過(guò)程中跨越了同步大格子,有的游戲里采用服務(wù)器判斷的方式,即根據(jù)角色的移動(dòng)速度和方向,計(jì)算出跨越的時(shí)刻,然后使用一個(gè)Timer來(lái)觸發(fā)。同時(shí)如果服務(wù)器要取這個(gè)角色的當(dāng)前位置,則需要通過(guò)運(yùn)動(dòng)公式來(lái)進(jìn)行計(jì)算。這個(gè)方案相對(duì)精確一些,但比較復(fù)雜,服務(wù)器也需要為每一個(gè)移動(dòng)的角色設(shè)定一個(gè)Timer,對(duì)服務(wù)器的性能有所影響。
我們采用的方式,是由客戶端判斷角色每移動(dòng)一小段距離,然后發(fā)消息通知服務(wù)器,服務(wù)器不對(duì)這個(gè)消息進(jìn)行轉(zhuǎn)發(fā),而只是判斷是否跨越了大格子,同時(shí)記錄下這個(gè)坐標(biāo),作為角色的當(dāng)前位置。這一小段距離可以取100左右,值取得越大時(shí),消息發(fā)送頻率越小,但服務(wù)器的同步大格子跨越判斷和角色當(dāng)前位置就越不精確。
因?yàn)槭侵苯油降倪\(yùn)行狀態(tài),所以客戶端發(fā)給服務(wù)器的坐標(biāo)單位是3D坐標(biāo)系里單位,而不是3D坐標(biāo)系格子的坐標(biāo)單位。這樣就更加精確,一點(diǎn)點(diǎn)距離的移動(dòng),都能準(zhǔn)確同步。
f) 同步運(yùn)動(dòng)狀態(tài)的一個(gè)問(wèn)題是,如果玩家操作很頻繁,比如快死了逃跑時(shí),瘋狂地點(diǎn)地圖,這時(shí)運(yùn)動(dòng)狀態(tài)變化的非?,如果每個(gè)狀態(tài)的變化都同步給服務(wù)器,再加上廣播,那消息量是很大的。
所以需要設(shè)置一個(gè)狀態(tài)同步的最短時(shí)間,當(dāng)運(yùn)動(dòng)狀態(tài)變化很快時(shí),則將狀態(tài)變化的消息緩存在客戶端,同時(shí)加一個(gè)Timer跟蹤。當(dāng)馬上有新的狀態(tài)變化消息出來(lái)時(shí),則進(jìn)行替換,同時(shí)更新Timer。當(dāng)沒(méi)有狀態(tài)變化的消息出來(lái)時(shí),Timer到時(shí)間了就會(huì)觸發(fā),將緩存的狀態(tài)變化的消息,發(fā)給服務(wù)器。
這樣通過(guò)消息緩存加上Timer的處理,既實(shí)現(xiàn)了運(yùn)行狀態(tài)同步的最短時(shí)間限制,也保證了最后有效的運(yùn)行狀態(tài)會(huì)稍晚一點(diǎn)點(diǎn)發(fā)送給服務(wù)器。
怪物的同步在傳統(tǒng)的端游里,是完全由服務(wù)器的怪物AI系統(tǒng)觸發(fā),客戶端只是純粹的接受服務(wù)器下發(fā)的怪物狀態(tài)數(shù)據(jù)。對(duì)于手機(jī)游戲里,由于手機(jī)上很難出現(xiàn)像PC里那樣的外掛,所以怪物的AI可以考慮放在客戶端觸發(fā),同時(shí)減少怪物的狀態(tài)同步。詳細(xì)說(shuō)明如下:
a) 怪物的隨機(jī)移動(dòng)不同步
在地圖上,怪物都會(huì)有一個(gè)固定的位置。怪物沒(méi)有進(jìn)入戰(zhàn)斗狀態(tài)時(shí),就會(huì)在這個(gè)固定位置的周圍走來(lái)走去,隨機(jī)的移動(dòng)。這個(gè)隨機(jī)的移動(dòng)由每個(gè)客戶端自己控制,這樣怪物的隨機(jī)移動(dòng),就不用消息廣播進(jìn)行同步了。
由于客戶端自己控制怪物的隨機(jī)走動(dòng),所以會(huì)出現(xiàn)不同客戶端里,怪物位置不一樣的問(wèn)題。但由于怪物隨機(jī)移動(dòng)的范圍較小,所以這個(gè)問(wèn)題不是很明顯,在手機(jī)上是可以接受的。角色打怪時(shí),是扇形的傷害范圍,所以即使怪物坐標(biāo)在不同的客戶端有點(diǎn)不一致,打怪的效果也是可以接受的。
b) 怪物的行為同步
當(dāng)有角色攻擊被動(dòng)怪物,或者進(jìn)入主動(dòng)怪物的視野范圍內(nèi)時(shí),怪物的AI就被這個(gè)角色所在的客戶端鎖定了,同時(shí)怪物進(jìn)入攻擊狀態(tài)。攻擊的判斷完全由鎖定怪物AI的客戶端進(jìn)行處理,同時(shí)這個(gè)客戶端會(huì)將這個(gè)怪物的行為上發(fā)到服務(wù)器,由服務(wù)器廣播給周圍的其他玩家。
怪物的AI鎖定,使用搶占式,即誰(shuí)最先發(fā)消息給服務(wù)器申請(qǐng)怪物的AI鎖定,誰(shuí)就獲得了怪物的控制權(quán),直到怪物死亡或脫離戰(zhàn)斗狀態(tài)。
怪物可以每進(jìn)行一次攻擊,客戶端就發(fā)一個(gè)消息給服務(wù)器。這樣做,消息還是有點(diǎn)多,特別是一群怪圍著幾個(gè)角色進(jìn)行攻擊時(shí),消息廣播還是有點(diǎn)多。所以可以將狀態(tài)的概念向上擴(kuò)大,只同步怪物在攻擊哪個(gè)玩家,而不同步每一次的攻擊,然后由每個(gè)客戶端根據(jù)怪物固定的攻擊速度各自去表現(xiàn)。這樣一個(gè)怪去攻擊一個(gè)玩家,就會(huì)只有一次消息廣播了。
c) 精英怪和BOSS怪的AI
精英怪和BOSS怪由于數(shù)量較少,而且比較重要,所以不能由客戶端來(lái)申請(qǐng)AI控制權(quán),而是服務(wù)器根據(jù)某種策略來(lái)控制。所使用的策略可以考慮角色的傷害值、防御值、角色與BOSS的距離遠(yuǎn)近等,根據(jù)這些因素,服務(wù)器計(jì)算出BOSS怪當(dāng)前最適合攻擊的對(duì)象(比如血量最少的玩家,最脆弱的法師等),然后將AI控制權(quán)發(fā)給那個(gè)客戶端,由那個(gè)客戶端控制攻擊行為,同時(shí)通過(guò)消息讓服務(wù)器同步給其他玩家。
總結(jié):怪物的同步方式的選擇,就是要盡量減少消息的廣播,同時(shí)讓游戲效果在可接受的范圍內(nèi)。怪物AI的這個(gè)處理方式,實(shí)際上是同時(shí)省去了游戲服務(wù)器的怪物AI模塊(端游一般是專門用的一個(gè)進(jìn)程或者另外一臺(tái)物理服務(wù)器來(lái)進(jìn)行怪物AI的計(jì)算),從而簡(jiǎn)化了MMO游戲的開發(fā)難度,同時(shí)保證了較好的游戲體驗(yàn)。
朱峰社區(qū)網(wǎng)頁(yè)版(手機(jī)掃描-分享-添加到屏幕)
朱峰社區(qū)微信公眾號(hào)(微信掃一掃-關(guān)注)
未知用戶
2005-2025 朱峰社區(qū) 版權(quán)所有 遼ICP備2021001865號(hào)-1
2005-2025 ZhuFeng Community All Rights Reserved
VIP