RTS製作日記。その15

アバター
MNS
記事: 35
登録日時: 15年前

RTS製作日記。その15

投稿記事 by MNS » 14年前

*壁を回避する動き


おまけみたいな感じですが、壁の回避行動をつけます。
現状、ユニットが壁を突き抜けるように移動することは有り得ません。
(壁が存在するところにグラフのノードが存在しないからです)
ただ、ユニットが重ならないよう押し合う処理があるため、
壁のほうに押されたユニットが、壁にめり込むないしは突き抜けることがあります。
awall.png
awall.png (1.2 KiB) 閲覧数: 86 回
これを回避するためには、移動先に壁があるかどうか確かめ、
このまま進んだら当たるな・・・という場合に、それを避けるような移動を行う必要があります。

CODE:

//基準線の長さ
const double LEN = 5.0;

//壁回避
Vec2D	MotionManager::AvoidWall()
{
	Vec2D Force;

	//壁に衝突しそうかを判断するための基準線
	// - 全面、右斜め前、左斜め前
	Vec2D V = m_pUnit->Velocity();
	Vec2D P = m_pUnit->Pos();
	Vec2D line[3] =
	{
		P + Vec2D(LEN, LEN),
		P + Vec2D(LEN*cos(+PHI/4), LEN*sin(+PHI/4)),
		P + Vec2D(LEN*cos(-PHI/4), LEN*sin(-PHI/4))
	};

	//複数の壁に衝突していることを考えて、
	//自身の座標と最も近い交点をもつ壁を回避
	Wall* closestWall = NULL;
	double distClosestWall = DBL_MAX;
	//最寄りの交点
	Vec2D closestIP;
	
	std::list& wList = WallManager::Instance().GetWallList();
	std::list::iterator it;
	Vec2D ip; //交点
	//全 基準線にたいし検証
	for(int i = 0; i From(), it->To(),
							  ip))
			{
				double dist = (ip-P).LengthSQ();
				if(dist Normal() * over.Length();
		}
	}

	return Force;
}
※補足 Wall->Normal() … 壁の法線ベクトルを取得します。
いくつかの基準線を用意します。(触覚みたいなものです)
それが壁にめりこんでいれば、そのめりこんだ分、ユニットを押し戻します。
そうすることによって、壁に距離に反比例して力が定まるので、
自然に壁を避けているように見えるはずです。

これをMotionManagerに追加し、フラグを付けて有効化すれば、
ユニットが壁にめり込むことがなくなります。
(”壁にめりこまなくなった”画像を用意するのは難しいので省きます。)
最後に編集したユーザー MNS on 2011年2月11日(金) 16:47 [ 編集 1 回目 ]

コメントはまだありません。