關於帝國2中的尋路和行軍算法

       一提起遊戲中的尋路,很多人就會想起A*算法. 的確,A*無疑是當前用的最多也是最先進的算法,在比較簡單的地圖上它的速度非常快,能很快找到最短路徑(確切說是時間代價最小路徑),而且使用A*算法可以很方便地控制搜索規模以防止程序堵塞.
       關於A*算法的文章已經很多了,上google隨便一搜都能找到,但是國內網友原創的似乎不是很多,建議英文不太差的愛好者上國外的網站查找相關資料,比如http://www-cs-students.stanford.edu/~amitp/gameprog.html.
       A*算法本身表述起來很簡單,程序寫起來也不難,兩三百行輕鬆搞定.關鍵是要在代碼優化上下功夫,這就很考驗程序員的算法功底了.基本的思路一般都是以空間(也就是內存的佔用)換取時間(搜索速度),另外還有一些地圖預處理(包括人工的預處理和用程序預處理)的技術比如多級地圖精度或者地圖分區域搜索等等,但我今天要討論的不是A*算法本身,關於這方面有興趣的網友可以另外和我交流.
       不管怎麼優化,尋路總是一項非常費時的工作,並且工作量和地圖的大小基本成線性關係(不限制搜索規模的前提下).現在的rts往往允許每方生產200個以上的移動單位,同時可能會有大量的移動物體需要尋路.如果同時選定100個單位點並向他們下達遠程行軍命令,假設每次尋路需要5ms(在複雜地圖上,這個數值一點都不誇張,我是說在我的機器上),那麼就需要0.5秒的時間在尋路上,也就是說整個遊戲將因此停頓0.5秒.你受的了麼?
       呵呵,俺們程序員是不會讓這種情況出現地,通常有幾種方法來避免尋路運算導致程序堵塞:

       1.限制同時選定的移動單位個數
                帝國2裏面,這個限制是40個.當然這樣一來,同一個編隊裏的人數就不可能超過40了.這一方面是爲了減少尋路耗時,同時可能也有別的考慮,我能想到的是同時控制過多的單位攻擊同一個目標可能效率會很低.我不知道其它rts遊戲是否也有類似的限制,但是如果採用了下文所述的第2,第3種方案的話,這個限制就顯得不那麼重要了.


       2.把尋路工作在時間上分散進行.
               可以估計一下每次尋路所花的時間,限制每個"回合"(就是遊戲的一幀)最多讓多少個單位尋路,其它的等下一個回合再說.這樣遊戲就不會停頓,但是缺點是可能會看到所有人不是同時動身,而是先後開始移動.網上有文章說爲了避免選中的單位"發楞"而讓玩家以爲出了什麼問題,可以讓一時來不及尋路的單位花很少的時間憑"直覺"決定一個方向(通常就是目標所在的直線方向了)先走再說,等輪到自己尋路以後再改回來.這也是個辦法,因爲"直覺"的方向在大多數情況下就是正確的方向.但是據我觀察在帝國2裏面沒有用到這個小伎倆,後面會說到.
       

       3.這個是最實惠最有效的,就是距離相近的單位公用一條路徑.所謂"相近"一般來說以互相都在視野之內爲限
                玩過帝國2的人都會感嘆其中各種漂亮的陣型,連行軍的時候都要擺的整整齊齊的一個方陣(當然前提是在空地上跑).即使你故意挨個把他們分散了(不能距離太遠),同時選中他們並點取一個目的地以後,他們也會在行進中慢慢的自動靠攏,不一會又排成方陣了.而且,不管你讓他們去地圖的什麼地方,他們都會全體立即響應,而不會出現上一條所說的那種停頓或者先後啓動,這是怎麼回事呢?聰明的你一定能想到,只要讓一個人帶隊尋路,其他人跟着就行了.對!就是這麼回事.讓一個單位尋路而其餘的單位跟隨,這比讓每個單位單獨尋路要快的多了.這個帶隊的移動單位稱之爲"尋路兵"
              說到這裏要提到帝國2的一個不知能不能算的bug,比如有一條很長的小河,你有一幫人馬,一部分在河左邊,另一部分在河右邊,他們挨的很近,雖然隔着河.現在你畫個框把他們同時選定,比如讓他們都到河左邊.因爲他們相互都看得見,於是程序就選了一個人帶路(怎麼選的我不太清楚).這時候可能出現兩種情況:一種是尋路兵在河左邊,於是他帶着河左邊的衆弟兄朝目的地去了,河右邊的一干人很想跟着(根據程序的設定,他們不需要自己尋路)但是無奈隔着河過不去,在河邊彷徨了一會(帝國2的算法據我觀察在原定路線不能走的情況下會先嚐試從兩邊繞行,當然繞行的範圍是有限的,如果發現繞不過去才重新尋路),當對岸的人馬走出他們視野的時候他們纔想起來可以自己尋路,於是順着河邊繞過去了.另一種情況更搞笑,就是系統選出的尋路兵在河右邊.本來河左邊的人是離目的地很近的,但是他們不管,非要隔着河緊跟着那邊的尋路兵,直到在河流的盡頭與尋路兵所在的部隊匯合以後,才一起排着方陣走向目的地.
             關於帝國2中尋路兵的確定,就是在一隊人馬中選哪個來帶頭尋路,我還沒有什麼頭緒.
             另外,當尋路兵死亡(按了del鍵,呵呵),或者被指定了另外的目的地時,剩下的單位中會重新產生一個尋路兵,重新尋路.
     

       奇怪的是,帝國2中的農民的移動卻沒有采用尋路兵策略,即使彼此很靠近的一堆農民,他們移動時也不會排成方陣,而且點選目標的一瞬間會出現上文第2條所述的那種停頓,即有的農民先啓動,有些後啓動.在我的CII533的機器上,40個農民,huge空白地圖從一頭到另一頭,最快啓動的農民和最慢的大概相差0.5秒,延遲已經很明顯了.我不太明白爲什麼這麼設計,可能是農民行爲的特殊性上的考慮.


        另外關於帝國2要說明的是它沒有類似紅警裏面的同一方的"讓路"算法,如果你讓幾個人把一個咽喉要道堵住,然後控制另一隊人試圖通過這個關口,可以看出尋路的時候算法沒有考慮堵住關口的單位,因爲你控制的人馬徑直就朝這個關口過來了,就像以爲它是通的一樣(這本身是合理的,因爲他們不知道擋路者什麼時候會離開),到了跟前一看堵住了,左邊右邊的繞了兩下沒繞過去就回頭找另一條路去了.擋路的人根本無動於衷.
 
      現在的rts正在向網絡化發展,在地圖越來越大,移動單位越來越多的情況下,一方面是路徑搜索算法本身的效率,另外行軍算法(例如陣型,讓路等等)的效率和巧妙程度也是個很值得研究的課題.
 
      呵呵,居然寫了這麼多.我有時間的話還會研究一下其它遊戲的尋路特點,如果有同好者歡迎和我交流.本文如果要轉載,請註明是轉載.謝謝!
 
cooker
03_05_16

發佈了31 篇原創文章 · 獲贊 2 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章