初始化数组后出现Nullreferenceexception

时间:2015-07-23 17:12:57

标签: c# xna visual-studio-2015

我一直在尝试在XNA中进行测试游戏(visual studio 2015),但每次加载时我都会得到一个NullReferenceException,即使我实际上已经初始化它。这是一个很短的版本...

    namespace Overbox
    {
        public class Player
        {
             private Player[] characterList = new Player[14];

             virtual public void Initialize()
             {
                  //characterList = new Player[14];
                  characterList[0] = new Hero();

                  //for (int i = 0; i <= characterList.Length; i++)
                  //    characterList[i].Initialize();
                  characterList[0].Initialize();
             }
    }
    virtual public void Draw(SpriteBatch spriteBatch, Texture2D texture)
    {
        //for (int i = 0; i <= characterList.Length; i++)
        //{
        //    if (characterList[i].Active)
        //        characterList[i].Draw(spriteBatch, texture);
        //}
        characterList[0].Draw(spriteBatch, texture); //Here the error occurs
    }



   }
}

如果有人因为任何原因想要全班,我可以编辑这个,但这是我能找到的所有相关代码。

编辑:堆栈跟踪

  

Overbox.exe!Overbox.Player.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch,Microsoft.Xna.Framework.Graphics.Texture2D纹理)第53行C#       Overbox.exe!Overbox.MediaHandler.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)第54行C#

     

Overbox.exe!Overbox.Program.Main(string [] args)第15行C#

一切都应该在那里。

英雄课程:

    namespace Overbox.Characters
    {
         class Jacketed : Player
         {
         override public void Initialize()
         {
                //Unrelated setting of variables
         }
         public override void Draw(SpriteBatch spriteBatch, Texture2D texture)
         {
                spriteBatch.Draw(texture, PlayerPosition, Color.White);
         }
    }
}

游戏循环类的非常短版本:

  public class Game1 : Microsoft.XNA.Framework.Game
  {
        public static Player player;
        //I do load the content which playerTexture requires before anyone asks about it
        private Texture2D playerTexture;


        protected override void Initialize()
        {
               player = new Player();
               player.Initialize();
        }
        protected override void Draw(GameTime gameTime)
        {
               spriteBatch.Begin();

               player.Draw(spriteBatch, playerTexture);

               spriteBatch.End();
        }
  }

3 个答案:

答案 0 :(得分:1)

private Player[] characterList = new Player[14];

创建一个Player数组,但实际上并不构造对象。所以你最终得到的基本上是一个充满空值的数组。

你遗失了这样的东西:

public Player()
{
    foreach (var character in characterList)
    {
        character = new Player();
    }
}

答案 1 :(得分:0)

这是一个疯狂的猜测,但我假设Hero会覆盖其中一个或两个或InitializeDraw。让我们说Hero看起来像这样:

class Hero : Player
{
    public override void Initialize()
    {
        // Do some stuff. Don't call base.Initialize()
    }
}

所以我们覆盖了Initialize(),但没有调用base.Initialize()。我们也没有覆盖Draw(),因此在Draw()个实例上调用Player时会使用Hero

因此,让我们考虑构建Player player的时间。然后还会创建player.characterList,但其元素为null。接下来,调用player.Initialize(),设置characterList[0] = new Hero()。请注意,characterList[0]也有自己的characterList数组。

接下来要发生的是characterList[0].Initialize()。这称为Initialize()中的Hero覆盖。这不会在Initialize()内调用Player,因此characterList实例中的Hero仍然有null元素。

将来的某个时间,Draw会调用Player方法。反过来,这会调用characterList[0].Draw(spriteBatch, texture)。由于我们没有覆盖Draw中的Hero方法,因此调用相同的方法,但是在我们的Hero实例上。但请记住,Hero characterList仍有null个值?好吧,这里唯一要做的就是调用characterList[0].Draw(spriteBatch, texture),正如我们现在所知,它正在Draw上调用null

这是我对正在发生的事情的猜测。细节可能会有所不同,但我想这种事情是根本原因。当然,请检查异常的堆栈跟踪。您会注意到Draw方法的两个框架,让您知道在Draw的递归调用中发生了异常。

答案 2 :(得分:0)

我已经考虑过这个解决方案一段时间了,但由于组织原因,我不想这样做。我所要做的就是将characterList移动到主游戏循环类并将其公之于众,保证在调用draw方法之前将其初始化。这确实有用。