使用游戏状态时程序崩溃(白屏)

时间:2018-08-18 22:48:13

标签: c# visual-studio xna monogame

我是编程新手。我正在使用monogame开发2D游戏,您必须四处奔走杀死敌人并从一个移动的砖块跳到另一个砖块,以免落在尖峰上而死。
我几乎掌握了所有的力学原理,碰撞原理。我想开始制作多个关卡,一个开始屏幕,您必须按s才能开始,以及当游戏结束屏幕消失时。
我已经实现了游戏状态。程序在第一个状态(菜单)上启动,在该状态下您会看到一张图片,说按S键开始,但是当我按S键启动时,程序崩溃了,我得到了一个空引用实例...但是如果我不使用菜单状态作为第一个状态,而我使用level1 gamestate进行游戏,因此没有null引用异常(但您当然不会获得菜单屏幕)。

我做错了什么,但我找不到。我将在下面粘贴我的game1.cs。我认为这就是问题所在。如果您还需要其他东西,请询问。

请帮助,在此先感谢。 ps:对不起,代码量很大,但问题可能无处不在

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();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果问题仅是空引用异常,请尝试通过查看异常发生的位置来调试代码。我也建议您阅读以下内容:What is a NullReferenceException, and how do I fix it?

简而言之:发生空引用异常是因为游戏期望变量中有一个值,但未设置该变量。 (并且“未设置”的标准值为null)。


我认为这是因为未设置_state,并且您的Switch语句没有default大小写。因此,如果它读取的情况未定义,它将崩溃。

那只是我的假设。要了解确切的问题,您必须尝试对其进行调试,并找出异常发生的时间和地点。