You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效查找二维数组中Tile类单元格的相邻单元格?

嘿,这个问题我之前做格子类游戏的时候也纠结过!四层嵌套循环确实看着头大,而且先全量创建Tile再遍历一遍加邻居,确实有点冗余。咱们来聊聊几个更清爽还能优化效率的实现方式:

1. 用预定义偏移量数组替代嵌套循环

把8个方向的偏移提前存成一个数组,这样就能把原来的四层循环简化成三层,代码可读性直接拉满,逻辑也更清晰。核心思路就是把“遍历x/y偏移”改成“遍历预定义的方向集合”,本质和你找到的那篇帖子思路一致,只是更贴合你的场景。

示例代码(C#):

// 先把8个相邻方向的偏移都列出来,看着也直观
var neighborOffsets = new (int dx, int dy)[] 
{
    (-1, -1), (-1, 0), (-1, 1),
    (0, -1),          (0, 1),
    (1, -1),  (1, 0), (1, 1)
};

int playfieldWidth = ...;
int playfieldHeight = ...;
Tile[,] playfieldTiles = new Tile[playfieldWidth, playfieldHeight];

// 第一步:创建所有Tile
for (int y = 0; y < playfieldHeight; y++)
{
    for (int x = 0; x < playfieldWidth; x++)
    {
        playfieldTiles[x, y] = new Tile();
    }
}

// 第二步:给每个Tile添加邻居
for (int y = 0; y < playfieldHeight; y++)
{
    for (int x = 0; x < playfieldWidth; x++)
    {
        var currentTile = playfieldTiles[x, y];
        foreach (var (dx, dy) in neighborOffsets)
        {
            int neighborX = x + dx;
            int neighborY = y + dy;
            // 检查是否在地图边界内
            if (neighborX >= 0 && neighborX < playfieldWidth && neighborY >= 0 && neighborY < playfieldHeight)
            {
                currentTile.dnTiles.Add(playfieldTiles[neighborX, neighborY]);
            }
        }
    }
}

这种方式虽然还是要遍历两次数组,但代码结构清晰太多,后续维护起来也方便,而且对于大多数游戏场景来说,性能差异完全可以忽略。

2. 边创建Tile边处理邻居(更高效)

如果想减少一次全量遍历,可以在创建每个Tile的时候,直接去关联已经创建好的相邻Tile。因为我们是按行优先顺序创建的,所以当前Tile的左上、上、右上、左这几个方向的Tile肯定已经存在了,只需要处理这些方向,然后互相添加邻居就行——这样每个邻居对只会被处理一次,还省了后续的全量遍历。

示例代码:

int playfieldWidth = ...;
int playfieldHeight = ...;
Tile[,] playfieldTiles = new Tile[playfieldWidth, playfieldHeight];

// 只需要处理已经创建过的邻居方向
var preCreatedOffsets = new (int dx, int dy)[] 
{
    (-1, -1), (-1, 0), (-1, 1),
    (0, -1)
};

for (int y = 0; y < playfieldHeight; y++)
{
    for (int x = 0; x < playfieldWidth; x++)
    {
        var currentTile = new Tile();
        playfieldTiles[x, y] = currentTile;

        foreach (var (dx, dy) in preCreatedOffsets)
        {
            int neighborX = x + dx;
            int neighborY = y + dy;
            if (neighborX >= 0 && neighborX < playfieldWidth && neighborY >= 0 && neighborY < playfieldHeight)
            {
                var neighborTile = playfieldTiles[neighborX, neighborY];
                // 互相添加邻居,一次操作搞定双向关联
                currentTile.dnTiles.Add(neighborTile);
                neighborTile.dnTiles.Add(currentTile);
            }
        }
    }
}

这种方式只需要遍历一次数组,而且邻居的添加操作直接减半(不用每个Tile都遍历8个方向),对于大尺寸的游戏场来说,性能提升会很明显。

额外小技巧:延迟加载邻居(极端场景)

如果你的游戏场特别大,或者大部分Tile的邻居很少被用到,还可以考虑延迟加载——也就是等到需要访问某个Tile的邻居时,再实时计算并缓存结果。不过这种方式适合特殊场景,一般游戏里提前初始化邻居会更稳定,避免运行时的计算开销。

内容的提问来源于stack exchange,提问作者Sander Koldenhof

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:35:20