4

几天来我一直在尝试这种方法无济于事,但基本上我在屏幕上有一些生物和玩家。我想要发生的是让敌人以可变速度转向面对玩家,而不是“锁定”到位并立即面对玩家。

我想要做的是计算给定的敌人顺时针或逆时针旋转面对玩家是否更快,但事实证明这超出了我的三角学能力。

例子:

在此处输入图像描述

x在这些图中代表“较短”的路径和我想在每种情况下旋转的方向。

在这种情况下,使用以下任何一种方法来计算“顺时针”或“逆时针”的最简单方法是什么:

  • 敌人面对的方向。
  • 敌人与玩家之间的角度,以及玩家与敌人之间的角度。
4

2 回答 2

8

假设你有一个方向向量,这里不需要计算角度或使用三角函数。

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()orcos()等​​,除非你需要从角度计算方向向量。

这也使用右手坐标系,如果您使用左手坐标系,它将向后 - 公式将相同,但“顺时针”和“逆时针”将被交换。

更深入的解释:(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)是对象所面对的方向。

于 2013-02-11T07:23:30.293 回答
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;

}
于 2013-02-11T07:15:06.000 回答