日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Roguelike游戏的视野算法

發布時間:2024/8/26 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Roguelike游戏的视野算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介

實現Roguelike的一項任務是弄清楚如何計算玩家或怪物的可見區域。現有的算法很多,但是都存在缺陷,因此我著手開發一種新的算法,該算法對我來說是快速,準確和美觀的。盡管我沒有創建理想的算法,但我仍然認為我的算法是對其他算法的改進。

可見區域(視野/ field of view / FOV),判斷單位是否可以看到地形的某個部分。這里假設地牢是很常見的基于tiles的類型。玩家是否可以“看到tile”(視線/ line of sight / LOS)有時與玩家是否可以“看到tile中的怪物”有所不同,也不同于他是否可以使用遠程武器或咒語”瞄準該怪物“(瞄準線/ line of targeting / LOT)。

理想的算法屬性

接下來首先描述視野算法一些常見而有用的特征,然后說明為什么大多數現有算法缺少這些特征中的一個或多個。
?

  • 對稱性(Symmetry): 如果站在tile A上可以看到tile B,那么站在tile B上就應該能夠看到tile A。而且視野不對稱通常會導致戰術性和公平性變差(當LOS與LOT相同)。當然如果游戲是刻意造成不對稱的話是例外。
  • 墻壁擴展(Expansive Walls):站在沒有凹陷的大房間時,你可以看到房間里所有的墻;而站在長走廊時,您可以看到走廊兩側所有的墻。盡管它很少影響游戲玩法,但如果算法不具有此屬性,看起來就會很丑,并且會使探索變得乏味。
  • 擴大柱子陰影: 當視線被柱子遮擋時,柱子應以扇形投射陰影。這通??梢蕴峁└邞鹦g性的玩法:更容易隱藏,伏擊和逃脫。但是許多roguelike根本沒有柱子,這個屬性就跟他們沒啥關系了。
  • 沒有盲角: 在拐角處可以在看到至少兩個tile。因此,如果沿拐角對角移動,你就不會發現自己旁邊突然出現之前看不見的怪物。這也意味著可以在進入大廳之前看到兩側至少兩個tile。大多數情況下這都是可取的,如果玩家走過每個角落都必須小心翼翼就有些乏味了。一些算法允許拐角處可以看到無限遠,也算保護玩家免受遠程武器的傷害。
  • 沒有偽影(Artifacts): 盡管對于視野算法而言什么是“正確”有討論空間,但是算法至少應該做到本份。意思是算法應該定義如同現實世界的幾何圖形并準確地模擬光傳播。偽影的意思是有些算法根本不符合現實世界的幾何體,是使用近似而非精確的數學來實現的,并且存在bug。
  • 效率: 算法不應該花費很長時間,并且最好避免重復測試同一個tile。



現有算法

不算詳盡,涵蓋了最常用的算法。

光線投射(Ray casting)

優點: 簡單。相當快。擴大柱子陰影。良好的光影平衡。沒有盲角。

缺點:?不對稱。沒有墻壁擴展。間隙很多(可見性不連續)。

這算法會將光線從玩家投射到地圖邊緣上的每個點(或視野半徑邊緣的每個點)。光線用簡單的畫線算法投射(如Bresenham'的算法[0]),一碰到墻就會停止。光線投射是最簡單而且速度很快的算法,但是有許多問題。
?

  • 不對稱。 Bresenham的算法是不對稱的,但是即使你用對稱的畫線算法,結果還是不對稱,因為在替換位置時線條的端點不會簡單地反轉。
  • 在可見點和陰影上也都存在間隙,并且很古怪。后期處理可以修復間隙,可以消除難看的偽影,但會減慢速度,并且無法解決其他問題。
  • 會多次重復測試tile,效率有些低下,但是由于簡單性,最終還是非???#xff0c;尤其是在較小的視線范圍。



光線投射以最快的算法聞名,但是這主要是由于較復雜的算法普遍實現的較差。實現良好的陰影投射算法永遠比光線投射更勝一籌。但如果撇開間隙和不對稱,僅考慮光線和陰影的形狀,我認為光線投射比陰影投射和菱形墻等更復雜的算法產生更好的結果。而且,隨著視線半徑的減小,大多數問題都變得沒那么嚴重了;如果圓形視線半徑為4或更小,它其實可以很好地工作,不需要進行后期處理(盡管還是有些一些偽影)。
?




陰影投射(點對tile或點對點)( Shadow casting)

優點:快。擴大柱子陰影。墻壁擴展。連續的可見性。

缺點:對角線視野比平常窄得多。盲角。光束通過門擴展得太多。不對稱。消除偽影的方法復雜(nontrivial)。

陰影投射是從玩家向外投射扇形光線的技術。當一個扇區碰到墻時,該扇區可能會減小角度或分成兩個扇區,然后分別進行處理。實現方式各不相同,但是好的實現只會訪問每個tile一次或接近一次,并且每個tile僅進行少量且大致恒定的工作。如果實現得當,陰影投射會成為最快的算法之一;但在實現不佳的情況下,它在走廊拐角和具有許多小障礙物的開放區域中的速度可能較慢。 “陰影投射”有點用詞不當,因為實際投射的是光,但我還是會用這詞,因為“Light casting”跟“Ray casting”有些像。在我見過的所有case,陰影投射都使用正方形的tile,但是其他形狀也是可能的。

在通常的實現中游戲賬號拍賣,如果從玩家的tile中心到目標tile的任何部分之間都存在一條暢通的線條,則tile為可見。這是一個示例,說明陰影投射如何針對單個八分圓扇形進行工作。 (并非所有實現都可以在八分圓中工作)

↑一個45度的扇形投影到了45度八分圓處,綠線為頂部,藍線為底部。顯示的分數是直線的斜率,數值永遠是0到1之間,帶有圓圈的象限被視為可見。然后,算法從發射點向外工作,對于每一列,它從扇區內的tile從上倒下掃。如果找到從透明到不透明的分界,則調整扇區至不包含該不透明。

↑已經掃描了前三列,并且在第四列中發現了分界(不透明>>透明),因此向下調整了頂部。

↑找到分界(透明>>不透明),因此向上調整了底部。

↑在第五列中找到了兩種分界,因此將扇區一分為二,每個扇區獨立繼續。當算法達到最大視距或所有扇區變空(底部斜率>頂部斜率),算法將停止。

陰影投射的一些功能和問題(使用普通的正方形tile)。


上面就是不對稱性會減弱戰術性的一個原因。如果可以瞄準看到的東西(LOS==LOT),那么走廊中間會比拐角具有優勢,盡管拐角看上去更隱蔽。拐角的單位可以在不見攻擊者的情況下被射殺。像這樣的不對等就是對稱性是一種理想特性的原因。但是,如果上述不對稱性被逆轉,則實際上它可能是優于對稱算法:可以使拐角真的更加隱蔽,使游戲更具戰術性(更佳的可能是LOS對稱,而LOT不對稱)。有一種稱為“反向陰影投射”的算法可以逆轉不對稱性,但通??雌饋砀畈⑶疫\行更慢。

不過,對陰影投射代碼進行小的修改就足以使其對稱。這是通過更改算法來實現的,因此只有在從玩家的tile中心到目標tile中心(而不是目標tile的任何部分)有一條暢通無阻的線條時,它才判定tile可見。如下所示,這可以解決一些問題但會導致其他問題。
?




【key point is the strategy of how to determine a tile is visible: just need the sector cover the tile? or need to cover the center point? or cover a certain percentage of area? 發射點固定了在格子中央,但是被觀察的一方則是視線稍為蹭到格子都算看見,因此不對稱】

菱形墻(Diamond walls)(點對tile或點對點)

優點:相當快。擴大支柱陰影。墻壁擴展。沒有盲角??梢娦曰具B續。

缺點:光束通過門會擴展太多。不對稱;小更改即可解決,但相對會丟失墻壁擴展并導致不連續

就像陰影投射一樣,如果從玩家tile的中心到目標tile的任何部分都存在一條暢通無阻的線條,則tile為可見,但是它會將墻視為菱形。這比標準陰影投射有更大的拐角可視距離空間,更好地窺視各個角落。但它本身會帶來一些問題,主要是有點過于寬容,使太多的tile可見,盡管如此,這似乎也是對標準陰影投射的一種改進。 (我稍為修改陰影投射代碼來實現)至于效率,它比普通陰影投射要慢一些,因為它需要為每個tile做更多的工作,但是仍然相當快。

將墻視為菱形實際上在roguelikes中很有用。原因是大多數roguelikes允許單位在對角相鄰的墻之間移動,如果墻是正方形的,它們的角就會碰觸,沒有空間。如下圖所示。使游戲的物理學更加一致【指可移動范圍與可視范圍有一致性? 】。菱形墻還可以使拐角處的視野更好,通常是好事。
?


不幸的是,菱形墻存在理論上的問題。與菱形成切線視之為不相交;零寬度的光束仍然能照亮tile。這樣可以在拐角處提供更好的視野,但在以下情況下使單位可以透視墻壁。應該要在特殊情況下禁止透視墻壁,但會造成游戲物理在某些情況下不一致。
?

菱墻的一些功能和問題

簡單更改足以將菱墻算法轉換為對稱算法,但有與標準陰影投射相同的優缺點




半寬墻(Half-width walls)

優缺點: 與菱形墻相同,但更寬容,但速度稍慢。

另一個類似于菱形墻的想法,分別是它使用的墻是通常寬度的一半。它也解決了在對角tile之間的視野問題,但在我看來過于寬容,感覺比菱形墻更差。由于并非每個墻都是相同形狀,因此實施速度也稍慢。 (形狀取決于是否有相鄰的墻要連接。)我姑且實現了這算法,但實在不值得花這氣力。

寬容的FOV(Permissive field of view)(tile to tile)

優點: 對稱。沒有盲角。墻壁擴展。連續可見性。

缺點: 慢。沒有擴大的支柱陰影。拐角處的可見性可能過多。

如果從玩家tile的任何部分到目標tile的任何部分之間都存在一條暢通無阻的線條,則視tile為可見。此方法的大多數實現都是估算,例如僅對對角進行相互測試【并不是任何部分,而是只有目標和自己的四個邊角點】,在某些情況下會失敗。精準的實現可以適應所有情況,但是慢。我提供了一個精確的實現(改編自Jonathon Duerig[1])。該算法的主要特征是對稱,并且在拐角可以看很遠,但對我而言有些太寬容了,所以我沒有很努力優化這算法。可以說如果所有生物的視線半徑都較短,那這算法感覺上和實際上都會更好。

有一個這算法的版本,可以在運行時更改寬容度(permissivity)。我玩了一下,把通常寬容度減半看上去很不錯,但就不再對稱了,而且我想有個更快的算法anyway。
?




Digital FOV(菱到菱)

優點和缺點: 與寬容FOV算法相同。

Digital FOV將每個tile都視為菱形,并且如果從玩家菱形的任何部分到目標菱形的任何部分都存在一條暢通的線條,則認為該tile可見。結果,它甚至比允寬容FOV稍微寬容一些(因為墻壁的障礙性更小) 。在其他方面所有相同的特征和缺點一樣,但更慢。這個想法是基于的相當笨拙的digital straight line segments概念,我沒有費心實現這個。 One interesting feature of the algorithm is that the knowledge of the digital line segment from a line-of-sight calculation allows easy tracing of a projectile path through space without hitting any walls, even down somewhat twisted tunnels (such as the Kuo corridor above) 。但是復雜性似乎超過了收益。

我的算法

以上沒有一個令我滿意。首先除了ray casting之外,要么太寬容,要么太過局限,有時兩者都有。而且ray casting有太多偽影,用不來。下面我打算修復的問題和我想要的功能。


?

  • 沒大多數其他算法那么寬松
  • 比其他算法對稱
  • 能夠做到對稱(至少跟不能穿墻的怪物相對)而不會損失墻壁擴展
  • 良好的拐角視野,但不能太好
  • 良好的狹窄的空間視野,而不會損失墻壁擴展
  • 比其他算法更少陰影間隙
  • 與菱形墻相當的效率
  • 沒有死角
  • 沒有偽影
  • 一致的物理



為此,我會將地牢的幾何結構像下圖一樣表示。 (注意:圖2中的兩個角應該是斜角的。我畫錯了。不過,這圖說明了內部正方形的用途。)
?


1.? ?? ???如果一個墻tile的兩個相鄰都不是墻,則將該角切成斜角。

2.? ?? ???如果光束與墻的形狀相交,則墻tile可見;

3.? ?? ???如果光束與中心正方形(size最大為tile的1/2)相交,則空白tile可見。

4.? ?? ???與圖形成切線不算相交,并且零寬度的扇形無法照亮。

帶有斜角的實心墻允許在拐角處窺視并可以看到對角空間,同時避免了鉆石墻的理論問題。除非光線在中心附近通過,否則不要看見空白tile,這應該會沒那么寬容,減少陰影間隙,減少不對稱性并搞定光線通過窄空間的行為。

圖2說明了光線穿過狹窄空間的問題。不管沿著隧道走多遠,扇形都會在離開走廊時打開,而其他算法會立即照亮出口上下方的tile。支柱也是同理,就像走廊的墻壁一樣,扇形在穿過支柱之間后打開。不照亮光線照射的比較少的tile就可以避免這種情況,還能讓柱子有效的阻擋光線。因為能防止小束光線照亮tile,應該還能減少陰影間隙。

可以通過調整斜角的角度和內部正方形的大小來調整寬容度??梢允褂谜叫我酝獾钠渌螤?#xff0c;但是起碼要可以放在tile中的最大菱形區域(就是不應該比柱子大)。用正方形的話,最大值為tile長寬的1/2,測試表明這樣的結果最好。使用3/8的寬度,可以在長走廊內和拐角的單位之間對稱的互望,很不錯,但在其他情況感覺有些局限(尤其是在有許多柱子的環境下),所以我會用1 /2。實際的實現使用了修改的陰影投射算法,只要我能避免在每個tile上做太多工作就能有不錯的性能。
?

不對稱版本的例子【1/2大小】


我的算法有兩個對稱版本:一個是完全對稱的版本,另一個是基本對稱的版本(就是單位之間是對稱但穿墻單位另算)。
?


基本對稱的版本。對稱時,它不會遇到其他算法的相同問題。最重要的是不會失去墻壁擴展。這是兩個對稱版本中較好的,除非你需要與穿墻單位也對稱
?


完全對稱版本。它與所有穿墻單位都有對稱性,但沒了了墻壁擴展;雖然擴展程度比大多數算法更好(寬容FOV除外)。與對稱的菱形墻非常相似但不相同

總結

以上是生活随笔為你收集整理的Roguelike游戏的视野算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。