我有一个工作怪物系统,通过向玩家2D(X,Y)位置移动一定距离来跟随玩家。
但是,我现在想要这样做,以便这些怪物以随机的时间间隔在短距离内游荡。假设我们有一个可以在200-300厘米/秒的范围内移动的怪物。
我需要知道如何准确地确定怪物目的地位置(X,Y)。目前我只需在200-300之间选择一个随机数,然后将这些值添加到怪物当前的X和Y值。虽然这样做有时会超过所需的行进距离。
我的问题是,如何在距我们当前位置一定距离的X,Y网格上选择一个位置。
这是我现在的移动代码......
// Determines if position is changed via addition or subtraction.
const int positive_or_negative = RandomValueInRange_New(0, 1);
// Determines how much to move in each direction
const int x = RandomValueInRange(200, 300);
const int y = RandomValueInRange(200, 300);
if (positive_or_negative == 1)
{
location.Move(x, y);
}
else
{
location.Move(-x, -y);
}
这听起来像是极坐标的工作。您想在给定(随机,范围内)半径的圆上选择一个随机点,然后将该点添加到怪物的当前位置:
// pick a random angle, in radians, between 0 and 2*pi
const double angle = ((double) RandomValueInRange(0, 628318)) / 100000.0;
// pick a random distance between min and max distance
const double radius = RandomValueInRange(200, 300);
// Convert polar co-ordinates to rectilinear co-ordinate deltas
const double dX = cos(angle)*radius;
const double dY = sin(angle)*radius;
// Add the rectilinear co-ordinates to your monster's position
location.Move(dX, dY);
您可以使用至少两种方法。您使用的方法将影响目标坐标的分布。
正如杰里米所说,第一个是使用极坐标。 r = random(200, 300); ang = random(0, 360)
。这导致在r=200
处的坐标密度高于在r=300
处的坐标密度,这是因为由于其较大的环境,最大半径处的“环”将比最小半径处的环具有多50%的面积。
第二种方法是重复产生两个随机值x = random(-300, 300); y = random(-300, 300)
,直到随机对通过200和300之间距离的约束。
int dX, dY, d2;
do {
dX = RandomValueInRange(-300, 300);
dY = RandomValueInRange(-300, 300);
d2 = dX*dX + dY*dY;
} while ( d2 < 200*200 || d2 > 300*300);
location.Move(dX, dY);
这在空间中产生均匀分布,但代价是重复随机数生成。只有43.6%的随机对会落在所需的区域内,因此在生成可接受的对之前,循环通常会执行2到3次。
虽然这种分布甚至在x-y空间中,但它在距离方面甚至都不是。一个怪物的平均移动距离超过250厘米,因为环形区域在250厘米到300厘米之间的区域比从200厘米到250厘米的环形区域多。
更现实的移动分布会根据之前的行动偏向下一步行动。例如,做一个约会可能是一个低概率事件。除非怪物在积极守护某个地点,否则它可能是最高可能行动!
没有关于怪物应该如何表现的更多细节,如果你不过分关注分布,那么最简单的一代将是极坐标路线,它从正好2个随机数代产生一个合法的位置而没有循环。