我是编程新手。我正在使用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();
}
}
}
答案 0 :(得分:0)
如果问题仅是空引用异常,请尝试通过查看异常发生的位置来调试代码。我也建议您阅读以下内容:What is a NullReferenceException, and how do I fix it?
简而言之:发生空引用异常是因为游戏期望变量中有一个值,但未设置该变量。 (并且“未设置”的标准值为null)。
我认为这是因为未设置_state
,并且您的Switch语句没有default
大小写。因此,如果它读取的情况未定义,它将崩溃。
那只是我的假设。要了解确切的问题,您必须尝试对其进行调试,并找出异常发生的时间和地点。