Unity 2D平铺图 - 按类型C#分组

时间:2017-02-26 17:14:30

标签: c# unity3d multidimensional-array

我正在寻找一种解决方案,根据它们的拼贴类型对我的游戏拼贴进行分组。磁贴存储在2d数组中,类型为空和水,组中的磁贴将存储在Group类中。

所以如果我有2d数组:

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);
}

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

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

  1. 左侧或底部都不是水砖(或存在):在当前的
  2. 上创建一个新组
  3. 左/下是水瓦片:向左/下组
  4. 添加电流
  5. 左侧和底部都是同一组中的水瓦片:向其组添加电流
  6. 左侧和底部都是不同组中的水砖:现在这些组有连接并需要合并。还要为新组添加电流
  7. 我写了一段代码作为演示,但请注意它是未经测试和简化的。我认为两个组合并是一种麻烦,因为你有更新它的每个组的参考。此外,您必须稍后使用一个磁贴(如果需要)对组进行排序。但它应该指出你正确的方向:

    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;
                }
            }
        }
    }