2012-11-24 33 views
0

構建代碼時,它生成的很好,但不會運行。調試它會導致每當一個精靈使用從精靈類變量(一審以設置一個NullReferenceException錯誤()參考精靈類(XNA C#)時出現System.NullReferenceException錯誤

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

Sprite類

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

檢查調用初始化,LoadContent的順序。也許你的CueBall等精靈尚未分配。 – dowhilefor

+0

沒什麼不同:/ – Rhiggens

+0

它通常有助於將您的問題分解爲一個最小的例子。所有代碼 –

回答

1

我相信你的setup方法是在LoadContent方法之前調用。

根據this documentationLoadContentInitialize調用。

protected override void Initialize() 
    { 
     Setup(); 
     SoundEffect.MasterVolume = 0.01f; 
     base.Initialize(); 
    } 

我會說這是公平的假設,base.Initialize()就是LoadContent從調用。

我相信,你的代碼是打破,因爲你想在Setup()方法他們實例化的LoadContent()方法前將Sprite類的屬性。你已經在你的LoadContent方法實例化後,他們與new Sprite()

CueBall.Rotation = 0.0f; 


我建議你移動,你修改你的Sprite屬性的語句。

CueBall = new Sprite(Content.Load<Texture2D>("Sprites/CueBall")); 
LoadContent方法

也可以將您Setup呼叫轉移到你的LoadContent方法

+0

非常感謝。 我讀了這個,並嘗試把base.Inintialize,所以它會加載內容之前嘗試安裝遊戲,這完美的工作。 我討厭這樣的問題有最簡單的解決方案。 乾杯 – Rhiggens