我一直在尝试这几天无效,但基本上我有一些生物和屏幕上的播放器。我想要发生的是让敌人转向以可变速度面对玩家,而不是“锁定”到位并立即面对玩家。
我想要做的是弄清楚给定的敌人是否更快地顺时针或逆时针旋转以面对玩家,但事实证明它超出了我的三角测量能力。
示例:
这些图中的
x
表示“更短”的路径以及我想在每种情况下旋转的方向。
在这种情况下,使用以下任何一种方法,以“顺时针”或“逆时针”计算出最简单的方法是什么:
答案 0 :(得分:7)
假设你有方向向量,无需来计算角度或使用三角函数。
var pos_x, pos_y, dir_x, dir_y, target_x, target_y;
if ((pos_x - target_x) * dir_y > (pos_y - target_y) * dir_x) {
// Target lies clockwise
} else {
// Target lies anticlockwise
}
这只是在物体朝向的方向上绘制一条虚线穿过物体,并找出目标所在线的哪一侧。这是基本的线性代数,因此您不需要在此函数的任何位置使用sin()
或cos()
等,除非您需要从角度计算方向向量。
这也使用右手坐标系,如果使用左手坐标系,它将向后 - 公式将相同,但“顺时针”和“逆时针”将被交换。
更深入的解释:该函数计算前向向量(dir_x, dir_y)
的外积和目标向量(target_x - pos_x, target_y - pos_y)
的向量。得到的外积是假标量,正或负,取决于目标是顺时针还是逆时针。
向量是幅度和方向,例如,向北3公里或向下6厘米。您可以使用笛卡尔坐标(x,y)表示矢量,也可以使用极坐标(r,θ)表示矢量。两个表示都为您提供相同的向量,但它们使用不同的数字和不同的公式。一般来说,你应该坚持使用笛卡尔坐标而不是极坐标。如果你正在编写一个游戏,那么极坐标会很糟糕 - 它们会在sin()
和cos()
到处乱丢您的代码。
代码中有三个向量:
向量(pos_x, pos_y)
是对象相对于原点的位置。
向量(target_x, target_y)
是目标相对于原点的位置。
向量(dir_x, dir_y)
是对象面向的方向。
答案 1 :(得分:1)
const CLOCKWISE:int = 0;
const COUNTER_CLOCKWISE:int = 1;
const PI2:Number = Math.PI * 2
function determineSmallestAngle(from:Sprite, to:Sprite):int
{
var a1:Number = Math.atan2(to.y - from.y, to.x - from.x);
var a2:Number = from.rotation * Math.PI / 180;
a2 -= Math.floor(a2 / PI2) * PI2;
if(a2 > Math.PI) a2 -= PI2;
a2 -= a1;
if (a2 > Math.PI) a2 -= PI2;
if (a2 < -1 * Math.PI) a2 += PI2;
if (a2 > 0) return CLOCKWISE;
return COUNTER_CLOCKWISE;
}