C# 如何使后续Ai在基于环形2D栅格的地图上工作

C# 如何使后续Ai在基于环形2D栅格的地图上工作,c#,grid,2d,artificial-intelligence,console-application,C#,Grid,2d,Artificial Intelligence,Console Application,我有一些NPC在一个二维矩阵中环绕,我必须让他们使用环形地图跟随敌人派系NPC 我尝试过几种解决方案,但它们都给了我奇怪的行为,只对网格的某个x或y值起作用,然后它们返回一个平铺,而不是跟随 这就是我现在要决定的方向: 公共位置GetNextStepTowards(位置原点、位置目标) { 位置nextStep=新位置(0,0); float dx=MathF.Abs(target.X-origin.X); float dy=MathF.Abs(target.Y-origin.Y); 如果(dx

我有一些NPC在一个二维矩阵中环绕,我必须让他们使用环形地图跟随敌人派系NPC

我尝试过几种解决方案,但它们都给了我奇怪的行为,只对网格的某个
x
y
值起作用,然后它们返回一个平铺,而不是跟随

这就是我现在要决定的方向:

公共位置GetNextStepTowards(位置原点、位置目标)
{
位置nextStep=新位置(0,0);
float dx=MathF.Abs(target.X-origin.X);
float dy=MathF.Abs(target.Y-origin.Y);
如果(dx>mapXSize/2)下一步X=-1;
如果(dxmapYSize/2)下一步Y=1;
如果(dy
一个职位是:

公共结构位置
{
公共整数X{get;set;}
公共整数Y{get;set;}
公共位置(整数x,整数y)
{
这个.X=X;
这个。Y=Y;
}
}
NPC只能移动一个单元(Moore's),因此移动向量应仅为
-1
1
之间的值


提前感谢您的帮助

过了一会儿,我想出了这个解决方案,在我看来有点笨拙:

公共位置GetNextStepTowards(位置原点、位置目标)
{
//返回位置
位置nextStep=新位置(0,0);
int dx=target.X-origin.X;
int dy=target.Y-origin.Y;
//环向距离
如果(dx>mapXSize/2)dx=mapXSize-dx;
如果(dy>maphysize/2)dy=mapXSize-dy;
//首先验证位置差异是否正确
//在X轴或Y轴上更大。
//然后检查目标是否较低/较高/向前/向后
if(数学功率(dx,2)>数学功率(dy,2))
{
如果(dx>0)下一步X=1;
如果(dx<0)下一步X=-1;
}
else if(数学功率(dy,2)>数学功率(dx,2))
{
如果(dy>0)下一步Y=1;
如果(dy<0)下一步Y=-1;
}
//如果X轴和Y轴的差值相同,
//斜移
//使用比较器确定具体的方向。
else如果((int)数学功率(dx,2)==(int)数学功率(dy,2))
{
下一步X=1*target.X.CompareTo(origin.X);
下一步Y=1*target.Y.CompareTo(origin.Y);
}
返回下一步;
}

<代码> > p>如果我们考虑x轴,有两种情况,如下图所示:

在第一种情况下(顶部),目标位于原点右侧。在这种情况下,向右移动是直接的,向左移动是环形的

在第二种情况下(底部),目标位于原点的左侧。在这种情况下,向左移动是直接的,向右移动是环形的

因此,代码需要检查原点和目标的相对位置,然后适当地计算左右距离。较小的距离决定了deltaX的方向和大小。同样的逻辑也适用于deltaY

如果deltaX和deltaY的大小相同,我们沿着对角线移动。否则,我们朝着较大的三角形方向移动

private int ComputeDelta(int src, int dst, int mapSize)
{
    int increasing, decreasing;
    if (dst >= src)
    {
        increasing = dst - src;               // increasing direction is direct
        decreasing = (mapSize + src) - dst;   // decreasing direction is toroidal
    }
    else
    {
        increasing = (mapSize + dst) - src;   // increasing direction is toroidal
        decreasing = src - dst;               // decreasing direction is direct
    }

    if (increasing <= decreasing) { return  increasing; }
    else                          { return -decreasing; }
}

public Position GetNextStepTowards(Position origin, Position target)
{
    Position nextStep = new Position(0, 0);

    // compute the distances
    int dx = ComputeDelta(origin.X, target.X, mapXSize);
    int dy = ComputeDelta(origin.Y, target.Y, mapYSize);

    // keep the dominant distance, and clear the other distance
    // keep both if they're equal
    if      (dx*dx > dy*dy) { dy = 0; }
    else if (dx*dx < dy*dy) { dx = 0; }

    // normalize the distances so they are -1, 0, or 1
    nextStep.X = dx.CompareTo(0);
    nextStep.Y = dy.CompareTo(0);

    return nextStep;
}
private int ComputeDelta(int src、int dst、int mapSize)
{
int递增,递减;
如果(dst>=src)
{
递增=dst-src;//递增方向是直接的
递减=(mapSize+src)-dst;//递减方向为环形
}
其他的
{
递增=(mapSize+dst)-src;//递增方向为环形
递减=src-dst;//递减方向是直接的
}

如果(增加@user3386109)解决了这个问题,我会很快发布我提出的解决方案,如果更多的人分享他们的解决方法,这会有所帮助。谢谢你分享这个解决方案,它创造了奇迹,比我提出的更优雅