我正在使用XNA制作游戏。
我有敌人和玩家。
敌人应该逐渐转向玩家。他们应该计算出需要顺时针或逆时针旋转的方向,以最短的距离为准。
通过使用Atan2,我得到了敌人当前面对的角度和它应该面对的角度(敌人和玩家之间连线的角度)。
然而,我得到了一些奇怪的行为。像下面这种情况,敌人可能会朝着错误的方向转弯。
我的代码(如下所示)不断变长,但问题仍然存在。在游戏中克服这个问题必须很常见。有没有解决这个问题的方法?
通过使用Atan2,我得到了敌人当前面对的角度和它应该面对的角度(敌人和玩家之间连线的角度)。
然而,我得到了一些奇怪的行为。像下面这种情况,敌人可能会朝着错误的方向转弯。
我的代码(如下所示)不断变长,但问题仍然存在。在游戏中克服这个问题必须很常见。有没有解决这个问题的方法?
//this bit is just in case enemy has rotated more than 360 degrees (gets set back to 0)
if (Math.Abs(_blocklist[0]._floor.Revolutions) >= 2)
{
_blocklist[0]._floor.Rotation = 0.0f;
}
//enemy rotation in radians
float blockroat = _blocklist[0]._floor.Rotation;
// vector to player - vector to enemy
_vectToPlayer = playerpos - _blocklist[0].Centre
angletoplayer = (float)(Math.Atan2(_vectToPlayer.Y, _vectToPlayer.X));
diff = blockroat - angletoplayer;
if (diff < -Math.PI)
{
diff += (float) Math.PI;
diff = -diff;
}
else if (diff > Math.PI)
{
diff -= (float)Math.PI;
diff = -diff;
}
// if enemy angle if off by a certain amount
if (Math.Abs(diff) >_maxturn)
{
if (diff < 0)
{
//turn clockwise
_blocklist[0]._floor.Rotation += _maxturn;
}
else
{
//turn anti clockwise
_blocklist[0]._floor.Rotation -= _maxturn;
}
}
更新
最终我采用了第二种方法,像这样... 完美地工作。而且比我之前的代码整洁得多。
//enemy rotation in radians from farseer (red line)
float brot = _blocklist[0]._floor.Rotation + ((float)Math.PI/2);
//vector from enemy to player (blue line)
Vector2 _vectToPlayer = playerpos - _blocklist[0].Centre;
//cross product of 2d vectors
cross = (_vectToPlayer.X * (float)Math.Sin(brot)) - ((float)Math.Cos(brot) * _vectToPlayer.Y);
//tolerance for how closely enemy must point towards player
if (Math.Abs(cross) > 5)
{
if (cross > 0)
{
//turn anticlockwise
_blocklist[0]._floor.Rotation -= _npcstats.maxturnspeed;
}
else
{
//turn clockwise
_blocklist[0]._floor.Rotation += _npcstats.maxturnspeed;
}
}
我认为我的以前的代码基本上是在按照建议的方法1来进行操作。但是我无法使其正常工作...我认为这是因为Farseer坐标系统和它与我的坐标系统之间的交互存在问题。