Matrix Object reference not set to an instance of an object

Hi all,

Currently I am making somewhat of a map using a grid. I got a grid working with extended and fusing fill rectangle, which worked.
Now I made a very basic sprite as a texture for the grid so I can alter the map to make roads/plants/objects etc.
I got the sprite loading and functioning in the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended;
using MonoGame.Extended.ViewportAdapters; 

namespace VikingFarmer
{
    class Map
    {
        private int TileWidth;
        private int TileHeight;
        private int Width;
        private int Height;
        public Animation grass; 
        public OrthographicCamera camera; 
        private GraphicsDevice Graphics; 

        public void Initialize(GameWindow window, GraphicsDevice graphics, int tileWidth, int  tileHeight, int width, int height, Texture2D grassTexture )
            {
            TileHeight = tileHeight;
            TileWidth = tileWidth;  
            Width = width;
            Height = height;
            Graphics = graphics;
            var viewPortAdapter = new BoxingViewportAdapter(window, graphics, 1600, 900) ;
            camera = new OrthographicCamera(viewPortAdapter);
            grass = new Animation();
            Vector2 position = Vector2.Zero;
            grass.Initialize(grassTexture, position, 16, 16, 1, 100, Color.White, 1f, true, 0);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    grass.Position.X = i * TileWidth;
                    grass.Position.Y = j * TileHeight;

                    grass.Draw(spriteBatch);
                }
            }
        }

        public void Update(GameTime gameTime, KeyboardState keyboardState, float playerMoveSpeed)
            {


                //keyboard movement
                if (keyboardState.IsKeyDown(Keys.A) || keyboardState.IsKeyDown(Keys.Left))
                {   

                camera.Move(new Vector2(-1, 0));
                }

                if (keyboardState.IsKeyDown(Keys.W) || keyboardState.IsKeyDown(Keys.Up))
                {
                camera.Move(new Vector2(0, -1));
                }
                if (keyboardState.IsKeyDown(Keys.D) || keyboardState.IsKeyDown(Keys.Right))
                {
                camera.Move(new Vector2(1, 0));
                }

                if (keyboardState.IsKeyDown(Keys.S) || keyboardState.IsKeyDown(Keys.Down))
                {
                camera.Move(new Vector2(0, 1));
                }

            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    grass.Position.X = i * TileWidth;
                    grass.Position.Y = j * TileHeight;

                    grass.Update(gameTime);
                }
            }
        }
        }
}

However, this does something which is pretty obvious namely drawing one instance of a sprite and updating it over the different positions leaving the last position as a single sprite instance, I knew this was gonna happen but was just to test the sprite. Therefore I made a multi-dimensional array to have multiple instances of the sprite and with it a grid that I can modify to my wishes.
The code resulted in this:

    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using MonoGame.Extended;
    using MonoGame.Extended.ViewportAdapters; 

    namespace VikingFarmer
    {
        class Map
        {
            private int TileWidth;
            private int TileHeight;
            private int Width;
            private int Height;
            public Animation[,] grass; 
            public OrthographicCamera camera; 
            private GraphicsDevice Graphics; 

            public void Initialize(GameWindow window, GraphicsDevice graphics, int tileWidth, int  tileHeight, int width, int height, Texture2D grassTexture )
                {
                TileHeight = tileHeight;
                TileWidth = tileWidth;  
                Width = width;
                Height = height;
                Graphics = graphics;
                var viewPortAdapter = new BoxingViewportAdapter(window, graphics, 1600, 900) ;
                camera = new OrthographicCamera(viewPortAdapter);
                grass = new Animation[Width, Height];
                Vector2 position = Vector2.Zero;
                for (int i = 0; i < Width; i++)
                {
                    for (int j = 0; j< Height; j++)
                    {
                        position.X = i * TileWidth;
                        position.Y = j * TileHeight; 
                        grass[i,j].Initialize(grassTexture,position,16,16,1,100,Color.White,1f,true,0);
                       
                    }
                }
                
            }

            public void Draw(SpriteBatch spriteBatch)
            {
                for (int i = 0; i < Width; i++)
                {   
                    for (int j = 0; j < Height; j++)
                    {
                        grass[i, j].Draw(spriteBatch);
                    }
                }
            }

            public void Update(GameTime gameTime, KeyboardState keyboardState, float playerMoveSpeed)
                {


                    //keyboard movement
                    if (keyboardState.IsKeyDown(Keys.A) || keyboardState.IsKeyDown(Keys.Left))
                    {   

                    camera.Move(new Vector2(-1, 0));
                    }

                    if (keyboardState.IsKeyDown(Keys.W) || keyboardState.IsKeyDown(Keys.Up))
                    {
                    camera.Move(new Vector2(0, -1));
                    }
                    if (keyboardState.IsKeyDown(Keys.D) || keyboardState.IsKeyDown(Keys.Right))
                    {
                    camera.Move(new Vector2(1, 0));
                    }

                    if (keyboardState.IsKeyDown(Keys.S) || keyboardState.IsKeyDown(Keys.Down))
                    {
                    camera.Move(new Vector2(0, 1));
                    }

                for (int i = 0; i < Width; i++)
                {
                    for (int j = 0; j < Height; j++)
                    {
                        grass[i, j].Update(gameTime);
                    }
                }
            }
            }
    }

The issue I know have is that when I run the code I get the error: System.NullReferenceException: Object Reference not set to an instance of an object.
From what I understand this has to do with something not being initialized, however what is the thing that hasnt been initialized then? Since the code with a single instance works.

I am a beginner in programming and am trying to teach myself methods of debugging and understanding error codes and so on, so far I have managed pretty nicely (with one other exception with key input, but that was a good learning experience in coding logic)
However, with this code I couldnt find ways to trial and error to find the issue, does anybody have tips how to find problems with these kind of error codes (other then google, which got me to the conclusion something wasn’t initialized)

Thanks a lot for tips, you guys rock

System null reference exception is probably the number one error you will see it almost always indicates you forgot to do something you normally would do.

So first off ill make a common example and show how to debug it.

lets take for example some common things you are probably using like spriteBatch you might set this up in initialize or load content.

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);

            currentFont = Content.Load<SpriteFont>("MgGenFont");
            defaultTexture = Content.Load<Texture2D>("CheckerBoardTemplateImage");

Now sometimes its useful when you are learning, to actually create a bug, in order to understand how solve a bug, which is what well do.

So i comment out the line with spriteBatch.

//spriteBatch = new SpriteBatch(GraphicsDevice);

As you can imagine spriteBatch isn’t going to work unless its been initialized so when i build and run this what happens?

Well i build it theres no problem but…

1> C:\Users.…\bin\DesktopGL\AnyCPU\Debug\AssimpLoaderExample.deps.json
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

When i run the code.

The first time i try to actually use the un-intialized spriteBatch reference i get an error … from the Operating System on the Reference the reason is because it is Null.

    protected void DrawSpriteBatches(GameTime gameTime)
    {
    ...
    spriteBatch.Begin(SpriteSortMode.Immediate);

Now if you look at the image you will also see at the bottom a few tabs like output which gives useful information and a call stack.
Typically clicking on this will show were the error occured clicking the next one down will show the method that called the error method and so on and so forth.

AssimpLoaderExample.exe!AssimpLoaderExample.Game1_DebugModelViewer.DrawSpriteBatches(Microsoft.Xna.Framework.GameTime gameTime = {Microsoft.Xna.Framework.GameTime}) Line 601 C#
AssimpLoaderExample.exe!AssimpLoaderExample.Game1_DebugModelViewer.Draw(Microsoft.Xna.Framework.GameTime gameTime = {Microsoft.Xna.Framework.GameTime}) Line 593 C#

As you already know the reason why this particular error occured because we created it here … aka …
We commented out the initialization of spriteBatch

Then to fix it we of course simply undo what we did. So we make sure it is initialized and un-comment it, so that it gets set up and the reference isn’t null.

spriteBatch = new SpriteBatch(GraphicsDevice);

Now you can do the same thing for a matrix or pretty much any type.
Typically when you declare a matrix reference you also initialize it like so.

Matrix myMatrix = Matrix.Identity;

Now even though there is no new call here to instantiate the type reference myMatrix, internally this c# class has some shortcuts that allow the Matrix.Identity call here to do all that under the hood for you. This is in fact the same thing as doing …
Matrix myMatrix = new Matrix( ,,, );

So when you get a null reference error first find were you declare the reference type variable that is in error.

Matrix myMatrix;
or
SpriteBatch mySpriteBatch;

Then figure out were you wanted to or were supposed to set it up or initialize it with …
= new Matrix(); or = Matrix.Identity; ect… but forgot to.

Hi Will,

Thanks about the tip about the call-stack that one helped with some other things that I had read.
Turned out I didn’t properly initialize every instance of grass.

            grass = new Animation[Width, Height];
            Vector2 position = Vector2.Zero;
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j< Height; j++)
                {
                    //grass[i,j] = new Animation();
                    position.X = i * TileWidth;
                    position.Y = j * TileHeight; 
                    grass[i,j].Initialize(grassTexture,position,16,16,1,100,Color.White,1f,true,0);
                   
                }
            }

Adding commented line solved everything. I will keep in mind to make my own little bugs once in a while :wink: