读取Array [] []时出现NullReferenceException

时间:2013-11-18 15:16:57

标签: c# arrays

Rectangle对象的声明失败,出现NullReferenceException,可能与for循环有关(yMax和xMax在tiles单元中) 谢谢你帮我理解为什么这给了我一个例外。

    TileData[][] tile = GameMain.Level.getCollisionTiles();
    int xMax = GameMain.Level.getMapHeight();
    int yMax = GameMain.Level.getMapWidth();

    for (int x = 0; x <= xMax; x++)
    {
        for (int y = 0; y <= yMax; y++)
        {
            Rectangle tileRectangle = tile[x][y].Target; //THIS LINE FAILS !!!!
            if (tileRectangle.Contains(m_hitbox)) //Si il y a collision
            {
                if ((m_hitbox.X + m_hitbox.Width) > tileRectangle.X) //si le joueur percute par la gauche
                {
                    m_hitbox.X--;
                }
                else if (m_hitbox.X < (tileRectangle.X + tileRectangle.Width)) //Droite
                {
                    m_hitbox.X++;
                }
                if ((m_hitbox.Y + m_hitbox.Height) > tileRectangle.Y) //si le joueur percute par le haut
                {
                    m_hitbox.Y--;
                }
                else if (m_hitbox.Y < (tileRectangle.Y + tileRectangle.Height)) //Bas
                {
                    m_hitbox.Y++;
                }
            }
        }
    }

这是一些代码,

访问者(GameMain.Level。):

public TileData[][] getCollisionTiles()
    {
        return m_collisionTiles;
    }

类“Level”属性和构造函数:

//Atributs
    Map m_map;
    List<TileLayer> m_layers;
    TileLayer m_collisionLayer;
    TileData[][] m_collisionTiles;
    int m_mapWidth;
    int m_mapHeight;
    int m_tileWidth;
    int m_tileHeight;
    //Constructeur
    public Level(ContentManager content, string levelName)
    {
        m_map = content.Load<Map>("Maps/"+levelName); //On charge la map

        //params
        m_mapWidth = m_map.Width;
        m_mapHeight = m_map.Height;
        m_tileWidth = m_map.TileWidth;
        m_tileHeight = m_map.TileHeight;

        //tiles / layers
        m_layers = new List<TileLayer>(m_map.TileLayers); //On charge les calques / couches
        m_collisionLayer = m_layers.Find( x => x.Name == "Collision"); //On charge le calque de collision
        m_collisionTiles = m_collisionLayer.Tiles;


    }

3 个答案:

答案 0 :(得分:0)

如果此行抛出NullReferenceException

Rectangle tileRectangle = tile[x][y].Target

然后tiletile[x]tile[x][y]为空。在调试器中运行它以找出哪一个。

答案 1 :(得分:0)

我的猜测是m_collisionLayer.Tiles通过循环遍历碰撞切片列表并将它们添加到数组来构造二维数组。如果给定的x值不存在数组,它将创建它并将适当的tile粘贴到适当的y值。

这种方法的问题在于,如果给定的x值不存在碰撞图块,那么它永远不会为该x值创建数组(这将是空的),因此tile[x]将保持为null tile[x][y]将提供空引用异常。

解决方法是在第一次声明数组时完全初始化数组,或在循环y值之前检查tile[x]是否为null,并在调用tile[x][y]之前检查.Target

空检查可能是更好的方法,因为它意味着你绕过一个紧凑的数组(即间隙中没有对象而不是空对象)。既然你想在调用.Target之前做一个空检查,那么你也可以添加以前的空检查。

此外,如果没有碰撞Tiles,那么tile可能为null,在这种情况下你也想要检查它。

for (int x = 0; x <= xMax; x++)
{
    if (tile[x]==null)
        continue;
    for (int y = 0; y <= yMax; y++)
    {
        if (tile[x][y]==null)
            continue;
        Rectangle tileRectangle = tile[x][y].Target; //THIS LINE FAILS !!!!
        //Snipped code here
    }
}

初始化它将在TileLayer对象中完成,基本上意味着你在创建数组的位置,你会做类似的事情:

int[][] arr = new int[10][];
for (int i= 0; i<arr.Length; i++)
{
    arr[i] = new int[10];
}

最后一点需要注意的是[] []适用于锯齿状阵列。如果您的图块总是在矩形中,那么您可能实际上想要使用TileData[,]。这是一个包含两个索引的单个数组,这可能是您想要的,而不是数组数组(这就是您现在拥有的数据)。

答案 2 :(得分:-1)

看起来你的循环中的边界范围不正确。

for (int x = 0; x < xMax; x++)
{
    for (int y = 0; y < yMax; y++)

不是“更少或相等”,而只是“更少”比较。