2014-02-26 36 views
0

我正在創建空間入侵者類型的遊戲並且遇到錯誤。 錯誤發生在Update函數中,在兩個for循環中。一個用於檢查有多少外星人活着,另一個用於檢查外星人是否到達屏幕底部。本地變量'i'不能在此範圍內聲明,因爲它會給'i'以不同的含義

這是主要的錯誤代碼中的

if (rectShipBullet.Y + rectShipBullet.Height < 0)// Adding this will allow the player to fire a new bullet each time the player misses. If a minus symbol was used then the bullet would go off the screen far too early and not look realistic so the plus symbol is used instead. 
         ShipBulletVisible = "No"; 

        int CountAliensAlive = 0;//Keeps track of how many aliens are alive. 
        for (int i = 0; i < rectSpaceInvader.Length; i++) 
        { 
         if (AlienAlive[i].Equals("Yes")) 
          CountAliensAlive = CountAliensAlive + 1; 
        } 



        //If half of the aliens are gone (25/50) aliens are dead then. 
        if (50 * 1/2 == CountAliensAlive) 
         SpaceInvaderSpeed = 15; // So when most of the aliens are dead the speed of the aliens coming down will double making it more difficult. 


        //Now we will check to see if the aliens reach the bottom of the screen and hit our ship which would cause a game over. 
        for (int i = 0; i < rectSpaceInvader.Length; i++) 
        { 
         { 

          if (AlienAlive[i].Equals("Yes")) //Checks to see if the space invader is visible. 
           if (rectSpaceInvader[i].Y + rectSpaceInvader[i].Height > rectSpaceShip.Y) 
            this.Exit(); 


         } 
        } 

整個代碼下面是參考

namespace Space_Invaders 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    /// 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 
     SpriteFont Start; 
     string Screen = "START"; 
     bool GameOver = false, restart = true; 

     SpriteFont Label; 
     string txt = "."; 
     Keys PrevKey; 

     string[] HighScores = new string[5]; 
     int count = 0; 

     Texture2D SpaceShip, ShipBullet; 
     Rectangle rectShipBullet;//Implementing the ship's bullet and again no need for multiple arrays since we are only going to use one bullet. 
     Rectangle rectSpaceShip; //No need for the multidimensonal array with the spaceship since there is only going to be on visible on the screen. 
     Texture2D[] SpaceInvader = new Texture2D[50]; 
     Rectangle[] rectSpaceInvader = new Rectangle[50]; //This will be a multidimensional array which will be used for the space invaders. For rows and columns. 
     String[] AlienAlive= new String[50]; //Creating another multidimensional array for keeping track of what aliens are alive or dead. At the beginning of the game we want all aliens to be alive at the start so we would begin by saying that aliens alive = "Yes". 
     SpriteFont scoreBoard;  
     int Score = 0; 
     int SpaceInvaderX=10, SpaceInvaderY=5; 
     int SpaceInvaderSpeed = 10;//Creating a variable for the speed of the aliens. 
     String Direction = "Right"; 
     String ShipBulletVisible = "No"; //Need to know when the bullet is going to be visible within the game so we create a string and immediately upon declaring we say no so we can add an if statement saying otherwise. 




     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      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 
      for (int i = 0; i < rectSpaceInvader.Length; i++) 
      { 
       if (i % 5 == 0 && i!=0) 
       { 
        SpaceInvaderY += 30; 
        SpaceInvaderX = 5; 
       } 

       rectSpaceInvader[i] = new Rectangle(SpaceInvaderX, SpaceInvaderY, 100, 25); 

       SpaceInvaderX = SpaceInvaderX+ rectSpaceInvader[i].Width + 2; 
       AlienAlive[i] = "Yes"; 
      } 

      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 

      Start = Content.Load<SpriteFont>("StartScreen"); 
      scoreBoard = Content.Load<SpriteFont>("Score"); 
      for (int i = 0; i < rectSpaceInvader.Length; i++) 
      { 
       SpaceInvader[i] = Content.Load<Texture2D>("Invader"); 
      } 
      // rectSpaceInvader = new Rectangle[50]; //Adding Rows & Columns to the space invaders so when the game is loaded there will be 5 rows of space invaders with 10 in each row. 
      // AlienAlive = new String[50];// Must declare the multidimensional array here also in order for it to detect what aliens are alive or not. 
      /* 
      for (int i = 0; i < rectSpaceInvader.Length; i++) // This is used for the columns, so when the program runs the loop will go through and say 0 times 50, then 1 times 50 and so on. 
      { 
       rectSpaceInvader[i].Width = SpaceInvader[i].Width; 
       rectSpaceInvader[i].Height = SpaceInvader[i].Height; 
       rectSpaceInvader[i].X = 50 ; //X corresponds to my collumns and will space the space invaders out according to what value was added to multiply by the columns. 
       rectSpaceInvader[i].Y = 50 ; //Y corresponds to my rows and will space the space invaders out according to what value was added to multiply by the rows. 
       AlienAlive[i] = "Yes"; 
      } 
     */ 
      SpaceShip = Content.Load<Texture2D>("SpaceShip");//Loading in the spaceship into the LoadContent function. 
      rectSpaceShip.Width = SpaceShip.Width;//Setting the width of the rectangle the same width as the spaceship image that is being loaded in. 
      rectSpaceShip.Height = SpaceShip.Height; //Setting the height of the rectangle the same height as the spaceship image that is being loaded in. 
      rectSpaceShip.X = 0;//Setting the X position of the spaceship to be in the far bottom left corner of the game screen. 
      rectSpaceShip.Y = 440; //Setting the Y position of the spaceship. 

      ShipBullet = Content.Load<Texture2D>("Bullet3"); 
      rectShipBullet.Width = ShipBullet.Width;//Setting the width of the bullet to be the same width as the bullet image that was loaded in. 
      rectShipBullet.Height = ShipBullet.Height;//Setting the heigh of the buller to be the same heigh as the bullet image that was loaded in. 
      rectShipBullet.X = 0; 
      rectShipBullet.Y = 0; 

     } 

     /// <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 

      // Alien Movement 
      if (!GameOver && !restart) 
      { 
       int RightEdge = graphics.GraphicsDevice.Viewport.Width; 
       int LeftEdge = 0; 
       for (int i = 0; i < rectSpaceInvader.Length; i++) 
       { 
        if (Direction.Equals("Right"))// ".Equals" is used in place of "==" and is used throughout the entire code". 
         rectSpaceInvader[i].X = rectSpaceInvader[i].X + SpaceInvaderSpeed; //If the direction is equal to right then the space invaders will move along the X axis towards the right edge of the screen. 
        if (Direction.Equals("Left")) 
         rectSpaceInvader[i].X = rectSpaceInvader[i].X - SpaceInvaderSpeed; //Almost same code as the one above except instead of going to the right we are moving the aliens to the left edge of the screen. 
       } 
       //Checks to see if any aliens have gone passed the edge of the right side of the screen. 
       String ChangeDirection = "No"; //Declaring a string variable inside the update function. 
       for (int i = 0; i < rectSpaceInvader.Length; i++) 
       { 
        if (AlienAlive[i].Equals("Yes"))//This code stops an error. The error is that without this line of code the aliens that the player has already shot are shown as invisible and dead on the screen but are still there while the game runs so if the player eliminated the first two rows of aliens, once the aliens reached the far left of the screen, the aliens would not go to the very edge of the screen, since the game still thinks the dead aliens are still in the game and the check that is running is causing them to collide with the left wall so with this line of code, that bypasses that. 
        { 
         if (rectSpaceInvader[i].X + rectSpaceInvader[i].Width > RightEdge) 
         { 
          Direction = "Left"; //This will not switch the aliens around and have them move to the left edge but the if statement above will do that. 
          ChangeDirection = "Yes"; 
         } 
         if (rectSpaceInvader[i].X < LeftEdge) 
         { 
          Direction = "Right"; //Checks to see if the aliens have gone passed the left edge of the screen and if so then the direction will turn them back towards the right edge of the screen. 
          ChangeDirection = "Yes"; 
         } 
        } 

       } 
       if (ChangeDirection.Equals("Yes")) 
       { 
        for (int i = 0; i < rectSpaceInvader.Length; i++) 
         rectSpaceInvader[i].Y = rectSpaceInvader[i].Y + 8;//Here we set and change the Y value for the aliens. When the aliens reach either the left or right edge of the game screen they will move down by 3 and continue moving down until the bottom. 

       } 
      } 
      //Ship Movement 
      KeyboardState kb = Keyboard.GetState(); 

      if (kb.IsKeyDown(Keys.S)) 
       restart = false; 

      if (kb.IsKeyDown(Keys.Left)) 
       rectSpaceShip.X = rectSpaceShip.X - 4;//Allows user to use the left arrow key in order to move the space ship to the left and the ship will move twice as fast as normal since the speed has been set to 2 
      if (kb.IsKeyDown(Keys.Right)) 
       rectSpaceShip.X = rectSpaceShip.X + 4;//Allows user to use the right arrow key in order to move the space ship to the right. 
      if (kb.IsKeyDown(Keys.Space) && ShipBulletVisible.Equals("No")) 
      { 
       ShipBulletVisible = "Yes";//Since we have set the spacebar as the trigger to show the bullet on the screen. 
       rectShipBullet.X = rectSpaceShip.X + (rectSpaceShip.Width/2) - (rectShipBullet.Width/2) - 1; //In order to set the position of the bullet to be in the middle of the ship, I had to take the width of the ship divide it by 2 which would make it to be in the middle of the ship since when the game ran previously the bullet would appear to the left edge of the ships rectangle. I then took that away from the width of the ship's bullet rectangle and divided that by 2. Was still slightly off so I had to subtract one from the entire line of code in order to get it dead centre. So when the spacebar is triggered the bullet will appear in the middle of the ship, also when moving the bullet will appear in the same position. 

       rectShipBullet.Y = rectSpaceShip.Y - rectShipBullet.Height + 2; //Since the Y values are increasing as you are moving down the screen I use "+2" and not minus 2 so that the very bottom of the bullet is on the tip of the spaceship. 


      } 
      if (ShipBulletVisible.Equals("Yes")) //Could use a boolean to check. 
       rectShipBullet.Y = rectShipBullet.Y - 5; //Making the bullet move when the spacebar is pressed and giving it an initial speed. 

      //Now I am checking to see if a bullet has hit an alien. Use of the For loop again. 
      if (ShipBulletVisible.Equals("Yes")) 
      { 
       for (int i = 0; i < rectSpaceInvader.Length; i++) 
       { 
        if (AlienAlive[i].Equals("Yes")) 
        {//This piece of code is crucial for the game to function right. If this is not in, when the game loads and the player takes out the first row of aliens. The player would not be able to advance since when the player would fire it the bullet would still hit aliens that are supposed to be dead but they are still loaded on the screen and are causing the bullet the to detect them as alive aliens. So with this piece of code, saying if the aliens are alive and that equals yes then it would run the check and bypass the invisible alive aliens and allow the player to continue playing the game. 
         if (rectShipBullet.Intersects(rectSpaceInvader[i])) //This means that if the bullet intersects/ has hit one of the aliens then the bullet would have to become invisible after hitting the alien to act like it has realistcly hit the alien and has disappeared. 
         { 

          ShipBulletVisible = "No"; 

          AlienAlive[i] = "No"; 

          Score++; 
          rectShipBullet.X = rectSpaceShip.X + (rectSpaceShip.Width/2) - (rectShipBullet.Width/2) - 1; //In order to set the position of the bullet to be in the middle of the ship, I had to take the width of the ship divide it by 2 which would make it to be in the middle of the ship since when the game ran previously the bullet would appear to the left edge of the ships rectangle. I then took that away from the width of the ship's bullet rectangle and divided that by 2. Was still slightly off so I had to subtract one from the entire line of code in order to get it dead centre. So when the spacebar is triggered the bullet will appear in the middle of the ship, also when moving the bullet will appear in the same position. 
          rectShipBullet.Y = rectSpaceShip.Y - rectShipBullet.Height + 2; 
          rectSpaceInvader[i].Width = 0; 
          rectSpaceInvader[i].Height = 0; 
          if (Score == 50) 
          { 
           this.Exit(); 
          } 
         } 


         //Checks to see if the bullet has missed any aliens and has gone off of the screen, before this code is added the game would not allow you to fire anymore new bullets. 
         if (rectShipBullet.Y + rectShipBullet.Height < 0)// Adding this will allow the player to fire a new bullet each time the player misses. If a minus symbol was used then the bullet would go off the screen far too early and not look realistic so the plus symbol is used instead. 
          ShipBulletVisible = "No"; 

         ***int CountAliensAlive = 0;//Keeps track of how many aliens are alive. 
         for (int i = 0; i < rectSpaceInvader.Length; i++) 
         { 
          if (AlienAlive[i].Equals("Yes")) 
           CountAliensAlive = CountAliensAlive + 1; 
         } 



         //If half of the aliens are gone (25/50) aliens are dead then. 
         if (50 * 1/2 == CountAliensAlive) 
          SpaceInvaderSpeed = 15; // So when most of the aliens are dead the speed of the aliens coming down will double making it more difficult. 


         //Now we will check to see if the aliens reach the bottom of the screen and hit our ship which would cause a game over. 
         for (int i = 0; i < rectSpaceInvader.Length; i++) 
         { 
          { 

           if (AlienAlive[i].Equals("Yes")) //Checks to see if the space invader is visible. 
            if (rectSpaceInvader[i].Y + rectSpaceInvader[i].Height > rectSpaceShip.Y) 
             this.Exit();* 


          } 
         }** 
         /* 
         for (int i = 0; i < rectSpaceInvader.Length; i++) 
          { 
           if (rectShipBullet.Intersects(rectSpaceInvader[i])) 
           { 
            Score++; 
            rectShipBullet.X = rectSpaceShip.X + (rectSpaceShip.Width/2) - (rectShipBullet.Width/2) - 1; //In order to set the position of the bullet to be in the middle of the ship, I had to take the width of the ship divide it by 2 which would make it to be in the middle of the ship since when the game ran previously the bullet would appear to the left edge of the ships rectangle. I then took that away from the width of the ship's bullet rectangle and divided that by 2. Was still slightly off so I had to subtract one from the entire line of code in order to get it dead centre. So when the spacebar is triggered the bullet will appear in the middle of the ship, also when moving the bullet will appear in the same position. 
            rectShipBullet.Y = rectSpaceShip.Y - rectShipBullet.Height + 2; 
           } 

          } 
         */ 

         if (restart) 
          Screen = "START"; 

         if (GameOver) 
          Screen = "Game Over"; 



         KeyboardState ks = Keyboard.GetState(); 
         Keys[] k = ks.GetPressedKeys(); 
         Keys tempKey = Keys.None; 
         string keyChar = ""; 

         foreach (Keys q in k) 
         { 
          Keys currentKey = q; 
          if (ks.IsKeyUp(PrevKey)) 
          { 
           if (!(q == Keys.None)) 
           { 
            switch (q) 
            { 
             case Keys.Space: 
              keyChar = " "; 
              break; 
             case Keys.Delete: 
              txt = ""; 
              break; 
             case Keys.Back: 
              txt = txt.Remove(txt.Length - 1); 
              break; 
             case Keys.Enter: 
              HighScores[count] = txt; 
              count++; 
              txt = ""; 
              if (count == 5) 
               count = 0; 
              break; 
             case Keys.End: 
              WriteScores(); 
              break; 
             case Keys.Home: 
              ReadScores(); 
              break; 
             default: 
              keyChar = q.ToString(); 
              break; 
            } 
            txt += keyChar; 
           } 
          } 

          if (currentKey != Keys.None && ks.IsKeyDown(currentKey)) 
          { 
           tempKey = currentKey; 
          } 

         } 

         PrevKey = tempKey; 
         base.Update(gameTime); 
        } 
       } 
      } 
     } 
     public void WriteScores() 
     { 
      StreamWriter Rite = new StreamWriter(@"C:\TheScores.txt"); 
      for (int i = 0; i < HighScores.Length; i++) 
      { 
       Rite.WriteLine(HighScores[i]); 
      } 
      Rite.Close(); 

     } 
     public void ReadScores() 
     { 
      if (File.Exists(@"C:\TheHighScores.txt")) 
      { 
       StreamReader Reed = new StreamReader(@"C:\TheScores.txt"); 
       for (int i = 0; i < HighScores.Length; i++) 
       { 
        txt += Reed.ReadLine() + "\n"; 
       } 
       Reed.Close(); 
      } 
     } 


     /// <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) 
     { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 

      // TODO: Add your drawing code here 
      spriteBatch.Begin(); 
      if (!restart && !GameOver) 
      { 
       for (int i = 0; i < rectSpaceInvader.Length; i++) 
       { 
        if (AlienAlive[i].Equals("Yes")) 

         spriteBatch.Draw(SpaceInvader[i], rectSpaceInvader[i], Color.White); //This will run the loop within the spritebatch and create 5 columns of space invaders and 10 space invaders in each of the rows using the spritebatch.draw method. 
       } 
       spriteBatch.Draw(SpaceShip, rectSpaceShip, Color.White);//Loading in the spaceship and loading it in outside the for loop because if it was drawn inside the for loop then it would create multiple spaceships when we only need one. 
       if (ShipBulletVisible.Equals("Yes"))//If the bullet is visible then this will trigger and draw the bullet onto the screen. 
        spriteBatch.Draw(ShipBullet, rectShipBullet, Color.White); 

       spriteBatch.DrawString(scoreBoard, Convert.ToString(Score) + " " + AlienAlive[49], new Vector2(10, 10), Color.Black); 
      } 
      else 
      { 
       if (GameOver) 
        Screen = "GAME OVER"; 

       spriteBatch.DrawString(Start, Screen, new Vector2(100, 100), Color.Black); 
       spriteBatch.DrawString(Label, txt, new Vector2(200, 100), Color.Black); 
      } 
       spriteBatch.End(); 

       base.Draw(gameTime); 

     } 
    } 
} 
+2

你確定你需要這麼多的代碼來顯示錯誤的示例? –

回答

8

您需要爲您的迭代器嵌套循環for不同的名稱。

實施例:

for(int i = 0; i < 10; i++) 
{ 
    for(int x = 0; x < 10; x++) 
    { 
     //some code 
    } 
} 

i通知和x。兩者在同一範圍內不能爲i

另一方面,這是有效的,因爲它們都存在於不同的範圍內。

for(int i = 0; i < 10; i++) 
{ 
    //some code 
} 

for(int i = 0; i < 10; i++) 
{ 
    //some code 
} 

修復:

這裏是有問題的循環。在聲明中,將i的所有實例更改爲x(或其他),如上所示。

for (int i = 0; i < rectSpaceInvader.Length; i++) 
{ 
    if (AlienAlive[i].Equals("Yes")) 
     CountAliensAlive = CountAliensAlive + 1; 
} 

for (int i = 0; i < rectSpaceInvader.Length; i++) 
{ 
    { 
     if (AlienAlive[i].Equals("Yes")) 
      if (rectSpaceInvader[i].Y + rectSpaceInvader[i].Height > rectSpaceShip.Y) 
       this.Exit();* 
    } 
} 

它們都包含在這一個裏面(顯示if作爲參考)。

if (ShipBulletVisible.Equals("Yes")) 
{ 
    for (int i = 0; i < rectSpaceInvader.Length; i++) 
    { 
     //code 
    } 
} 
+2

+1因爲偉大的偵探工作發現! –

+0

我在錯誤所在的頂部添加了。我沒有在循環中使用循環。 – user3353568

+0

但是你正在循環中使用循環。 – aw04

2

正如@ aw04(+1)所指出的那樣,你有循環使用相同的變量嵌套在一起。你有這樣的位置(在你update法):

//Now I am checking to see if a bullet has hit an alien. Use of the For loop again. 
     if (ShipBulletVisible.Equals("Yes")) 
     { 
      for (int i = 0; i < rectSpaceInvader.Length; i++) 
      { 
       if (AlienAlive[i].Equals("Yes")) 
       { 
        if (...) 

        for (int i = 0; i < rectSpaceInvader.Length; i++)<-- this is causing the error. Change the variable to x or j like was suggested, or change the outer loops variable 
        {...} 

        //Now we will check to see if the aliens reach the bottom of the screen and hit our ship which would cause a game over. 
        for (int i = 0; i < rectSpaceInvader.Length; i++)<-- same thing here 
        {...} 
       } 
      } 
     } 

作爲一個側面說明,你的代碼會更易於管理,如果您對外星人做的一類。

+0

感謝@davidsbro提供的修復。 – user3353568

+0

當然,很高興它有幫助。如果你解決了你的問題,你應該給出更有幫助的答案(在這種情況下可能是@ aw04)。 – davidsbro

相關問題