-1

I'm pretty new to programming. I'm developing a 2D game using monogame where you have to run around killing enemies and jumping from one moving tile to another trying not to fall on the spikes and die.
I almost have everything of the mechanics, collision. I want to start making multiple levels, a beginscreen where you have to press s to start and when you die a gameover screen.
I have implemented gamestates. the program starts on the first state(menu) where you get a picture that says press S to start but when i press S to start the program crashes and I get a null reference exeption... but if I don't use the menu state as the first state and instead I use the level1 gamestate the game works so there is no null reference exeption (but you don't get the menuscreen of course).

I'm doing something wrong but i cant find it. I will paste my game1.cs below. I think that's where the problem is. if you need something else please ask.

please help, thanks in advance. ps: sorry for the large amount of code but the problem could be everywhere

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace ninjaprincess
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        //Game states http://community.monogame.net/t/switch-scenes-in-monogame/2605
        enum GameState
        {
            Menu,
            GamePlayLevel1,
            EndGame
        }
        GameState _state;
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Hero ninja;
        private Texture2D ninjasprite;
        private Texture2D background;
        private LevelDesign level;
        private Texture2D StartScreen;
        Camera camera;
        bool start;

        List<Knife> knives = new List<Knife>();
        KeyboardState pastkey;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            /// dit toevoegen voor fullscreen////
            graphics.PreferredBackBufferHeight = 1080;
            graphics.PreferredBackBufferWidth = 1920;
            graphics.IsFullScreen = true;
        }

        protected override void Initialize()
        {
            camera = new Camera(GraphicsDevice.Viewport);
            base.Initialize();
        }

        protected override void LoadContent()
        {

            spriteBatch = new SpriteBatch(GraphicsDevice);
            level = new LevelDesign();
            background = Content.Load<Texture2D>("background");
            ninja = new Hero(ninjasprite, new Vector2(10, 20));
            ninja.Content(Content);
            level.content = Content;
            StartScreen = Content.Load<Texture2D>("Startscherm");

            Block.Content = Content;
            level.tileArray = new byte[,]
            {
            { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            { 0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            { 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0},
            { 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,0,4,4,4,0,0,0,0},
            { 0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0},
            { 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0},
            { 0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
            { 0,0,1,1,1,0,0,0,0,0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0}
            };

            level.CreateWorld(105);
            ninja.controllers = new KeyboardArrows();
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// game-specific content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            if (_state == GameState.GamePlayLevel1)
            {
                camera.Update(ninja.Position, level.Width + 400, 1080);
                ninja.Update(gameTime);

                if (ninja.controllers.shooting && pastkey.IsKeyUp(Keys.Space))
                {
                    ShootKnife();
                }
                pastkey = Keyboard.GetState();
                UpdateKnife();

                foreach (Block block in level.blockArray)
                {

                    if (block is Grass)
                    {
                        ninja.CollideOnGrass(block.Rectangle);
                    }
                    if (block is Spikes)
                    {
                        ninja.CollideOnSpikes(block.Rectangle);
                    }
                    if (block is MovingGrassLeft)
                    {
                        ninja.CollideOnGrass(block.Rectangle);
                        block.Update(gameTime);
                    }
                }

                foreach (Enemy enemy in level.enemyArray)
                {

                    if (enemy is Enemy)
                    {
                        ninja.CollideOnEnemy(enemy.EnemyRectangle, 2840, 1080, level.enemyArray, (enemy.EnemyRectangle.X - (enemy.EnemyRectangle.Width / 3)), enemy.EnemyRectangle.Y + (enemy.EnemyRectangle.Height / 2));
                        enemy.Update(gameTime);

                    }
                }

                if (ninja.isAlive == false)
                {
                    _state = GameState.EndGame;

                }
            }

            base.Update(gameTime);
            switch (_state)
            {
                case GameState.Menu:
                    UpdateMenu(gameTime);
                    break;
                case GameState.GamePlayLevel1:
                    UpdateGameplay(gameTime);
                    break;
                case GameState.EndGame:
                    UpdateEndGame(gameTime);
                    break;
            }

        }

        void UpdateMenu(GameTime gametime)
        {
            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.S))
                _state = GameState.GamePlayLevel1;
            else if (keyState.IsKeyDown(Keys.Q))
                Exit();
        }

        void UpdateGameplay(GameTime gametime)
        {
            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.Escape))
                _state = GameState.Menu;

        }

        void UpdateEndGame(GameTime gametime)
        {

            KeyboardState keyState = Keyboard.GetState();
            if (keyState.IsKeyDown(Keys.Q))
                Exit();
            if (keyState.IsKeyDown(Keys.S))
                _state = GameState.GamePlayLevel1;
        }

        public void UpdateKnife()
        {
            foreach (Knife knife in knives)
            {

                knife.position.X += 25f;
                for (int i = 1; i < knives.Count; i++)
                {
                    if (knives[i].isVisible == false)
                    {
                        knives.RemoveAt(i);
                        i--;
                    }
                }
            }
        }

        public void ShootKnife()
        {
            Knife newKnife = new Knife(Content.Load<Texture2D>("KunaiRight"));
            newKnife.isVisible = true;
            newKnife.velocity.X = 3f;
            newKnife.position = new Vector2(ninja.Position.X, ninja.Position.Y + (ninja.PlayerRectangle.Height / 2));

            if (knives.Count < 50)
            {
                knives.Add(newKnife);
            }
        }

        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            switch (_state)
            {
                case GameState.Menu:
                    DrawMenu(gameTime);
                    break;
                case GameState.GamePlayLevel1:
                    DrawGamePlayLevel1(gameTime);
                    break;
                case GameState.EndGame:
                    DrawEndGame(gameTime);
                    break;
            }
            base.Draw(gameTime);
        }

        void DrawMenu(GameTime GameTime)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(StartScreen, new Rectangle(0, 0, 1920, 1080), Color.AliceBlue);
            spriteBatch.End();
        }

        void DrawGamePlayLevel1(GameTime GameTime)
        {
            GraphicsDevice.Clear(Color.White);
            spriteBatch.Begin();
            spriteBatch.Draw(background, new Rectangle(0, 0, 1920, 1080), Color.White);
            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, null, null, null, null, camera.Transform);
            level.DrawLevel(spriteBatch);
            ninja.Draw(spriteBatch);
            foreach (Knife knife in knives)
            {
                knife.Draw(spriteBatch);
            }
            spriteBatch.End();

        }
        void DrawEndGame(GameTime GameTime)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(StartScreen, new Rectangle(0, 0, 1920, 1080), Color.White);
            spriteBatch.End();
        }
    }
}
Steven
  • 1,996
  • 3
  • 22
  • 33
  • 266 lines is way too much. Please trim it down to a [MCVE] – CertainPerformance Aug 19 '18 at 00:39
  • Null ref are usually somehow easy to find in debug bug since the application should stop at the exact point of failure, allowing you to find it. The code you provided is both too big and incomplete for someone else to debug it. So simply run it again in debug and see where it fails. – abousquet Aug 19 '18 at 23:15

1 Answers1

0

If the problem is only a nullreference Exception, then try debugging your code by looking where the exception happens. I also recommend reading this: What is a NullReferenceException, and how do I fix it?

In a nutshell: Nullreference exceptions happens because the game's expecting a value in a variable, but that variable is not set. (and the standard value of 'not set' is null).


I think it's because your _state isn't set, and your Switch statements doesn't have a default case. So if It reads something that's not defined in the cases, it'll crash.

That's just my assumption though. To know the exact problem, you have to try debugging it and find where and when the exception occurs.

Steven
  • 1,996
  • 3
  • 22
  • 33