追跡と逃避 - fc2tmhrst.web.fc2.com/game2.pdf追跡と逃避とは...
TRANSCRIPT
2章
追跡と逃避
追跡と逃避とは
● この章ではゲームの共通課題である
追跡と逃避について見ていく● コンピュータ制御のキャラクターがプレーヤーの操作する
キャラクターを追いかけたり、逆に逃げたりそういったことである
● 追跡と逃避の問題は2つの要素があり、ある意味もう1つ存在している
・追跡や逃避を開始するための決断に関すること
・追跡や逃避を演出すること
・障害物を回避すること
この章では2つめの演出することを取り上げ
いくつかの追跡手法と逃避手法を
最も基本的なものから順番に見ていく
基本的な追跡と逃避● 追跡の場合
プレデター(攻撃者)とターゲット(標的)の座標をそれぞれ求め、座標の差を少しずつ縮めるようなゲームループをかけて、プレデターの座標を更新していくif(predatorX > preyX) predatorX--;
else if(predatorX < preyX) predatorX++;
if(predatorY > preyY) predatorY--;
else if(predatorX < preyY) predatorY++;
この考えを使いインクリメントとデクリメントを
逆にすると逃避を実装することができる
● タイルベースのゲームゲームの領域が正方形や六角形の形をした個々のタイルに分かれ、プレーヤーの位置はそうしたタイルの1つに固定される。移動はタイル単位で行われ、プレーヤーは好きな方向へ自由に進むことができる
● 連続動作環境位置は浮動小数点座標によって表される。このため、ゲーム領域の任意の位置を表すことができ、プレーヤーは好きな方向へ自由に進むことができる。
先のアルゴリズムはタイルベースか連続動作かに
関わらず適用することができる
タイル環境での基本的な追跡
○がプレーヤー◎がトロールとして
トロールがプレーヤーを追いかけるときの経路
基本的な追跡の問題点
● トロールの座標の1つ(この場合は水平座標)がプレーヤーの座標と等しくなるまで、プレーヤーに向かって対角線上を移動する。その後トロールはもう1つの座標軸(この場合は垂直座標軸)に沿って、プレーヤーに向かって前進させる。
→ 上下左右斜めの8方向に目標が
いないとまっすぐ行けない
→ 複数のトロールの群れなどプレデターの集団がプレーヤーの周 りに集まってくるとプレデター全員がターゲットから一番近い 軸に向かって対角線上に進み、それから軸に沿って向かう
これではプレデターの集団が一列縦隊でやってくることになる
LOS追跡
照準(Line-of-Sight: LOS)法
要はプレデターを直線的にターゲットに向かわせること
プレデターは常にターゲットの現在位置に向かってまっすぐに移動する注:ターゲットが動いている場合は経路が直線であるとは限らない
詳しく!
● xを1ずつ増やしてその分yを少数分増やしていけばいいじゃん!(x,y逆もまたしかり)
注:タイル環境に少数はない
● xが1増えるとyは(y2-y1)/(x2-x1)だけ増える
↑
傾きだよ
傾きはxが1増えた時yはどれだけ増えるか
ブレゼンハムアルゴリズム
● ピクセルベースのLOS追跡するためのアルゴリズム
簡単に言うと
プレーヤーとトロールの座標を確認して
x座標の差とy座標の差どっちが長いか場合分け
x座標の差のほうが長かったとして
xが1プラスされた時のyの上がり具合を計算
この場合yの上がり具合は少数になる
yの上がり具合は一定に達したらy++する
詳しく!(草案1)
hh=y2-y1 , ww=x2-x1 とするしかしhh/wwは小数演算だから誤差でまくり
詳しく!(草案2)
割り算をなくして整数演算のみとして誤差をなくすe+=hh/ww; の両辺にwwをかけてあげる
連続動作環境でのLOS追跡シナリオは以下の通り
プレーヤーは推力で船を前進させて操舵力で方向転換する、コンピュータ側の船も同じ仕組み。プレーヤーがどこに移動してもコンピュータに後を追わせるようにする。コンピュータはプレデター。プレデターが知っている情報はプレーヤー(ターゲット)の現在位置と自分の現在位置だけ
簡単な流れプレデターの直線上よりも右にいたら右に舵をとり左にいたら左に舵をとる
LOS追跡関数
● void DoLineOfSightChase(void){
Vector 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); // 実際に操舵力を適用する
}
● u=VRotate2D(-Predator.fOrientation,
(Prey.vPosition –Predator.vPosition));
この行のコードはプレデターからターゲットへのLOSを計算しています。
実のところこの行はLOSを計算するだけでなく、プレデターからターゲット間の
相対位置ベクトルを計算し、(Prey.vPosition – Predator.vPosition)の部分で
地球固定座標を計算し、
その結果として生じたベクトルを関数VRotate2Dに渡して、
プレデターの船体固定座標に変換する。
VRotate2Dに地球固定座標系とそれに対する船体固定座標系の向きを与えると、
VRotate2Dは標準の座標系変換を実行します
これでプレデターからターゲットへ向かうベクトルが得られる
● u=VRotate2D(-Predator.fOrientation, (Prey.vPosition – Predator.vPosition)); とは
1 2 3
1 : プレデターの向き
2 : プレイヤー(ターゲット)の位置
3 : プレデターの位置
2 ー 3で 地球固定座標を計算
(プレデターから見たターゲットの向き)
VRotate2D関数でプレデターの船体固定座標に変換する
そしてターゲットがプレデターの右左前にいるか確認
わかりやすく図で書いてみます
地球固定座標は東西南北が固定されている船体固定座標はオブジェクトに固定された座標
船の向きに対して9時の方向とかいうじゃないですか
● 今のやり方だとプレデターが常にターゲットをまっすぐ捉えるという点では効果的
● しかし欠点もありターゲットにまっすぐに進むことが必ずしも最短距離ではないということ
次はターゲットの移動先を予想して追撃するアルゴリズムです
追撃ここでは最終的に
ターゲットが向かう先を予想して
予想した場所に向かうようにする
このアルゴリズムついて● プレデターとターゲットが鉢合わせするには
それらの相対速度を考慮しなければならない
なぜならば、もし戦闘機のロケットだったら
早くたどり着いても待ち伏せができない、など● なのでターゲットや自分自身の現在の速度、
スピードと方向も考慮しなければならない● この情報はいずれ到着するであろうポイントを
予測するために使う
相対速度とは
● 運動している物体を、運動している(または静止している)観測者が見るときの速度
例
→方向に 1の速さで移動しているA
2の速さで移動しているB
静止しているCがいたとして● Cから見たらBは2の速さで移動しているように見えるが
Aから見たらBは1の速さで移動しているように見える
流れ(わかりやすく逆順)
● 最終的にはターゲットの平均移動距離を求める
St=Sprye(ターゲット位置) + (Vprey(ターゲットのベクトル))(tc)
それを求めるためのものを以下を書いていく
● プレデターとターゲット間の相対速度で移動する間に接近する範囲に等しい距離の移動にかかる平均時間を求める
tc = |Sr(相対距離)| / |Vr(相対速度)|
● プレデターとターゲット間の相対距離
(ターゲットの現在位置とプレデターの現在位置のベクトルの差に相当)
Sr = Sprye – Spredator
● 相対速度、単純に言うと
ターゲットの速度とプレデターの速度のベクトルの差
Vr = Vprey - Vpredator
● St=Sprye+(Vprey)(tc)
tc(時間がわかったら)ターゲットがtc時間後にどこにいるか予測することができる
ターゲットの現在位置はSpreyで、Vpreyの速さで移動している
速度に時間をかけると平均移動距離が得られるので、
ターゲットがtc時間後にVpreyの速さで移動する距離を計算し、それを現在位置に足せば、予想位置をつくりだせる
プログラム (LOSのプログラムに赤を追加、変更した)
void DoLineOfSightChase(void){
Vector u,v; bool left = false; bool right=false;
Vector Vr, Sr, St ;
Double tc ;
Vr=Prey.vVelocity-Predator.vVelocity;
Sr=Prey.vPosition-Predator.vPosition;
tc=Sr.Magnitude()/Vr.Magnitude();
St=Prey.vPosition+(Preu.vVelocity*tc);
u=VRotate2D(-Predator.fOrientation, (St – Predator.vPosition));
u.Normalize();
if(u.x < -_TOL) left = true;
else if(u.x > _TOL) right = true;
predator.SetThrusters(left, right);
}
問題点
追撃を実行できない場合が当然ある● プレデターがターゲットよりも遅い● 同じ速度で一直線上に並んでしまった● プレデターがターゲットの前方を行き、ター
ゲットと同じかそれ以上の速度で移動したら両者が決して鉢合わせすることのない前方の追撃ポイントが予想される
問題点
追撃を実行できない場合が当然ある● プレデターがターゲットよりも遅い● 同じ速度で一直線上に並んでしまった● プレデターがターゲットの前方を行き、ター
ゲットと同じかそれ以上の速度で移動したら両者が決して鉢合わせすることのない前方の追撃ポイントが予想される
終わり
● この章では実際の追跡と逃避の実行を、タイル環境と連続動作環境での基本の追跡、LOS追跡、追撃という観点から説明した
● この手法はキャラクターに知性があるように錯覚を生みます
参考サイト(本)、画像引用
● ゲーム開発者のためのAI入門David M.Bourg
Glenn Seemann 著● 伝説のお茶の間
http://dencha.ojaru.jp/programs_07/pg_graphic_07.html