【问题标题】:How to check if a space in a 3d array is open/empty如何检查 3d 数组中的空间是否打开/为空
【发布时间】:2016-09-15 03:53:21
【问题描述】:

我现在正在为我的代码而苦苦挣扎,我正在 Unity 中编写它,但因为它与 Unity 无关,但通常更多的编码,我认为将它放在这里是一个更好的主意。

背景资料

无论如何,让我解释一下背景信息。我有一个名为 BlockType 的枚举数组,BlockType 枚举包含 Air 或 Stone。而我的数组是一个 3d 数组,我称它为 blocks 并像这样声明blocks = new BlockType[50,50,50](注意:所有块都被初始化为空气)

我也有特征,现在特征只是基本的房间,它们被赋予一个大小,并且只是以它们的位置作为原点放置块。最后,PosDirObj 只是包含位置 (Vect3) 和方向 (Vect2,即(1,0),(0,1),(-1,0),(0,-1)) 的对象。我使用它们来存储特征的位置和方向,因为一旦放置它们我就不需要它们了,所以将它放在特征中是没有意义的。

问题

无论如何,我的问题是,我试图找出房间是否适合我的阵列,这意味着在房间所在的每个位置,只有空气块,我还添加了 1 个块检查实际房间尺寸的填充物只是为了留出空间供以后使用。现在它要么告诉我它是对的,有时它不是,而且大多数时候,它告诉我它是错的,它是正确的,我认为方向系统搞砸了,但我不知道如何修复它。

这是我的代码:

  public bool FeatureFitsInWorld (Feature feature, MathDR.PosDirObj wall)
  {
        // Get required parameters
        Vect3 pos = new Vect3(wall.position.x + Mathf.Abs(wall.direction.x),
                              wall.position.y,
                              wall.position.z + Mathf.Abs(wall.direction.y)); // Gets the position where the starting point will be (adding wall.direction.x/y because there's a padding)
        Vect3 size = feature.size; // The size the room will be
        Vector2 dir = ConvertDirToFitDir(wall.direction); // The direction, btw, this function just changes all 0s to 0.5f, Vector2s are using floats, Vect2s are using ints
        //Vect2 dir = wall.direction; //Using this for testing... Useless for now

        // Checks if the feature doesn't go out of bounds
        if (pos.x + (size.x * (int)dir.x) > worldSize.x ||
            pos.x + (size.x * (int)dir.x) < 0 ||
            pos.y + size.y > worldSize.y ||
            pos.y < 0 ||
            pos.z + (size.z * (int)dir.y) > worldSize.z ||
            pos.z + (size.z * (int)dir.y) < 0)
        {
            Debug.Log("Feature goes out of bounds! at pos " + pos + " with size " + size + " and direction " + dir);
            return false;
        }

        // Checks if all blocks are Air
        for (int x = -1; x < size.x + 1; x++)
        {
            for (int y = 0; y < size.y; y++)
            {
                for (int z = -1; z < size.z + 1; z++)
                {
                    // Checks if the block we are looking at is air,
                    // add some coordinates because else it would just search for an absolute position if the room was placed at 0,0,0, which we are not
                    if (blocks[pos.x + (int)(x * dir.x),
                               pos.y + y,
                               pos.z + (int)(z * dir.y)] != BlockType.Air)
                    {
                        Debug.Log("Found that block isn't air at " + (pos.x + (int)(x * dir.x)) + " " + (pos.y + y) + " " + (pos.z + (int)(z * dir.y)) + " ");
                        return false;
                    }

                }
            }
        }

        return true;
    }

有人知道我的代码有什么问题吗?似乎是什么问题?这个函数我已经重写了两次了,还是不知道为什么不行。

谢谢!

【问题讨论】:

  • 我不太确定你在这里做什么,但看起来你正在将你的 z 与你的 y 相乘:pos.z + (size.z * (int)dir.y) &gt; worldSize.z 当你检查你的块是否不相等时,你正在做类似的事情到空气中。
  • 是的,那是因为方向只有 x,y 但是因为我所有的房间都在同一水平面上,所以我只使用它而不是使用 (0,0,1),而是这样做(0,1)

标签: c# multidimensional-array enums


【解决方案1】:

好的,感谢 PM 的 Chris,能够解决问题。

这是任何可能需要它的人的代码,无论如何非常感谢!

public bool FeatureFits(Feature feature, MathDR.PosDirObj wall)
    {
        // Get required parameters
        Vect3 dir = wall.direction;
        Vect3 pos = wall.position;
        Vect3 size = feature.size;

        if (dir.x == 0)
            dir.x = 1;
        if (dir.y == 0)
            dir.y = 1;
        if (dir.z == 0)
            dir.z = 1;

        int padding = 1;

        int x1 = pos.x - padding;
        int x2 = pos.x + (size.x * dir.x) + padding;

        int y1 = pos.y - padding;
        int y2 = pos.y + (size.y * dir.y) + padding;

        int z1 = pos.z - padding;
        int z2 = pos.z + (size.z * dir.z) + padding;

        // Check if outside bounds
        if (x1 < 0 ||
            x2 < 0 ||
            y1 < 0 ||
            y2 < 0 ||
            z1 < 0 ||
            z2 < 0 ||
            x1 > worldSize.x ||
            x2 > worldSize.x ||
            y1 > worldSize.y ||
            y2 > worldSize.y ||
            z1 > worldSize.z ||
            z2 > worldSize.z) {
            return false;
        }

        // Checks for every block that the feature will take + 1 padding
        for (int x = System.Math.Min(x1, x2); x <= System.Math.Max(x1, x2); x++)
        {
            for (int y = System.Math.Min(y1, y2); y <= System.Math.Max(y1, y2); y++)
            {
                for (int z = System.Math.Min(z1, z2); z <= System.Math.Max(z1, z2); z++)
                {
                    if (blocks[x, y, z] != BlockType.Air)
                    {
                        return false;
                    }
                }
            }
        }

        return true;
    }

顺便说一句,我将 dir 之类的代码更改为 Vect3 只是为了让它更灵活一些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2012-12-01
    • 2012-07-02
    • 1970-01-01
    相关资源
    最近更新 更多