构建代码时,它构建正常,但不会运行。每当精灵使用精灵类中的变量时,调试它会导致Nullreferenceexception错误(Setup()的第一个实例
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;
namespace BilliardsEngine2D
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Sprite CueBall;
Sprite DirectionArrow;
Sprite RedBall;
SpriteFont myFont;
//SoundEffect HitCue;
//SoundEffect Collision;
int ScreenWidth, ScreenHeight;
float distance = 0.0f;
public static float MasterVolume { get; set; }
KeyboardState oldState;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 500;
graphics.PreferredBackBufferWidth = 750;
}
protected override void Initialize()
{
Setup();
SoundEffect.MasterVolume = 0.01f;
base.Initialize();
}
private void Setup()
{
ScreenHeight = graphics.GraphicsDevice.Viewport.Height;
ScreenWidth = graphics.GraphicsDevice.Viewport.Width;
CueBall.Rotation = 0.0f;
DirectionArrow.Rotation = CueBall.Rotation;
CueBall.Velocity = Vector2.Zero;
CueBall.Position = new Vector2(ScreenWidth / 2, ScreenHeight / 2);
DirectionArrow.Position = CueBall.Position;
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
CueBall = new Sprite(Content.Load<Texture2D>("Sprites/CueBall"));
DirectionArrow = new Sprite(Content.Load<Texture2D>("Sprites/Arrow"));
RedBall = new Sprite(Content.Load<Texture2D>("Sprites/RedBall"));
myFont = Content.Load<SpriteFont>("LucidaSans");
}
protected override void Update(GameTime gameTime)
{
KeyboardState newState = Keyboard.GetState();
if (newState.IsKeyDown(Keys.Escape)) //Pause
{
Exit();
}
if (newState.IsKeyDown(Keys.Left)) //Rotate Left
{
CueBall.Rotation -= 0.05f;
DirectionArrow.Rotation = CueBall.Rotation;
}
if (newState.IsKeyDown(Keys.Right)) //Rotate Right
{
CueBall.Rotation += 0.05f;
DirectionArrow.Rotation = CueBall.Rotation;
}
if (newState.IsKeyDown(Keys.Space) && oldState.IsKeyUp(Keys.Space)) //Power Up
{
}
if (newState.IsKeyUp(Keys.Space) && oldState.IsKeyDown(Keys.Space)) //Fire
{
HitCueBall();
}
oldState = newState;
SideCollision();
//BallCollision();
base.Update(gameTime);
}
private void AccelerateCueBall() //
{
CueBall.Velocity += new Vector2(
(float)(Math.Cos(CueBall.Rotation - MathHelper.PiOver2) * 0.05f),
(float)((Math.Sin(CueBall.Rotation - MathHelper.PiOver2) * 0.05f)));
if (CueBall.Velocity.X > 7.5f)
{
CueBall.Velocity = new Vector2(5.0f, CueBall.Velocity.Y);
}
if (CueBall.Velocity.X < -7.5f)
{
CueBall.Velocity = new Vector2(-5.0f, CueBall.Velocity.Y);
}
if (CueBall.Velocity.Y > 7.5f)
{
CueBall.Velocity = new Vector2(CueBall.Velocity.X, 5.0f);
}
if (CueBall.Velocity.Y < -7.5f)
{
CueBall.Velocity = new Vector2(CueBall.Velocity.X, -5.0f);
}
}
public void SideCollision()
{
CueBall.Position += CueBall.Velocity;
if (CueBall.Position.X + CueBall.Width < 0)
{
CueBall.Position = new Vector2(ScreenWidth, CueBall.Position.Y);
}
if (CueBall.Position.X - CueBall.Width > ScreenWidth)
{
CueBall.Position = new Vector2(0, CueBall.Position.Y);
}
if (CueBall.Position.Y + CueBall.Height < 0)
{
CueBall.Position = new Vector2(CueBall.Position.X, ScreenHeight);
}
if (CueBall.Position.Y - CueBall.Height > ScreenHeight)
{
CueBall.Position = new Vector2(CueBall.Position.X, 0);
}
}
private bool CheckBallCollision(Sprite CueBall, Sprite RedBall)
{
Vector2 position1 = CueBall.Position;
Vector2 position2 = RedBall.Position;
float Cathetus1 = Math.Abs(position1.X - position2.X);
float Cathetus2 = Math.Abs(position1.Y - position2.Y);
Cathetus1 *= Cathetus1;
Cathetus2 *= Cathetus2;
distance = (float)Math.Sqrt(Cathetus1 + Cathetus2);
if ((int)distance < CueBall.Width)
return true;
return false;
}
private void HitCueBall()
{
Vector2 Velocity = new Vector2(
(float)Math.Cos(CueBall.Rotation - (float)MathHelper.PiOver2),
(float)Math.Sin(CueBall.Rotation - (float)MathHelper.PiOver2));
Velocity.Normalize();
Velocity *= 6.0f;
CueBall.Velocity = Velocity;
CueBall.Position = CueBall.Position + CueBall.Velocity;
}
protected override void UnloadContent()
{
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Green);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
spriteBatch.Draw(CueBall.Texture, CueBall.Position, null, Color.White, CueBall.Rotation, CueBall.Center, CueBall.Scale, SpriteEffects.None, 1.0f);
spriteBatch.Draw(DirectionArrow.Texture, DirectionArrow.Position, null, Color.White, DirectionArrow.Rotation, DirectionArrow.Center,
DirectionArrow.Scale, SpriteEffects.None, 1.0f);
spriteBatch.End();
base.Draw(gameTime);
}
}
精灵类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace BilliardsEngine2D
{
class Sprite
{
Texture2D texture;
Vector2 position;
Vector2 center;
Vector2 velocity;
float rotation;
float scale;
public Sprite(Texture2D texture)
{
this.texture = texture;
position = Vector2.Zero;
center = new Vector2(texture.Width / 2, texture.Height / 2);
velocity = Vector2.Zero;
Rotation = 0.0f;
Scale = 1.0f;
}
public Texture2D Texture
{
get { return texture; }
}
public Vector2 Position
{
get { return position; }
set { position = value; }
}
public Vector2 Center
{
get { return center; }
}
public Vector2 Velocity
{
get { return velocity; }
set { velocity = value; }
}
public float Rotation
{
get { return rotation; }
set
{
rotation = value;
if (rotation < -MathHelper.TwoPi)
rotation = MathHelper.TwoPi;
if (rotation > MathHelper.TwoPi)
rotation = -MathHelper.TwoPi;
}
}
public float Scale
{
get { return scale; }
set { scale = value; }
}
public int Width
{
get { return texture.Width; }
}
public int Height
{
get { return texture.Height; }
}
}
任何想法如何解决这个问题。
答案 0 :(得分:1)
我相信您的setup
方法在LoadContent
方法之前被调用。
根据this documentation LoadContent
由Initialize
调用。
protected override void Initialize()
{
Setup();
SoundEffect.MasterVolume = 0.01f;
base.Initialize();
}
我认为假设base.Initialize()
是调用LoadContent
的地方是公平的。
我认为您的代码存在问题,因为您试图在Sprite
方法之前设置Setup()
类的属性之前 {1}}方法。
我建议您在修改Sprite属性的位置移动语句:
LoadContent()
在您使用CueBall.Rotation = 0.0f;
方法new Sprite()
进行实例化后,。
LoadContent
您的CueBall = new Sprite(Content.Load<Texture2D>("Sprites/CueBall"));
方法中的
或者您可以将LoadContent
来电转移到Setup
方法