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

來源:互聯網
上載者:User

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的演算法參見http://blog.sina.com.cn/s/blog_4b194f4f0100crbj.html,其中講的很好,只是注意其中關鍵的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
    程式:  
    
                                                          圖-磚塊環境中的視線追逐示範     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.