NullReferenceException in xna



我试图创建一个简单的游戏来测试碰撞检测,但它不会正常运行。它构建得很好,但我得到这个错误在运行它:"NullReferenceException:对象引用不设置为对象的实例"。

SpriteManager.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Project_3
{
    public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private Game1 _Game1;
        //SpriteBatch for drawing
        SpriteBatch spriteBatch;
        //A sprite for the player and a list of automated sprites
        UserControlledSprite player;
        List<Sprite> spriteList = new List<Sprite>();

        public SpriteManager(Game1 game)
            : base(game)
        {
            // TODO: Construct any child components here
            _Game1 = game;
        }
        public override void Initialize()
        {
            // TODO: Add your initialization code here
            base.Initialize();
        }
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            //Load the player sprite
            player = new UserControlledSprite(
                Game.Content.Load<Texture2D>("Images/bill"),
                Vector2.Zero, 10, new Vector2(6, 6));
            //Load several different automated sprites into the list
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/kit"),
                new Vector2(150, 150), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/kit"),
                new Vector2(300, 150), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/beast"),
                new Vector2(150, 300), 10, Vector2.Zero));
            spriteList.Add(new AutomatedSprite(
                Game.Content.Load<Texture2D>("Images/beast"),
                new Vector2(600, 400), 10, Vector2.Zero));
            base.LoadContent();
        }
        public override void Update(GameTime gameTime)
        {
            // Update player
            player.Update(gameTime, Game.Window.ClientBounds);
            // Update all sprites
            foreach (Sprite s in spriteList)
            {
                s.Update(gameTime, Game.Window.ClientBounds);
            }
            base.Update(gameTime);
        }
        public override void Draw(GameTime gameTime)
        {
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
            // Draw the player
            player.Draw(gameTime, spriteBatch);
            // Draw all sprites
            foreach (Sprite s in spriteList)
                s.Draw(gameTime, spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

抛出异常的行是SpriteManager中的player.Update(gameTime, Game.Window.ClientBounds);。完整的异常消息是"System类型的未处理异常"。在Project 3.exe中发生了NullReferenceException。附加信息:对象引用未设置为对象的实例。"

UserControlledSprite.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Project_3
{
class UserControlledSprite : Sprite
{
    // Movement stuff
    MouseState prevMouseState;
    // Get direction of sprite based on player input and speed
    public override Vector2 direction
    {
        get
        {
            Vector2 inputDirection = Vector2.Zero;
            // If player pressed arrow keys, move the sprite
            if (Keyboard.GetState().IsKeyDown(Keys.Left))
                inputDirection.X -= 1;
            if (Keyboard.GetState().IsKeyDown(Keys.Right))
                inputDirection.X += 1;
            if (Keyboard.GetState().IsKeyDown(Keys.Up))
                inputDirection.Y -= 1;
            if (Keyboard.GetState().IsKeyDown(Keys.Down))
                inputDirection.Y += 1;
            // If player pressed the gamepad thumbstick, move the sprite
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            if (gamepadState.ThumbSticks.Left.X != 0)
                inputDirection.X += gamepadState.ThumbSticks.Left.X;
            if (gamepadState.ThumbSticks.Left.Y != 0)
                inputDirection.Y -= gamepadState.ThumbSticks.Left.Y;
            return inputDirection * speed;
        }
    }
    public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
    {
    }
    public override void Update(GameTime gameTime, Rectangle clientBounds)
    {
        // Move the sprite based on direction
        position += direction;
        // If player moved the mouse, move the sprite
        MouseState currMouseState = Mouse.GetState();
        if (currMouseState.X != prevMouseState.X ||
            currMouseState.Y != prevMouseState.Y)
        {
            position = new Vector2(currMouseState.X, currMouseState.Y);
        }
        prevMouseState = currMouseState;
        // If sprite is off the screen, move it back within the game window
        if (position.X < 0)
            position.X = 0;
        if (position.Y < 0)
            position.Y = 0;
        if (position.X > clientBounds.Width - 150)
            position.X = clientBounds.Width - 150;
        if (position.Y > clientBounds.Height - 150)
            position.Y = clientBounds.Height - 150;
        base.Update(gameTime, clientBounds);
    }
}
}

我不知道为什么它不工作。我已经尝试了很多不同的东西,但由于我是xna的新手,我可能错过了一些简单的东西。

任何帮助都将是非常感激的。

编辑:忘记添加Sprite.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Project_3
{
    abstract class Sprite
    {
    // Stuff needed to draw the sprite
    Texture2D textureImage;
    // Collision data
    int collisionOffset;
    // Movement data
    protected Vector2 speed;
    protected Vector2 position;
    // Abstract definition of direction property
    public abstract Vector2 direction
    {
        get;
    }
    public Sprite()
    {
    }
    public Sprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
    //: this(textureImage, position, collisionOffset, speed)
    {
    }
    public virtual void Update(GameTime gameTime, Rectangle clientBounds)
    {
    }
    public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        // Draw the sprite
        if (textureImage != null)
        {
            spriteBatch.Draw(textureImage, position, Color.White);
        }
    }
    // Gets the collision rect based on position, framesize and collision offset
    public Rectangle collisionRect
    {
        get
        {
            return new Rectangle(
                (int)position.X + collisionOffset,
                (int)position.Y + collisionOffset,
                150 - (collisionOffset * 2),
                150 - (collisionOffset * 2));
        }
    }

    public Game1 _Game1 { get; set; }
}
}

您没有实例化position。您将position变量传递给UserControlledSprite的构造函数,但不将其应用于类范围内的变量。您需要声明另一个变量来保存position变量,该变量仅对构造函数方法可见。

这意味着UserControlledSprite对象第一次调用Update时,position += direction;将抛出NullReferenceException。老实说,我不知道你怎么没有得到编译时错误,因为position将不存在于Update的上下文中,除非你没有向我们展示整个代码。

对不起,我还不能发表评论。

当你创建一个玩家(UserControlledSprite)时,你似乎不需要从"UserControlledSprite(…parameters…)"中调用Sprite构造函数。

public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed)
{
}

可能需要是:

public UserControlledSprite(Texture2D textureImage, Vector2 position, int collisionOffset, Vector2 speed) 
    : base(TextureImage, position, collisionOffset, speed)
{
}

设置要传递的数据也很有用。所以你传入textureImage, position, collisionOffset和speed。我看到您在Sprite类中拥有变量,但我没有看到您在使用构造函数创建它们时设置它们。除非,告诉我如果是这种情况,请传递与变量自动设置的名称相同的参数?如果不是这样,那么确保你在sprite类中实际设置了position, collisionOffset, speed和textureImage到它们实际传递的参数。我一直认为你不能在参数中使用与类的变量相同的名称。

所以你必须这样做(如果上面是真的):

public UserControlledSprite(Texture2D _textureImage, Vector2 _position, int _collisionOffset, Vector2 _speed) 
    : base(_textureImage, _position, _collisionOffset, _speed)
{
    //Do this either here or in Sprite. 
    this.textureImage = _textureImage;
    this.position = _position;
    this.collisionOffset = _collisionOffset;
    this.speed = _speed.
}    
我认为上面(紧接在这上面)的细节对你当前的问题不是那么重要。我认为它与构造函数有更多的关系,但我不确定。我这里没有VS,只是想试着帮你解决这个问题。无论如何,我希望这对你有帮助。抱歉,如果可以的话我会评论的。可惜我还不能。

最新更新