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

六边形消除后填充逻辑实现求助:二维数组坐标更新

实现六边形下落填充的核心思路(数组优先更新)

我明白你的需求:销毁指定坐标的六边形后,让同一列上方的六边形“下落”填补空位,顶部生成新六边形,核心是更新二维数组Hexagons的引用,而非实际移动对象,确保每个坐标位置仅有唯一引用。下面是具体的实现方案,结合你的现有代码修改:

1. 调整销毁逻辑:记录要销毁的坐标而非对象

首先,把原来收集待销毁对象的逻辑改成记录待销毁的坐标,这样后续处理数组时更清晰,还能避免重复操作:

// 替换原来的HexToBeDestroyed对象列表,改用坐标列表存储要销毁的位置
List<Vector2Int> coordsToDestroy = new List<Vector2Int>();

// 在你的匹配逻辑中,添加坐标而非对象
if (MatchedColors == 2) {
    // 添加匹配的三个坐标
    coordsToDestroy.Add(new Vector2Int(x, y));
    coordsToDestroy.Add(new Vector2Int(x - 1, y));
    coordsToDestroy.Add(new Vector2Int(x - 1, y - 1));
    // 去重,避免重复添加同一坐标
    coordsToDestroy = coordsToDestroy.Distinct().ToList();
}
MatchedColors = 0;

2. 核心:处理下落填充与数组更新

编写专门的方法处理每一列的六边形下落和数组更新,核心是先收集每一列中保留的六边形,再重新填充数组,顶部空位生成新六边形:

private void HandleHexagonFall(int gridWidth, int gridHeight) {
    // 遍历每一列
    for (int x = 0; x < gridWidth; x++) {
        // 收集当前列中未被标记销毁的有效六边形
        List<HexCoordinates> validHexes = new List<HexCoordinates>();
        for (int y = 0; y < gridHeight; y++) {
            Vector2Int currentCoord = new Vector2Int(x, y);
            // 如果当前坐标不在销毁列表,且对象存在
            if (!coordsToDestroy.Contains(currentCoord) && Hexagons[x, y] != null) {
                validHexes.Add(Hexagons[x, y]);
            }
        }

        // 重新填充当前列的数组
        for (int y = 0; y < gridHeight; y++) {
            if (y < validHexes.Count) {
                // 将保留的六边形放到新的坐标位置
                Hexagons[x, y] = validHexes[y];
                // 更新六边形自身的坐标记录(必须同步,否则后续匹配逻辑出错)
                Hexagons[x, y].Coordinates = new Vector2Int(x, y);
                // 更新世界位置,视觉上呈现下落效果
                Hexagons[x, y].transform.position = CalcWorldPos(new Vector2(x, y));
                // 更新对象名称以便调试
                Hexagons[x, y].transform.name = $"X: {x} | Y: {y}";
            } else {
                // 顶部空位生成新的六边形
                GameObject newHex = Instantiate(HexagonPre, Vector2.zero, Quaternion.identity, HexGrid);
                // 随机设置颜色(复用你原来的逻辑)
                int randColor = Random.Range(0, 5);
                switch(randColor) {
                    case 0: newHex.GetComponent<SpriteRenderer>().color = Color.blue; break;
                    case 1: newHex.GetComponent<SpriteRenderer>().color = Color.red; break;
                    case 2: newHex.GetComponent<SpriteRenderer>().color = Color.green; break;
                    case 3: newHex.GetComponent<SpriteRenderer>().color = Color.yellow; break;
                    case 4: newHex.GetComponent<SpriteRenderer>().color = Color.cyan; break;
                }
                // 设置新六边形的坐标信息
                HexCoordinates hexCoord = newHex.GetComponent<HexCoordinates>();
                hexCoord.Coordinates = new Vector2Int(x, y);
                newHex.transform.position = CalcWorldPos(new Vector2(x, y));
                newHex.transform.name = $"X: {x} | Y: {y}";
                // 将新六边形加入数组
                Hexagons[x, y] = hexCoord;
            }
        }
    }

    // 最后销毁所有标记要删除的对象
    foreach (Vector2Int coord in coordsToDestroy) {
        if (Hexagons[coord.x, coord.y] != null) {
            Destroy(Hexagons[coord.x, coord.y].gameObject);
        }
    }
    // 清空销毁列表,准备下一次操作
    coordsToDestroy.Clear();
}

3. 补充初始化逻辑(关键!)

你的CreateGrid方法里缺少对Hexagons数组的赋值,必须补上,否则后续数组操作会报错:

public void CreateGrid(int gridWidth, int gridHeight) {
    // 初始化二维数组
    Hexagons = new HexCoordinates[gridWidth, gridHeight];
    
    for (int y = 0; y < gridHeight; y++) {
        for (int x = 0; x < gridWidth; x++) {
            GameObject Hexagon = Instantiate(HexagonPre, Vector2.zero, Quaternion.identity, HexGrid);
            int RandColor = Random.Range(0, 5);
            if (RandColor == 0) {
                Hexagon.GetComponent<SpriteRenderer>().color = Color.blue;
            } else if (RandColor == 1) {
                Hexagon.GetComponent<SpriteRenderer>().color = Color.red;
            } else if (RandColor == 2) {
                Hexagon.GetComponent<SpriteRenderer>().color = Color.green;
            } else if (RandColor == 3) {
                Hexagon.GetComponent<SpriteRenderer>().color = Color.yellow;
            } else if (RandColor == 4) {
                Hexagon.GetComponent<SpriteRenderer>().color = Color.cyan;
            }
            Vector2 gridPos = new Vector2(x, y);
            Hexagon.transform.position = CalcWorldPos(gridPos);
            HexCoordinates hexCoord = Hexagon.GetComponent<HexCoordinates>();
            hexCoord.Coordinates = new Vector2Int(x, y);
            Hexagon.transform.name = "X: " + x + " | Y: " + y;
            // 将六边形引用存入数组
            Hexagons[x, y] = hexCoord;
        }
    }
}

核心原理说明

  • 数组优先:我们通过重新填充数组来实现“下落”逻辑,确保每个坐标位置只有唯一的六边形引用,完全符合你的核心要求。
  • 视觉同步:虽然没有移动对象,但通过CalcWorldPos重新计算世界位置,让对象看起来是从上方下落到底部空位的。
  • 数据一致性:每个六边形的Coordinates组件必须和数组中的坐标严格对应,否则后续的匹配、销毁逻辑会出现错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:22:30