2012-01-02 8 views
1

タイルマップのインポーターをビルドしようとしているときにC#でこのエラーが発生しました。このようにフォーマットされたファイルを読むはずです。NullReferenceException、これはどのように処理するのですか?

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 

基本的には、最初の行にマップ名を有する第2の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]); 

これらは私がこのツリーを作るのに使うクラスです。この質問を短縮するためにusingステートメントを削除しました。

//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; 
     } 
    } 
} 
+0

'locals'リストのヌルプロパティとは何ですか? – annonymously

答えて

0

MapTileという新しい配列を作成しますが、個々の要素は決して初期化しません。これを試してみてください:これは、配列の各poitionに新しいMapTileオブジェクトを作成します

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

。これを行わないと、null参照例外が発生していました。私はまた、MapTileのコンストラクタをパラメータなしに変更してから、以前のようにMapTile.spritesを設定することを検討します。

+0

ありがとう!それはそれを修正した。私はそれが初期化されていないこれらの事のいずれかと関係があることを知っていましたが、私はこのバリエーションを試みたことはありません。コンストラクタの提案は良いものです。私は空のコンストラクタを追加します。 – CELLShock

関連する問題