2012-04-17 44 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带有空引用异常下划线。我认为它可能在绘制或更新方法中缺少一些东西,但我不知道。有关此异常的详细信息指出“未将对象引用设置为对象的实例”。帮助将是伟大的,谢谢!MissileFired.Move的空参考例外

+0

它肯定看起来像你在'Initialize'方法中将'MissileFired'设置为null。然后,在你的第一个'Update'调用中,你调用'Move',很可能没有对象。为什么在你的'Initialize'方法中甚至无效'MissileFired'对象? – Tejs 2012-04-17 14:52:15

回答

2

对象MissileFired为空。当您尝试在空对象上调用成员(例如Move())时,您会得到一个NullReferenceException

从我可以在你的代码中看到,MissileFired有条件通过按键产生,所以也许试图用它首先应该做一个空检查,而不是假设它存在的代码:

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

对我来说这是有道理的,导弹只有在被解雇时才会存在,但代码需要处理这两种情况。

+0

回答了我的问题,谢谢! – user1275084 2012-04-17 15:09:14

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

这是一个问题 - MissleFired是比赛开始后空,所以你不能没有你的Update()方法返回null检查使用它,你确信你已经初始化之前。

+0

它不是* always * null。 – 2012-04-17 14:53:52