NullReferenceException, как мне справиться с этим? - PullRequest
1 голос
/ 03 января 2012

Я получаю эту ошибку в C # при попытке создать импортер для карты тайлов.Предполагается, что файлы должны быть отформатированы следующим образом:

DatMapName!
6|4
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY
SpritePageID:SpriteID:OffsetX:OffsetY|SpritePageID:SpriteID:OffsetX:OffsetY SpritePageID:SpriteID:OffsetX:OffsetY

в структуру данных, скомпилированную следующим образом:

map
    MapTile[MapSizeX, MapSizeY]
        Tile[Sprites on tile]
        - string SpritePageID
        - int SpriteID
        - Vector2 Offset

В основном это имя карты в первой строке, X / Yразмер на втором, а затем он имеет SpritePageID, spriteID, offsetx, offsetY, разделенные:, и несколько спрайтов на плитку, разделенные |.Пробелы разделяют разные плитки.

Однако во время обработки я получаю следующую ошибку:

Error   1   Building content threw NullReferenceException: Object reference not set to an instance of an object.
at LibTilePipelineExtension.LevelProcessor.Process(String input, ContentProcessorContext context) in C:\Projects\C#\XNA1\TileWorld\LibTilePipelineExtension\LevelProcessor.cs:line 45
at Microsoft.Xna.Framework.Content.Pipeline.ContentProcessor`2.Microsoft.Xna.Framework.Content.Pipeline.IContentProcessor.Process(Object input, ContentProcessorContext context)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAssetWorker(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.BuildAsset(BuildItem item)
at Microsoft.Xna.Framework.Content.Pipeline.BuildCoordinator.RunTheBuild()
at Microsoft.Xna.Framework.Content.Pipeline.Tasks.BuildContent.RemoteProxy.RunTheBuild(BuildCoordinatorSettings settings, TimestampCache timestampCache, ITaskItem[] sourceAssets, String[]& outputContent, String[]& rebuiltContent, String[]& intermediates, Dictionary`2& dependencyTimestamps, KeyValuePair`2[]& warnings)
C:\Projects\C#\XNA1\TileWorld\TileWorld\TileWorldContent\tileworldtest1.tilemap TileWorld

Вот код, который выдает эту ошибку.

string[] lines = input.Split(new char[] { '\n' });
// ------
// Clear out commented lines from the array. Turn it to a list, remove indices, turn back to array.
List<string> derp1 = new List<string>(lines);
for (int derp2 = 0; derp2 < derp1.Count; derp2++) {
    if (derp1[derp2][0] == ' ' || derp1[derp2][0] == ';') {
        derp1.RemoveAt(derp2);
        derp2--;
    }
}
lines = derp1.ToArray();
// ------
int rows = Convert.ToInt32(lines[1].Split('|')[0]);
int columns = Convert.ToInt32(lines[1].Split('|')[1]);

MapTile[,] res = new MapTile[rows, columns];

for (int i0 = 2; i0 < (rows + 2); i0++) {
    string[] tiles = lines[i0].Split(' ');

    for (int i1 = 0; i1 < columns; i1++) {
        string[] tileSprites = tiles[i1].Split('|');
-->     res[i0 - 2, i1].sprites = new Tile[tileSprites.Length];   <-- Exception

        for (int i2 = 0; i2 < tileSprites.Length; i2++) {
            string[] spriteData = tileSprites[i2].Split(':');

            res[i0 - 2, i1].sprites[i2] = new Tile(spriteData[0], Convert.ToInt32(spriteData[1]), new Vector2(Convert.ToInt32(spriteData[2]), Convert.ToInt32(spriteData[3])));
        }
    }
}
return new Map(res, lines[0]);

Этоклассы, которые я использую, чтобы сделать это дерево.Я удалил операторы использования, чтобы сократить этот вопрос.

//Map.cs
namespace LibTile {
    public class Map {
        public MapTile[,] grid { get; set; }
        public string MapName { get; set; }

        public Map(MapTile[,] value) {
            grid = value;
        }
        public Map(MapTile[,] value, string name) {
            grid = value;
            MapName = name;
        }

        public MapTile GetTile(int row, int col) {
            return grid[row, col];
        }

        public int Rows {
            get {
                return grid.GetLength(0);
            }
        }

        public int Columns {
            get {
                return grid.GetLength(1);
            }
        }
    }
}

.

//MapTile.cs
namespace LibTile {
    public class MapTile {
        public Tile[] sprites { get; set; }

        public MapTile(Tile[] value) {
            sprites = value;
        }
    }
}

.

//Tile.cs
namespace LibTile {
    public class Tile {
        public String SpritePageID;
        public int SpriteID;
        public Vector2 Offset;

        public Tile(String spid, int sid, int ox, int oy) {
            SpritePageID = spid;
            SpriteID = sid;
            Offset = new Vector2(ox,oy);
        }
        public Tile(String spid, int sid, Vector2 o) {
            SpritePageID = spid;
            SpriteID = sid;
            Offset = o;
        }
    }
}

1 Ответ

0 голосов
/ 03 января 2012

Вы создаете новый массив MapTile, но вы никогда не инициализируете отдельные элементы.Попробуйте это:

res[i0 - 2, i1] = new MapTile(new Tile[tileSprites.Length]);

Это создаст новый объект MapTile в каждой точке массива.Невыполнение этого требования привело к исключению из-за нулевой ссылки.Я также хотел бы рассмотреть возможность изменения конструктора MapTile без параметров, а затем просто установить MapTile.sprites, как вы делали раньше.

...