遊戲開發中的人工智能——追逐和閃躲

轉載至 閱讀筆記-遊戲開發中的人工智能-第2章-追逐和閃躲

1. 追逐/閃躲的組成

    完整追逐/閃躲由三部分組成:
   ·作出追或逃的決策判斷(在後文談論到狀態機和神經網絡時,再討論)
   ·開始追或逃(本章重點)
 ·避開障礙物(第五章和第六章,再討論)
2. 基本追逐和閃躲

    假設:追逐者座標(predatorX, predatorY),閃躲者座標(preyX,preyY) 
   連續環境的基本追逐代碼

if(predatorX > preyX) predatorX--;
else if(predatorX < preyX) predatorX++
if(predatorY > preyY) predatorY--; 
else if(predatorY < preyY) predatorY++


連續環境的基本閃躲代碼

if(preyX > predatorX) preyX++;
else if(preyX < predatorX) preyX--;
if(preyY > predatorY) preyY++; 
else if(preyY < predatorY) preyY--;


磚塊環境的基本追逐/閃躲代碼與連續環境的十分類似,這裏忽略。

3. 視線追逐
3.1 磚塊環境中,爲什麼要視線追逐

   
                          圖-磚塊環境中的簡單追逐和視線追逐

    左邊的是簡單追逐的圖像,右邊的是視線追逐的圖像。
    簡單追逐算出來的肯定是最短的路徑,但是不一定能夠求得視覺上的直線,而直線追逐在視覺上會好很多。
    另外,如果有一羣攻擊者往玩家處聚攏時,簡單追逐會使得,在以目標爲遠點的座標系中,他們沿着對角線走到距離最近的座標軸,然後再沿着該座標軸走向目標。這樣就相當於讓他們排成一個縱隊發起攻擊。更加合理的做法是,分別從不同方向向目標逼近。

3.2 磚塊環境中,如何實現視線追逐
    書中使用的是所謂的Bresenham(佈雷森漢姆直線算法)算法,該算法是在圖素環境中畫線最有效的方法之一。最原始的Bresenham需要除法計算斜率,但是簡化版本的Bresenham,利用乘法避免了減法的應用。
    首先,Bresenham確實是比較好的算法,因爲它能夠保證整條路徑的近似在一條直線上。而不簡單的是把兩種步子均勻化,可以說Breseham更具有大局觀。
    Bresenham的算法參見其中講的很好,只是注意其中關鍵的d-1的部分,其實是因爲向右上方移動了,y座標加1,所以需要減1。把其中的公式乘以Dx,就能得到不需要除法的推導過程了。 
 3.2 連續環境中的視線追逐
    這一小節討論的連續環境中的視線追逐是最簡單的追逐算法,不過考慮了追逐者得移動不僅有線速度,還有角速度。算法思路就是,首先根據角速度把方向轉到視線方向,然後向目標追過去。這一節中的更多的是介紹全局座標系統和局部座標系統。

        
                                                      圖-座標系統

     局部座標系統怎麼構造呢,即局部構造系統的x軸,y軸方向怎麼確定的呢。其實就是認爲追逐者當前的移動方向是y軸的正方向(當前追逐者靜止咋辦呢?這個還不知道),x軸正方向是y軸正方向逆時針旋轉90度得到。座標轉化關鍵是那個夾角。根據上面的公式,把追逐者的全局座標(X',Y')和局部座標(0,0)帶入,就能算出來夾角的餘弦和正弦值了。實際上,使用局部座標系,是因爲有現成的函數可以幫助座標進行座標系轉化,而座標轉化後,使用起來更加方便了。從下面代碼中也能發現,即在判斷向左轉還是向右轉的時候,只需要判斷視線向量的x座標的正負即可,當然這裏的方便性與前面局部座標轉化的參數有很大關係即-Predator.fOrientation,具體的還不清楚,沒接觸過VRotate2D這個函數。

void DoLineOfSightChase(void)
{
  Vector u,v; // u追逐者向量,v獵物向量
  bool left = false; // 是否需要向左轉
  bool right = false; // 是否需要向右轉 
  u = VRotate2D(-Predator.fOrientation,
  Prey.vPosition-Predator.vPosition) // 視線在局部座標系中的向量
  u.Normalize(); // 歸一劃
  if(u.x < -_TOL) // 判斷轉動的方向
    left = true;
  else if(u.x > _TOL)
    right = true; 
  Predator.SetThrusters(left, right); // 轉動
}

 

4. 攔截

    攔截算法的基本原理是能夠預測獵物未來的位置,然後直接到那個位置去,是其能和獵物同時到達同一位置。爲了找出追擊者和獵物能同時到達的點,不僅要考慮他們的移動方向,還要考慮他們的速度。其實很簡單,首先預測追擊者追到獵物的最短時間,即,靠攏時間=相對位移/相對速度,如果追擊者不能改變方向的話,靠攏時間可能不存在,比如相對位移與相對速度方向相反,這就永遠都不可能靠攏,這一小節的最後對這種情況進行了簡單說明。有了靠攏時間,就能根據獵物的速度和初始位移,預測到其在靠攏時間後的位置,這樣追擊者只有根據這個位置,採用前面的視線法追擊這個位置就好了。
   這個攔截算法對嗎?感覺還是有問題,根據書中說法,獵物和追逐者的速度向量和位移向量都是固定的,因爲靠攏時間的計算,需要相對位移和相對速度。但是如果這些都是固定的話,很容易得到兩者很可能不會相遇的問題。更近合理的解釋應該是獵物的速度向量和初始位置向量固定,追逐者的初始位置和速度大小固定,而速度方向不固定,這樣通過調整方向來達到攔截的作用。計算可以採用靠攏時間的方法,不過是一個方程。
5. 總結
    這一章給出的還是一些基礎方法,第5章還會說明利用勢函數進行追逐或閃躲。   

6. 實踐

    附件中是我自己實現的磚塊環境中的視線追逐,其中有三個算法可選,第一個是基本方法,第二個是bresenham方法,第三個是用除法和取模運算視線的方法。後兩種方法在一些情況下很很相似,當然也有不同的,個人感覺還是bresenham更好一些,畢竟有理論支持。
    磚塊環境中的追逐演示程序:http://files.cnblogs.com/pangxiaodong/chasing.swf
    程序截圖:  
    
                                                          圖-磚塊環境中的視線追逐演示   

 

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