NullReferenceException未处理-不知道原因

本文关键字:不知道 未处理 NullReferenceException | 更新日期: 2023-09-27 18:24:07

我正在尝试用XNA编写一个非常基本的自上而下的2D游戏,我已经开始尝试在游戏中添加草纹理,然后将这些纹理绘制到屏幕的底部。

然而,我在Level.cs类的第32行收到一个"NullReferenceException未处理"错误。由于我只是XNA的新手,(相比之下)C#的新手,我一辈子都无法理解这一点。

更新1: 感谢mcmonkey4eva,该错误已解决。然而,我的代码现在在我的TestLevel类(Level.cs)的Draw()方法中停止了。错误仍然是"NullReferenceException was Unhandled"错误,并且这些方法与以前有点不同。

有人知道我在这里做错了什么吗?


这是我更新的Level.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.Content;
using First.Tiles;
using First;

namespace First.Level
{
    class TestLevel
    {
        //An array of groundtiles that will be set to grass, lava, etc
        public GroundTile[,] groundlevel;
        //Width/Height of the Level
        int width, height;
        Grass grass;
        public TestLevel(int width, int height, ContentManager myContent)
        {
            content = myContent;
            //I input my screen dimensions as my level size
            this.width = width;
            this.height = height;
            groundlevel = new GroundTile[width, height];
            grass = new Grass(content.Load<Texture2D>(@"Images'GroundTiles"));
        }
        //Drawing the grass near the bottom of the screen
        public void generateGround()
        {
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x += 32)
                {
                    if (y == (height - 100))
                    {
                        if (groundlevel[x, y] == null)
                        {
                            groundlevel[x, y] = grass;
                        }
                    }
                }
            }
        }
        public void draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach(GroundTile ground in groundlevel)
            {
                ground.Draw(gameTime, spriteBatch); //Here's where the error is
            }
        }
        public static ContentManager Content
        {
            get { return content; }
        }
        static ContentManager content;
    }
}

这是我更新的Game1.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;
using First.Entity;
using First.Tiles;
using First.Level;
namespace First
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        const int SCREEN_WIDTH = 600;
        const int SCREEN_HEIGHT = 400;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        TestLevel level;
        UserControlledSprite Lancer;
        Texture2D lancerTexture;
        Vector2 position = new Vector2(200, 200);
        Point frameSize = new Point(32, 48);
        int collisionOffset = 0;
        Point currentFrame = new Point(0, 0);
        Point sheetSize = new Point(4, 4);
        Point spriteToUse = new Point(0, 0);
        Vector2 speed = new Vector2(2, 2);
        int millisecondsPerFrame = 500;
        Rectangle clientBounds;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            clientBounds = graphics.GraphicsDevice.Viewport.Bounds;
            clientBounds.Width = SCREEN_WIDTH;
            clientBounds.Height = SCREEN_HEIGHT;
            this.IsMouseVisible = true;
            base.Initialize();
        }
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            Content.RootDirectory = "Content";
            level = new TestLevel(SCREEN_WIDTH, SCREEN_HEIGHT, Content);
            level.generateGround();
            lancerTexture = Content.Load<Texture2D>(@"Images'Lancer");
            Lancer = new UserControlledSprite(lancerTexture, position, frameSize, collisionOffset,
                                              currentFrame, sheetSize, spriteToUse, speed, millisecondsPerFrame);
        }
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            Lancer.Update(gameTime, clientBounds);
            base.Update(gameTime);
        }
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            Lancer.Draw(gameTime, spriteBatch);
            level.draw(gameTime, spriteBatch);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

这是我的Grass.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.Content;
using First.Tiles;
using First;

namespace First.Level
{
    class TestLevel
    {
        //An array of groundtiles that will be set to grass, lava, etc
        public GroundTile[,] groundlevel;
        //Width/Height of the Level
        int width, height;
        Grass grass;
        public TestLevel(int width, int height, ContentManager myContent)
        {
            content = myContent;
            //I input my screen dimensions as my level size
            this.width = width;
            this.height = height;
            groundlevel = new GroundTile[width, height];
            grass = new Grass(content.Load<Texture2D>(@"Images'GroundTiles"));
        }
        //Drawing the grass near the bottom of the screen
        public void generateGround()
        {
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x += 32)
                {
                    if (y == (height - 100))
                    {
                        if (groundlevel[x, y] == null)
                        {
                            groundlevel[x, y] = grass;
                        }
                    }
                }
            }
        }
        public void draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            foreach(GroundTile ground in groundlevel)
            {
                ground.Draw(gameTime, spriteBatch);
            }
        }
        public static ContentManager Content
        {
            get { return content; }
        }
        static ContentManager content;
    }
}

以防万一,这也是我的GroundTile类:

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.Content;
using First.Entity;
namespace First.Tiles
{
    class GroundTile
    {
        //public GroundTile grass = new Grass(content.Load<Texture2D>(@"Images'GroundTiles"));
        // frameSize needs to be modular, for the objects above walking-ground level
        public Texture2D texture;
        protected Point frameSize;
        public Point frame;
        public Vector2 position;
        int collisionOffset;
        protected Point sheetSize = new Point(9, 19);
        public GroundTile(Texture2D tiles, Point frame, Point frameSize, int collisionOffset)
        {
            this.frame = frame;
            this.frameSize = frameSize;
            this.collisionOffset = collisionOffset;
            this.texture = tiles;
        }
        //Collision Detection, incase of water or something
        public Rectangle collisionRect
        {
            get
            {
                return new Rectangle(
                    (int)position.X + collisionOffset,
                    (int)position.Y + collisionOffset,
                    frameSize.X - (collisionOffset * 2),
                    frameSize.Y - (collisionOffset * 2));
            }
        }
        //Not really used, but just in case
        public bool collidesWith(GroundTile tile, Sprite sprite)
        {
            if (sprite.collisionRect.Intersects(collisionRect))
            {
                sprite.position -= sprite.direction;
            }
            return false;
        }
        public static ContentManager Content
        {
            get { return content; }
        }
        static ContentManager content;
        public GraphicsDevice Graphicsdevice
        {
            get { return graphicsDevice; }
        }
        GraphicsDevice graphicsDevice;
        public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(texture,
                position,
                new Rectangle(frame.X * frameSize.X,
                    frame.Y * frameSize.Y,
                    frameSize.X, frameSize.Y),
                    Color.White, 0, Vector2.Zero,
                    1f, SpriteEffects.None, 0);
        }
    }
}

NullReferenceException未处理-不知道原因

您在设置Content之前访问它,或者说,您根本没有设置它。

更改

public TestLevel(int width, int height)
{
    //I input my screen dimensions as my level size

public TestLevel(int width, int height, ContentManager myContent)
{
    content = myContent;
    //I input my screen dimensions as my level size

然后在创建TestLevel对象时添加Content参数(我假设来自Game1.cs)(注意:请确保在[在LoadContent方法中]创建Content对象后创建TestLevel!)

编辑:

针对新问题:

你没有定义数组的内容,除了一层草。。。

线路

            ground.Draw(gameTime, spriteBatch);

更改为

            if (ground != null)
            {
                 ground.Draw(gameTime, spriteBatch);
            }

但你也应该确保地面上确实充满了内容。。。特别是,阵列中每个点的新平铺对象,而不仅仅是一条线,也不仅仅是每个位置的同一个"草"实例。

我无意冒犯,但你在处理一些非常基本的错误。查阅并遵循一些基本的C#教程可能对您有益。

我不知道XNA,但很明显你很满意。返回null。

这是类名还是级别类的属性?如果它是一个属性,请确保它已初始化。另外,如果您调用类的静态属性

,我不明白您是如何收到nullreferenceexception的