2012-04-17 13 views
2
namespace SpaceInvader 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class SpaceInvaders : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     Texture2D StarfieldImg; 
     Texture2D InvaderImg; 
     Texture2D AltInvaderImg; 
     Texture2D RocketLauncherImg; 
     Texture2D MissileImg; 
     int RocketXPos; 
     int AlienDirection; 
     int AlienSpeed; 
     Invader[] Invaders; 
     double Ticks; 
     Missile MissileFired; 

     public SpaceInvaders() 
     { 
      graphics = new GraphicsDeviceManager(this); 

      graphics.PreferredBackBufferWidth = 1024; 
      graphics.PreferredBackBufferHeight = 768; 
      graphics.ApplyChanges(); 

      Content.RootDirectory = "Content"; 
     } 

     /// <summary> 
     /// Allows the game to perform any initialization it needs to before starting to run. 
     /// This is where it can query for any required services and load any non-graphic 
     /// related content. Calling base.Initialize will enumerate through any components 
     /// and initialize them as well. 
     /// </summary> 
     protected override void Initialize() 
     { 
      // TODO: Add your initialization logic here 
      RocketXPos = 512; 

      AlienDirection = -1; 
      AlienSpeed = 16; 

      Invaders = new Invader[11]; 

      int XPos = 512; 
      for (int Count = 0; Count < 11; Count++) 
      { 
       Invaders[Count] = new Invader(); 
       Invaders[Count].SetXPos(XPos); 
       Invaders[Count].SetYPos(100); 

       XPos = XPos + 32; 
      } 

      Ticks = 0; 

      MissileFired = null; 
      base.Initialize(); 
     } 

     /// <summary> 
     /// LoadContent will be called once per game and is the place to load 
     /// all of your content. 
     /// </summary> 
     protected override void LoadContent() 
     { 
      // Create a new SpriteBatch, which can be used to draw textures. 
      spriteBatch = new SpriteBatch(GraphicsDevice); 

      // TODO: use this.Content to load your game content here 
      StarfieldImg = Content.Load<Texture2D>("Starfield1024x768"); 
      InvaderImg = Content.Load<Texture2D>("inv1"); 
      AltInvaderImg = Content.Load<Texture2D>("inv12"); 
      RocketLauncherImg = Content.Load<Texture2D>("LaserBase"); 
      MissileImg = Content.Load<Texture2D>("bullet"); 

     } 

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

     /// <summary> 
     /// Allows the game to run logic such as updating the world, 
     /// checking for collisions, gathering input, and playing audio. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Update(GameTime gameTime) 
     { 
      // Allows the game to exit 
      if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
       this.Exit(); 

      // TODO: Add your update logic here 
      MissileFired.Move(); 

      if (Keyboard.GetState().IsKeyDown(Keys.Space)) 
      { 
       MissileFired = new Missile(RocketXPos, 650); 
      } 

      if (Keyboard.GetState().IsKeyDown(Keys.Left)) 
      { 
       RocketXPos = RocketXPos - 4; 
      } 

      if (Keyboard.GetState().IsKeyDown(Keys.Right)) 
      { 
       RocketXPos = RocketXPos + 4; 
      } 

      if (RocketXPos < 100) 
      { 
       RocketXPos = 100; 
      } 

      if (RocketXPos > 924) 
      { 
       RocketXPos = 924; 
      } 

      Ticks = Ticks + gameTime.ElapsedGameTime.TotalMilliseconds; 

      if (Ticks > 500) 
      { 
       for (int Count = 0; Count < 11; Count++) 
       { 
        Invaders[Count].MoveHorizontal(AlienSpeed * AlienDirection); 
       } 

       if (Invaders[0].GetXPos() < 96) 
       { 
        AlienDirection = +1; 

        int XPos = 96; 
        for (int Count = 0; Count < 11; Count++) 
        { 
         Invaders[Count].MoveVertical(4); 
         Invaders[Count].SetXPos(XPos); 
         XPos = XPos + InvaderImg.Width; 
        } 
       } 

       if (Invaders[10].GetXPos() > 924) 
       { 
        AlienDirection = -1; 

        int XPos = 924 - InvaderImg.Width * 10; 
        for (int Count = 0; Count < 11; Count++) 
        { 
         Invaders[Count].MoveVertical(4); 
         Invaders[Count].SetXPos(XPos); 
         XPos = XPos + InvaderImg.Width; 
        } 
       } 

       Ticks = 0; 
      } 

      base.Update(gameTime); 
     } 


     /// <summary> 
     /// This is called when the game should draw itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Draw(GameTime gameTime) 
     { 
      spriteBatch.Begin(); 

      spriteBatch.Draw(StarfieldImg, Vector2.Zero, Color.White); 

      spriteBatch.Draw(RocketLauncherImg, new Vector2(RocketXPos, 650), Color.White); 

      if (MissileFired != null) 
      { 
       Vector2 MissilePos = new 
       Vector2(MissileFired.GetPosition().X, MissileFired.GetPosition().Y - MissileImg.Height); 
      spriteBatch.Draw(MissileImg, MissilePos, Color.White); 
      } 



      for (int Count = 0; Count < 11; Count++) 
      { 
       spriteBatch.Draw(InvaderImg, Invaders[Count].GetPos(), Color.White); 
      } 

      spriteBatch.End(); 

      base.Draw(gameTime); 
     } 
    } 
} 

このゲームを実行しようとすると、MissileFired.MoveにはNULL参照例外が下線付きで表示されます。私はそれが描画や更新メソッドで何かが欠落しているかもしれないと思うが、私はヒントを持っていません。この例外の詳細については、「オブジェクト参照がオブジェクトのインスタンスに設定されていません」と記載されています。ヘルプは素晴らしい、ありがとう!MissileFired.MoveのNull参照例外

+0

'Initialize'メソッドで' MissileFired'をnullに設定しているように見えます。そして、あなたの最初の 'Update'コールでは、' Move'を呼び出します。ほとんどの場合、オブジェクトなしです。あなたの 'Initialize'メソッドで' MissileFired'オブジェクトをヌルにする理由は? – Tejs

答えて

2

オブジェクトMissileFiredがnullです。 nullオブジェクト(たとえばMove())のメンバーを呼び出そうとすると、NullReferenceExceptionが返されます。

if (MissileFired != null) 
{ 
    MissileFired.Move(); 
} 

:私はあなたのコード内で見ることができるものから、

MissileFiredは条件付きでキーを押して、それは最初のNULLチェックを行うといない、それが存在すると仮定しなければならない使用しようとするので、おそらくコードによって作成されました私にとって、これは意味をなさない。ミサイルは発射時にのみ存在するだろうが、コードは両方の状況を処理する必要がある。

問題だ
+0

私の質問にお答えしました、ありがとうございます! – user1275084

1
protected override void Initialize() 
    { 
     ... 
     MissileFired = null; 
     ... 
    } 

- MissleFiredは、ゲーム開始後にnullであるので、あなたは、あなたがそれを初期化していることを確認している前に、あなたは、あなたの更新()メソッドにnullをチェックせずにそれを使用することはできません。

+0

*常に* nullではありません。 –