像阿軻(荊軻),隱刺,小丑這種從背後暴擊在代碼上是怎麼實現的?
王者榮耀荊軻改版重鑄,命名阿軻,技能全面修改,其中被動技能為從背後進攻必定暴擊,這給這個遊戲人物帶來了其他的操作性,那麼這在代碼上是如何實現的,如何判斷正面背後,從而打出暴擊
添加了另外兩個英雄,防止撕逼
這裡涉及到一個是攻擊到傷害的結算順序,另一個是單位方向的判斷。
首先底層的攻擊到傷害的結算流程里,要開放一個「準備發起攻擊」的事件入口,在「攻擊前搖」之前(即開始攻擊動畫前)。同時要在這個節點上,允許強制設定本次攻擊的暴擊與否。
那麼腳本邏輯的角度上就很簡單了:
單位進入範圍滿足條件準備發起攻擊 -&> 判斷是否在目標背後 -&> 強制設定本次攻擊為暴擊 -&> 進入前搖階段並播放暴擊動作,然後結算傷害等。
如何判斷一個單位是否在目標背後?
MOBA遊戲用於邏輯判斷的坐標軸一般是二維的,只需要取攻擊者到目標的位移向量 (目標坐標-攻擊者坐標),以及目標的面向角度(目標在Z軸上的歐拉角)。把面向角度換算為單位向量 ,然後算向量的夾角是否小於一定範圍(以夾角60度為例,相當於120度的扇形判定範圍)。這裡可以用向量點積的定義,得到夾角的cos
,
然後判斷這個 值是否大於 o 或別的你給定的值。
p.s.
針對遠程和投射物等情況,把這裡的投射物視為攻擊者進行邏輯判斷即可。
看了所有的回答,都把焦點放在了「如何判定在背後」,其實這只是一個初中算數的問題,那麼思考一個問題——這幾個人的攻擊恰好是近戰攻擊,我們是否允許設計一個英雄,他也有「任何傷害背後攻擊必爆」的特性,但是他的4個技能是:
1,向前丟出一個回力標,飛到一定距離後折返,類似LoL的輪子媽的Q,策劃要求「如果背後命中敵人則必爆」。
2,在身邊召喚雷電球順時針環繞自己,擊中敵人後會爆炸,策劃要求「如果從背後擊中敵人則必爆」。
3,飛出魚叉,抓住一個目標並拽回,目標被拽回的路徑上的敵人碰到目標都會受到傷害,策劃要求「如果目標被拽回時,從背後撞擊了路徑上的人,則此傷害必爆」。
4,大招:在遠處召喚8道水柱,水柱順時針螺旋向中心(即釋放技能時候角色的位置)移動,對碰到的敵人造成傷害,對碰到的友軍造成治療,策劃要求「如果是從正面碰到友軍則治療必爆,如果時從背後碰到敵人則傷害必爆。」
思考一個問題——以上四個需求為什麼不可以?那麼問題來了!——這4個傷害的「背後判定」,一定與「我」(釋放這個技能的人)的位置有關嗎?所以我想說,樓上的大多是紙上談兵,那麼作為一個實際干出過數款上線並有幾款成績不錯的Moba遊戲的我就從最簡單的實現來談談這個在真實的Moba遊戲中是如何實現的。
在這個問題中,涉及到的數據以及他們的最基礎屬性:
1,CharacterObj(角色對象),有一個屬性面向(FaceDirection),為了編寫lua腳本的策劃便於理解,我們通常使用0-359的整數,描述了一個角色面向的角度,這裡還要注意一點——在很多遊戲設計的需求下,面向的角度不等於角色移動的方向的角度,你可以根據需要把面向(FaceDirection)和移動角度(MoveDirection)做一個分家,但是這個問題下,我們關注的只是FaceDirection。
2,DamageInfo(傷害信息),通常新手會認為這個是一個多餘的環節,但是如果你真的理解了我的buff機制(你可以從知乎搜索「如何設計一個易擴展的遊戲技能系統」),你會發現整個流程中這是一個必要的東西。首先我們來說DamageInfo通常包含的內容(與本次討論無關的屬性就不再這裡列出了,根據項目的實際需求擴展這個結構就行了):
1)Damage: 通常在Moba中是int,如果你還會用到金木水火土等屬性傷害,那麼可以把它定位Array,如果你是傳統頁游,那int其實很難滿足你的需求。無論如何,你需要一個地方暫時記錄這次傷害的值。
2)isHit:boolean,是否命中,是否能夠命中並不影響造成的傷害,傷害管傷害(Damage)計算值,會影響最後命中的因素非常多,所以這裡只記錄當前傷害信息能否命中。
3)isCritical:boolean,是否暴擊,同是否命中,你不應該因為暴擊了直接就把Damage進行運算,我們說DamageInfo這個信息用於最後的傷害計算,所以最後實際算傷害的時候,會根據DamageInfo.damage和DamageInfo.isCritical得出一個合適的傷害數字的。
4)degree:int,0-359,傷害來源的角度,這個角度就是當前問題的關鍵,由於遊戲中有太多的因素會產生傷害,所以每一個因素在產生傷害的時候都會有不同的賦值方式,因此這裡會涉及到另外一個課題——將傷害來源做個抽象歸類,合理的設計下應該是這樣的:
當你的遊戲依賴的邏輯對象是:
bulletObj:在Moba類遊戲中那些必定命中的、通常用於單體的技能,請記住,技能的效果未必是傷害,傷害只是效果之一,這才是對的抽象!
aoeObj:在Moba類遊戲中通常是一些範圍性技能。
buffObj:給角色添加buff的處理。
這3個邏輯對象的對應「效果」(確切的說是回調點)的函數中,可能帶有產生傷害信息的介面,由此,我們可以獲得這個DamageInfo,也正是在此時,根據遊戲的規則來賦值了這個DamageInfo.degree:
bulletObj的degree,通常等於這個bulletObj在命中時候的方向。之所以說是「通常」,因為遊戲策劃可以重新定義他的用法,下同。
aoeObj的degree,通常等於aoeObj.position到產生傷害信息的對象角色的向量的角度。
buffObj的degree,通常是0,也有用buffObj.caster(釋放這個buff的角色)當前(buffObj邏輯回調瞬間)的面向作為degree的,兩者都是科學的,取決於策劃設計需要。
實際上我們看開篇我命題設計的4個技能,他們的degree的確和「我與目標」的位置沒什麼關係,而是與「我」發出的aoe/bullet與目標的位置有關係。
也許我需要進一步的解釋一下好的傷害流程的抽象,才能讓你更明白DamageInfo的意義,那麼我們就接著說:
請注意,這個傷害流程適合於任何需要傷害邏輯的遊戲,在這裡我們穿插了對buffObj的回調點的處理,把這些處理丟給腳本也好,丟給其他程序邏輯代碼段也好,這都OK,關鍵在於——整個傷害流程是一個變化DamageInfo值的過程,最後依賴於DamageInfo的數據,我們產生了真正的傷害。事實上,很多類似「背後必爆」的處理,都是在這一段里通過buff機制來實現的。
當你理解了這個流程的時候,我想你不難寫出這樣一個buffModel(用於創建一個添加在角色身上的buffObj),偽代碼如下:
buff.id = "crit_behind";
buff.visible = false;
buff.onHit = function(buffObj, target, damageInfo, designParam) {
if (math.abs((360 + damageInfo.degree - target.faceDirection) % 360) &<= 60) {
//在邏輯的世界,命中的時候,2個點(傷害來源和挨打者)必然重合,所以我們只能認為如果2個人的面向是相向的,並且差距在一個可接受範圍內,那麼就是「背後攻擊」(因為來源會定義不同的方向,這是給來源留個活路,這裡涉及到一個邏輯架構能力)
damageInfo.isCritical = true;
}
return damageInfo;
}
就是這樣的簡單思路,很輕易的就能實現你來自任何渠道的傷害和你能想到的一切處理,比如說「來自正面的傷害會治療目標」這種,我相信聰明人看到這裡已經狠輕易就能知道怎麼做了。所以說,這個問題的根本,並不是用一個數學公式解決2個點的方向問題,而是一個邏輯抽象問題——合理的遊戲邏輯業務框架該如何設計才是問題的根本。
實際上這種遊戲里,人物的方向基本只能由移動,平A和技能改變,那麼只需要用一個矢量存一下人物的朝向。背刺發起方由於技能(平A)的關係一定朝向目標,只要算一下兩個角色的朝向矢量的點積,看正負就知道能不能發起背刺了。update:其實我不玩dota,不玩dota2,不玩lol,不玩農藥,風暴只是刷刷活動。問技能原理什麼的我也不是欽定不答,但是可不可以介紹一下說的是什麼啊qaquupdate:有人在隔壁叫板嗯。。。這是個原理性的說明,但是這個原理用到哪裡都可以。比如說放出了技能,可以用一個實體對象,然後把上面的回答的發起者全部替換成這個實體,照樣可以用。
稍微不友善一下,答題就好好答題,沒事瞎懟別人幹什麼?我這一個原理性的說明淺入淺出,你再怎麼做跑的了這個原理么?天天懟人不好,你怎麼知道人家是不是寫300的呢?
其實我更想問的是,如何做出李白部分技能不可選中的效果,哪吒乾坤天降全圖奔襲的效果,露娜大招標記無限月下連的效果,趙雲損血免傷的效果,東皇太一支配的效果,虞姬後跳免疫控制的效果,,,,,我甚至還想問,
如何做到終結造成已損失百分之14的真實效果,
閃現位移的效果,紅藍爸爸為什麼刷新,懲戒如何只打野怪不打英雄,我想問的很多很多,這些問題,應該和題主一個類型。其實我想問的是,何時才能學好編程,如何將自己的想法變成遊戲世界的現實,我的心中有無數個世界,想和我愛的人分享。
所以,我的夢想應該如何實現,這才是我想問的。兩個英雄面部向量點乘小於零且碰撞檢測到傷害就可以判斷是背部傷害
設攻擊者為atk,被攻擊者為def。先計算兩者的偏移位置矢量loc,loc = def.location - atk.location然後將矢量loc進行逆旋轉,轉換到def的本地坐標系,loc.unrotation(def.rotation)。現在我們得到了atk在def的本地坐標系中的位置,然後根據這個本地位置,用反正切就能很方便的算出:他在坐標系中,和原點的角度r,r = atan2(loc.y, loc.x)
我們做的話,伺服器會存有role的坐標、方向狀態。判斷Attack到來的角度就可以了。
保存目標位移方向或位置停止前的位移方向,若荊軻攻擊方向和前者的方向相同或角度範圍內。產生暴擊
防止撕逼,笑死我了。三個其中的隱刺並不是背後暴擊。隱刺是在背後攻擊額外增加敏捷*係數的傷害。有一個相反的鋼背獸是背面傷害減免40%,側面傷害減免20%。這幾個其實不難實現,不知道上面幾個如何寫這麼複雜。首先每個遊戲傷害流程不完全相同。不過你要知道就是在合適的時機增加傷害。在dota中的隱刺,他的傷害是優先於攻擊傷害的,先不論合理,他的實現就是在攻擊前,先判斷自己的位置跟目標直線兩點的一條向量,跟目標的正對方向的向量。兩條向量之間的夾角。在一定範圍內,則造成傷害,然後再計算普攻傷害。鋼背是在被攻擊的時候在某某範圍內減免傷害。如果是刀刀暴擊,那麼大概就是在攻擊前判斷範圍,在範圍內就把暴擊率改為100%。總的來說這個功能不難,只要是你的傷害流程規範,完美,非常好改。如果流程混亂,那麼基本就完蛋了。
算一下兩個Direction circle 的差值?
大概是:
if Dot (map getDirection [a,b])&>0
then do 背後傷害判定 else do 正常傷害判定對么??。。普攻使用投射物概念,投射物碰撞時判斷受擊部位;技能使用法術場概念,aoe判斷比較蛋疼,貌似只有小丑分身爆炸是aoe,沒有了解這個有沒有背後爆擊判定
抖個機靈一切遊戲效果都是可以用隱形的兔子實現的!
感覺這三個英雄都是普攻判定,沒什麼意思,有沒有大佬系統論述一下鋼背獸的背後/側面判定?
在每個英雄的技能腳本文件中,肯定會有一個暴露的介面onDamaged(self, target , skill ),這個介面在攻擊判定發生後觸發(也就是判斷技能命中了,但是還沒有結算傷害),此時,只需要取到self自己的朝向,target目標單位的朝向 ,判斷到這個skill是荊軻等其他英雄必定暴擊的技能,就可以算出是否必定暴擊了。
而關於技能是否命中,目標是否屬於技能釋放範圍內,這個可以放在onAttacked(self, target ,skill ) 中(判斷技能是否命中)進行判斷。
3d模型有個正方向 一般是是臉的朝向 在攻擊範圍內看一下是不是撞臉就行了
向量的點乘可以解決這個問題
2D遊戲,每個角色都保存位置坐標,
還可以保存方向向量,指向最後移動的方向,必須有這個方向,你的人物貼圖才是正確的。
計算是否背刺,根據向量角度就可以得出了,當然最好加上距離。
三維變換都有旋轉矩陣,基本上通過getrotation之類的函數就能知道角度了。看了一圈回答,都只判斷了角度,而沒有判斷位置。如果阿珂同學學了旋風斬,在她背後追擊被掃到的也會被判斷成背刺,要出bug的。
Direction = Victim.GetWorldLocation() - Instigator.GetWorldLocation()DotResult = Direction.Normalize().Dot(Victim.GetWorldRotation().Vector)If(DotResult &>=0 DotResult &< Threshold){ 背刺}elsr{other}
推薦閱讀:
※如何評價現在App Store上暢銷前10的《刀劍神域》手游《黑衣騎士》?
※如何評價『皇室戰爭』於2016年10月20日做出的平衡性調整?
※如何評價對比一下《小米槍戰》、《終結者 2:審判日》、《荒野行動》這一類手機遊戲?
※玩陰陽師迷茫了怎麼辦?
※如何評價 Lifeline 的主人公 Taylor?會產生感情嗎?