【问题标题】:Dynamically adding tiles to a grid based map将切片动态添加到基于网格的地图
【发布时间】:2015-12-24 03:10:56
【问题描述】:

我想要一张可无限探索的地图。计划是创建游戏图块类别(道路、障碍物、建筑物),并在玩家接近现有图块集的边缘时随机选择要添加的游戏图块类别。一旦玩家距离该图块 2 个方格,图块也将被销毁。目前我正在使用一个需要大小初始化程序的多维数组。

到目前为止我所拥有的:

public class GameManager : MonoBehaviour
{
    private GameObject[,] tileArray;
    public GameObject groundTile;
    public GameObject player;

    private int tileSize = 80;
    private int nextFarX = 1;
    private int nextFarZ = 1;
    private int nextNearX = -1;
    private int nextNearZ = -1;
    private float padding = .1f;

    private int arrayOffset;
    private int arrayDimension;

    // Use this for initialization
    void Start ()
    {
        arrayDimension = 200;
        arrayOffset = arrayDimension / 2;
        tileArray = new GameObject[,];
        this.AddCubeAt(0, 0);
    }

    // Update is called once per frame
    void Update () {
        var x = Convert.ToInt32(player.transform.position.x / tileSize);
        var z = Convert.ToInt32(player.transform.position.z / tileSize);

        for (int i = -1; i < 2; i++)
        {
            for (int j = -1; j < 2; j++)
            {
                var checkX = x + i;
                var checkZ = z + j;
                if (tileArray[checkX + arrayOffset, checkZ + arrayOffset] == null)
                {
                    //player is less than 2 tiles away from this grid, add a tile
                    this.AddCubeAt(checkX, checkZ);
                }
            }
        }
        // feels like a hack, but it will remove tiles that are not touching the tile that the player occupies
        for (int i = 0; i < 6; i++)
        {
            for (int j = 0; j < 6; j++)
            {
                if (i == 0 | i == 5 | j == 0 | j == 5)
                {
                    if (tileArray[x + (i-2) + arrayOffset, z + (j-2) + arrayOffset] != null)
                    {
                        Destroy(tileArray[x + (i - 2) + arrayOffset, z + (j - 2) + arrayOffset]);
                        tileArray[x + (i - 2) + arrayOffset, z + (j - 2) + arrayOffset] = null;
                    } 
                }
            }
        }
    }

    private void AddCubeAt(int x, int z)
    {
        var pos = new Vector3(x * tileSize, 0, z * tileSize);
        var rot = Quaternion.identity;
        GameObject newCube = (GameObject)Instantiate(groundTile, pos, rot);
        tileArray[x + arrayOffset, z + arrayOffset] = newCube;
    }
}

有什么更好的方法来解决这个问题?

【问题讨论】:

    标签: unity3d unity5


    【解决方案1】:

    您应该熟悉图形数据结构(不是邻接矩阵实现)。它更适合这项任务。而且,我会解决这个问题

    一旦玩家距离该图块 2 个方格,图块也会被销毁

    以另一种方式:每次玩家改变他的位置时,我都会在目标深度(在你的情况下为 2)开始 DFS 并删除找到的瓷砖。

    【讨论】:

    • 我进行了一些搜索,但没有找到“图形数据结构”的示例。我粘贴的代码有效(包括破坏图块),它只是不允许无限大小的地图,因为多维数组具有固定大小。你能分享一些例子/链接吗?
    • @Roger 有很多关于图数据结构的资料。例如,Adjacency list。我敦促你阅读Data Structures and Algorithms in Java(至少有一章叫做“图算法”)
    • 我所拥有的将一次仅实例化 9 个图块(至少在 update() 完成时)。我知道跟踪图中深度的图算法方法可能是一种有效的方法。只有 9 个活动磁贴,我没有性能问题需要更高效的东西。我需要的是一个 c# 类或混合类型来存储没有预定义大小的多维二维对象数组。
    • @Roger 好吧,然后使用 List>。很抱歉造成误解。
    【解决方案2】:

    决定使用一个简单的字典和查询/更新它的方法:

    private GameObject RetrieveTileAt(int x, int z)
    {
        string key = string.Format("{0}.{1}", x, z);
        if (tileDictionary.ContainsKey(key))
        {
            return tileDictionary[key];
        }
        else
        {
            return null;
        }
    }
    
    private void InsertTileAt(int x, int z, GameObject tile)
    {
        string key = string.Format("{0}.{1}", x, z);
        tileDictionary[key] = tile;
    }
    

    它不是一个无限大小的网格,(int min + int max)squared,但它应该远远超过我的需要。

    【讨论】:

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