10

我试图在一个立方体周围实现 A* 寻路,立方体由 6 个网格组成,为​​了简单起见,我有 4 个方法 GetXPlus、GetXMinus、GetYPlus、GetYMinus。每种方法都会检查下一个图块是否在当前网格空间内,如果不是则切换到适当的网格。

我遇到的问题是,当试图从当前网格以另一种方式翻转的网格中获取图块时,返回的图块位于另一侧。有没有一种方法或方法可以让我避免为每个原始网格和方向编写独特的逻辑?

为了帮助阐明我的问题,在此我来自(紫色)网格并使用 GetXPlus 方法:

在此处输入图像描述

我当前实现的一个片段(每个网格是 64 x 64):

public Tile GetXPlus( int currentX, int currentY )
{
    var newX = currentX + 1;
    var tile = GetTile( newX , currentY );

    if( newX > 64 ) //Get adjacent XPlus Grid 
    { 
        currentGrid = SetCurrentGrid( XPlusGridIndex );
        tile = GetTile( newX - 64, currentY );
    }

    return tile;
}

背景

此实现源于对此处建议的不同问题的出色回答:https ://gamedev.stackexchange.com/questions/53866/pathfinding-on-a-uneven-planetary-surface

4

2 回答 2

1

我建议您比上一个答案所建议的更进一步。创建一个代表所有瓦片的立方体,并缓存每个瓦片的邻居。由于瓷砖之间的关系是固定的,它将为您节省很多时间。

之后,您可以使用double[,,]int[,,,]来跟踪您处理过的图块,并在此基础上将邻居添加到您的Queue<Tile>.

如果需要,您也可以实施GetDirection(Tile tile)。该功能只需要在方向字典中搜索。

公共类立方体 { 私人瓷砖 [,,] 瓷砖;

    public Cube(int size)
    {
        tiles = new Tile[size, size, 6];

        // initialize.
        for (var side = 0; side < 6; side++)
        {
            for (var x = 0; x < size; x++)
            {
                for (var y = 0; y < size; y++)
                {
                    tiles[x, y, side] = new Tile(x, y, side);
                }
            }
        }

        // set directions & neighbors
        for (var side = 0; side < 6; side++)
        {
            for (var x = 0; x < size; x++)
            {
                for (var y = 0; y < size; y++)
                {
                    // todo: implement.
                }
            }
        }
    }

    public Tile this[int x, int y, int side]
    {
        get
        {
            return tiles[x, y, side];
        }
    }
}

public class Tile
{
    private Dictionary<DirectionType, Tile> directions = new Dictionary<DirectionType, Tile>();

    private Tile[] neighbors = new Tile[4];

    public Tile(int x, int y, int side)
    {
        this.X = x;
        this.Y = y;
        this.Side = side;
    }

    public int X { get; private set; }
    public int Y { get; private set; }
    public int Side { get; private set; }

    public Tile this[DirectionType dir]
    {
        get
        {
            return directions[dir];
        }
    }



    public Tile[] Neighbors { get { return neighbors; } }
}

public enum DirectionType
{
    // delta: +1, 0
    e,
    // delta: 0, +1
    n,
    // delta: -1, 0
    w,
    // delta: 0, -1
    s,
    // delta: 0, 0
    X
}
于 2013-05-14T13:43:15.760 回答
0

您可以使用从一个由“X 坐标”、“Y 坐标”和“平铺”组成的 3d 坐标空间映射到另一个的函数。

给定一个命令:

enum TileBorder
{
    Left   = 0,
    Top    = 1,
    Right  = 2,
    Bottom = 3
}

您可以将这些转换存储在Tile类的数组中:

class Tile
{
    public Tile[] Neighbors { get; set; }
    public Func<int, int, int>[] XTransitions { get; set; }
    public Func<int, int, int>[] YTransitions { get; set; }

    public void GetXPlus(int x, int y, out int newX, out int newY, out Tile newTile)
    {
        x++;
        if (x <= 64)
        {
            newX = x;
            newY = y;
            newTile = this;
        }
        else
        {
            newX = XTransitions[(int)TileBorder.Right](x, y);
            newY = YTransitions[(int)TileBorder.Right](x, y);
            newTile = Neighbors[(int)TileBorder.Right];
        }
    }
    // ...
}

然后你只需要在设置结构时稍微注意一下。例如,假设您的坐标从 1 到 64(包括 1 到 64),这就是您可以设置绿色图块的方式。

Tile pink   = new Tile();
Tile green  = new Tile();
Tile orange = new Tile();
Tile purple = new Tile();
Tile blue   = new Tile();

green.Neighbors = new Tile[] 
{ 
    /* left */   orange, 
    /* top */    pink,
    /* right */  blue,
    /* bottom */ purple 
};

green.XTransitions = new Func<int, int, int>[] 
{
    /* left */   (x, y) => 1, 
    /* top */    (x, y) => x,
    /* right */  (x, y) => 64,
    /* bottom */ (x, y) => x 
};

green.YTransitions = new Func<int, int, int>[] 
{
    /* left */   (x, y) => 65 - y, 
    /* top */    (x, y) => 64,
    /* right */  (x, y) => 65 - y,
    /* bottom */ (x, y) => 1
};

请注意,tile 转换函数只是一个查找,但为了完全灵活,您还可以使用以下类型
Func<int, int, Tile, int>的函数:x 坐标、
Func<int, int, Tile, int>y 坐标和
Func<int, int, Tile, Tile>tile。

于 2013-05-13T22:54:47.017 回答