【问题标题】:Unity 2D Tile Map -- Group Tiles By Type C#Unity 2D Tile Map -- 按类型 C# 分组 Tiles
【发布时间】:2017-07-17 05:35:00
【问题描述】:

我正在寻找一种解决方案,按我的游戏图块类型对它们进行分组。瓦片存储在二维数组中,类型为空和水,分组的瓦片将存储在 Group 类中。

所以如果我有二维数组:

0, 0, 0, 0, 0, 0, 0, 0,

0, 1, 1, 1, 0, 0, 0, 0,

0, 1, 1, 0, 0, 0, 1, 1,

0, 1, 0, 0, 0, 0, 1, 1

0 是空的,1 是水,会有两个水组。

我花了整个下午试图弄清楚,这就是我目前所拥有的。

public void GenerateGroups(){
    //Debug.Log("Generate Groups");
    m_Groups = new List<Group>();
    List<Tile> groupingTiles = new List<Tile>();

    int groupId = 1;

    foreach(Tile t in m_Tiles){
        t.IsGrouped = false;
    }

    for(int y = 0;  y < Height; y++){
        for (int x = 0; x < Width; x++) {
            Tile tile = m_Tiles[x, y];

            if(tile.Type == TileType.Water && !tile.IsGrouped){

        //      if(m_Tiles[x+1, y].IsGrouped || m_Tiles[x, y + 1].IsGrouped){
        //          if(m_Groups.Count > 0){
        //              foreach(Group g in m_Groups){
        //                  if(g.m_Tiles.Contains(m_Tiles[x+1, y]) || g.m_Tiles.Contains(m_Tiles[x, y + 1])){
        //                      g.m_Tiles.Add(tile);
        //                      tile.IsGrouped = true;
        //                      continue;
        //                  }
        //              }
        //          }
        //      }else{
        //          groupingTiles.Add(tile);    
        //      }

                groupingTiles.Add(tile);

                tile.IsGrouped = true;

                Tile next = m_Tiles[x + 1, y];
                int pos = x + 1;

                while(next.Type == TileType.Water && !next.IsGrouped && pos < Width){
                //  Debug.Log("Going right!");
                    groupingTiles.Add(next);
                    pos++;
                    next.IsGrouped = true;
                    next = m_Tiles[pos, y];
                }

                next = m_Tiles[x, y + 1];
                pos = y + 1;

                while(next.Type == TileType.Water && !next.IsGrouped && pos < Height){
                    //Debug.Log("Going up!");
                    groupingTiles.Add(next);
                    pos++;
                    next.IsGrouped = true;
                    next = m_Tiles[x, pos];
                }

            }

            if(groupingTiles.Count > 0){
                //Debug.Log("Group Tiles: " + groupingTiles.Count);
                m_Groups.Add(new Group("Group_" + groupId, groupingTiles));
                groupId++;
                groupingTiles = new List<Tile>();
            }
        }
    }


    Debug.Log(m_Groups.Count);
}

任何帮助将不胜感激!

【问题讨论】:

  • 为什么要在 for 循环中使用 while,这似乎是多余的,可能会导致所有问题
  • 添加所有在当前图块上方和右侧的图块,只要它们是水图块。然后它将在 for 循环中跳过它们,但这正是我目前所拥有的并且它不起作用。只是在等待有人提出一个好的算法,不知道如何去做

标签: c# unity3d multidimensional-array


【解决方案1】:

我会通过在磁贴内保存组的引用来解决此问题。遇到水瓦时,检查它的左边或底部邻居是否也是水瓦。这可能会在四种情况下结束:

  1. 左边或底部都不是水瓦(或存在):在当前瓦上创建一个新组
  2. left/bottom是一个水瓦:将current添加到left/bottom组
  3. 左侧和底部都是同一组中的水砖:将电流添加到它们的组中
  4. 左侧和底部都是不同组中的水砖:现在这些组有连接,需要合并。还将当前添加到该新组

我写了一段代码作为演示,但请注意它未经测试和简化。我认为合并两个组有点麻烦,因为您可以更新每个图块的参考。此外,您必须稍后(如果需要)仅使用一个图块对组进行分类。但它应该为您指明正确的方向:

for(int y = 0; y < Height; y++)
{
    for(int x = 0; x < Width; x++)
    {
        Tile currentTile = GetTile(x, y);

        if(!currentTile.IsWater)
            continue;

        Tile leftTile = GetLeftNeighbour(currentTile);
        Tile bottomTile = GetBottomNeighbour(currentTile);

        if(!leftTile.IsWater && !bottomTile.IsWater)
        {
            //first case
            Group newGroup = new Group();

            newGroup.Tiles.Add(currentTile);
            currentTile.Group = newGroup;                
        }
        else if(leftTile.IsWater && !bottomTile.IsWater)
        {
            //second case A
            leftTile.Group.Tiles.Add(currentTile);
            currentTile.Group = leftTile.Group;
        }
        else if(!leftTile.IsWater && bottomTile.IsWater)
        {
            //second case B
            bottomTile.Group.Tiles.Add(currentTile);
            currentTile.Group = bottomTile.Group;
        }
        else
        {
            if(leftTile.Group == bottomTile.Group)
            {
                //third case
                leftTile.Group.Tiles.Add(currentTile);
                currentTile.Group = leftTile.Group;
            }
            else
            {
                //fourth case
                leftTile.Group.Merge(bottomTile.Group);

                leftTile.Group.Tiles.Add(currentTile);
                currentTile.Group = leftTile.Group;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多