2015-01-22 5 views
-4

이 코드는 atm에 문제가 있으며 누구나 나를 도와 주겠다고 마음 먹으면 기권합니다. 나는 왜 그런 오류가 발생하는지 알지 못한다. 그래서 어떤 사람은 왜 그런 일이 일어날 지 말해 줄 수있다.음수가 아니어야하며 군중의 크기보다 작아야합니다.

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 WindowsGame2 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     private Rectangle Bounds = Rectangle.Empty; 
     SpriteFont font; 

     Texture2D gfx_shot; 
     Texture2D gfx; 
     Texture2D gfx_acc; 
     Texture2D gfx_meteor; 

     Vector2 position; 
     Vector2 ship_speed = new Vector2(); 
     List<Vector2> shot_pos = new List<Vector2>(); 
     List<Vector2> shot_speed = new List<Vector2>();   
     List<Vector2> meteor_pos = new List<Vector2>(); 
     List<Vector2> meteor_speed = new List<Vector2>(); 

     Random myRnd = new Random(); 

     float angle = 0; 
     const float ship_acc = 0.1f; 
     const float ship_max_speed = 4; 
     const int shot_delay = 200; 
     int shot_time; 
     int score = 0; 

     double shot_rad = 3.25, 
      meteor_rad = 33; 

     bool accelerate; 

     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 

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

      // Här läggs SpriteBatch till som gör att man kan använda dem som en texture 
      gfx = Content.Load<Texture2D>("ship"); 
      gfx_acc = Content.Load<Texture2D>("ship_acc"); 
      gfx_shot = Content.Load<Texture2D>("shot"); 
      font = Content.Load<SpriteFont>("myFont"); 

      // Positionen av rymdskäpet 
      position = new Vector2(200, 200); 

      gfx_meteor = Content.Load<Texture2D>("meteor"); 
      int i; 
      for (i = 0; i < 10; i++) 
      { 
       meteor_pos.Add(new Vector2(myRnd.Next(800), myRnd.Next(600))); 
       double tmp_angle = (myRnd.Next(1000) * Math.PI * 2)/1000.0; 
       double tmp_speed = 0.5 + 3.0 * (myRnd.Next(1000)/1000.0); 
       meteor_speed.Add(new Vector2((float)(tmp_speed * Math.Cos(tmp_angle)), 
        (float)(tmp_speed * Math.Sin(tmp_angle)))); 
      } 

      if (i < 10) 
      { 
       meteor_pos.Add(new Vector2(myRnd.Next(800), myRnd.Next(600))); 
       double tmp_angle = (myRnd.Next(1000) * Math.PI * 2)/1000.0; 
       double tmp_speed = 0.5 + 3.0 * (myRnd.Next(1000)/1000.0); 
       meteor_speed.Add(new Vector2((float)(tmp_speed * Math.Cos(tmp_angle)), 
        (float)(tmp_speed * Math.Sin(tmp_angle)))); 
       i++; 
      } 
     } 

     /// <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(); 

      // Denna funktion känner av snap trycken för att köra rymdskäppet 
      KeyboardState ks = Keyboard.GetState(); 

      if (ks.IsKeyDown(Keys.Left)) 
      { 
       angle -= 0.05f; 
      } 
      if (ks.IsKeyDown(Keys.Right)) 
      { 
       angle += 0.05f; 
      } 
      if (ks.IsKeyDown(Keys.Up)) 
      { 
       accelerate = true; 

       ship_speed.X += ship_acc * (float)Math.Cos(angle); 
       ship_speed.Y += ship_acc * (float)Math.Sin(angle); 
       if (ship_speed.Length() > ship_max_speed) 
       { 
        ship_speed.Normalize(); 
        ship_speed *= ship_max_speed; 
       } 
      } 
      else 
      { 
       accelerate = false; 
      } 

      position += ship_speed; 

      // Detta kollar om rymdskäpet åker utanför skärmen. Om den gör det ska den komma in på andra sidan 
      if (position.X < -80) 
      { 
       position.X = graphics.GraphicsDevice.Viewport.Width + 80; 
      } 
      if (position.X > graphics.GraphicsDevice.Viewport.Width + 80) 
      { 
       position.X = -80; 
      } 
      if (position.Y < -60) 
      { 
       position.Y = graphics.GraphicsDevice.Viewport.Height + 60; 
      } 
      if (position.Y > graphics.GraphicsDevice.Viewport.Height + 60) 
      { 
       position.Y = -60; 
      } 

      // Här kollar den alla viktiga detaljer om hur skoten funkar 
      shot_time -= gameTime.ElapsedGameTime.Milliseconds; 
      if (shot_time < 0) 
      { 
       shot_time = 0; 
      } 

      if (ks.IsKeyDown(Keys.Space) && shot_time == 0) 
      { 
       shot_time = shot_delay; 
       shot_pos.Add(new Vector2(position.X, position.Y)); 
       shot_speed.Add(new Vector2(5 * (float)Math.Cos(angle), 5 * (float)Math.Sin(angle))); 
      } 

      for (int i = 0; i < shot_pos.Count; i++) 
      { 
       shot_pos[i] += shot_speed[i]; 
       if (shot_pos[i].X < -100 || shot_pos[i].X > graphics.GraphicsDevice.Viewport.Width + 100 
        || shot_pos[i].Y < -100 || shot_pos[i].Y > graphics.GraphicsDevice.Viewport.Height + 100) 
       { 
        shot_pos.RemoveAt(i); 
        shot_speed.RemoveAt(i); 
        continue; 
       } 

      } 

      // Här updaterar vi Metorernas location 
      for (int i = 0; i < meteor_pos.Count; i++) 
      { 
       meteor_pos[i] += meteor_speed[i]; 
       Vector2 v = meteor_pos[i]; 
       //Utanför skärmen? 
       if (v.X < -80) 
        v.X = graphics.GraphicsDevice.Viewport.Width + 80; 
       if (v.X > graphics.GraphicsDevice.Viewport.Width + 80) 
        v.X = -80; 
       if (v.Y < -60) 
        v.Y = graphics.GraphicsDevice.Viewport.Height + 60; 
       if (v.Y > graphics.GraphicsDevice.Viewport.Height + 60) 
        v.Y = -60; 
       if (v.X == position.X) 
        break; 

       //Uppdatera i listan 
       meteor_pos[i] = v; 
      } 

      for (int a = 0; a < meteor_pos.Count; a++) 
      { 

       double ship_xplus = position.X + meteor_pos[a].X; 
       double ship_xminus = position.X - meteor_pos[a].X; 
       double ship_yplus = position.Y + meteor_pos[a].Y; 
       double ship_yminus = position.Y - meteor_pos[a].Y; 


       if ((ship_xplus * ship_xplus + ship_yplus * ship_yplus) < (shot_rad + meteor_rad) * (shot_rad + meteor_rad)) 
       { 

       } 
       else if ((ship_xminus * ship_xminus + ship_yminus * ship_yminus) < (shot_rad + meteor_rad) * (shot_rad + meteor_rad)) 
       { 

       } 
      } 

      // Test 
      //Om det finns skott o meteoriter så kolla kollision 
      if (shot_pos.Count > 0 && meteor_pos.Count > 0) 
      { 
       for (int i = 0; i < shot_pos.Count; i++) 
       { 
        for (int a = 0; a < meteor_pos.Count; a++) 
        { 
         float xdiff = shot_pos[i].X - meteor_pos[a].X; 
         float ydiff = shot_pos[i].Y - meteor_pos[a].Y; 


         if ((xdiff * xdiff + ydiff * ydiff) < (shot_rad + meteor_rad) * (shot_rad + meteor_rad)) 
         { 
          shot_pos.RemoveAt(i); 
          shot_speed.RemoveAt(i); 
          meteor_pos.RemoveAt(a); 
          meteor_speed.RemoveAt(a); 
          continue; 
         } 
        } 
       } 
      } 

      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) 
     { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 
      // Starta renderingen av rymdskäppet 
      spriteBatch.Begin(); 

       // Om rymdskäppet accelerar så kör denna renderings processen och lägg till eld bakom rymdskäpet 
       if (accelerate) 
       { 
        spriteBatch.Draw(gfx_acc, position, null, Color.White, angle + (float)Math.PI/2, new Vector2(gfx.Width/2, gfx.Height/2), 1.0f, SpriteEffects.None, 0); 
       } 
       // Om rymdskäppet svänger kör denna renderings processen 
       spriteBatch.Draw(gfx, position, null, Color.White, angle + (float)Math.PI/2, new Vector2(gfx.Width/2, gfx.Height/2), 1.0f, SpriteEffects.None, 0); 

       // Här skriver den hur många skot du har skjutit på skärmen 
       for (int i = 0; i < shot_pos.Count; i++) 
       { 
        spriteBatch.Draw(gfx_shot, shot_pos[i], null, Color.White, 0, new Vector2(gfx_shot.Width/2, gfx_shot.Height/2), 1.0f, SpriteEffects.None, 0); 

       } 

       // Här gör vi en font som skriver hur många skot det är just nu på skärmen 
       spriteBatch.DrawString(font, "Shots: " + shot_pos.Count, new Vector2(10, 10), Color.White); 
       spriteBatch.DrawString(font, "Score: " + score, new Vector2(10, 35), Color.White); 

       // Här gör vi så metorerna renderas utt på skärmen 
       for (int i = 0; i < meteor_pos.Count; i++) 
       { 
        spriteBatch.Draw(gfx_meteor, meteor_pos[i], null, Color.White, 0, 
         new Vector2(gfx_meteor.Width/2, gfx_meteor.Height/2), 1.0f, SpriteEffects.None, 0); 
       } 
      // Avsluta renderingen av rymdskäppet 

       //if (Collision()) 
        //spriteBatch.DrawString(font, "You were killed", new Vector2(10, 10), Color.White); 

      spriteBatch.End(); 
     } 
    } 
} 

이 오류는 다음과 같습니다

Index was out of range. It may not be negative and must be smaller than the size of the crowd.

편집 :

나는 다음과 같은 오류가 SRY가 문제가 무엇인지 표시하는 것을 잊었다 : 코드 P 여기

입니다 this : float xdiff = shot_pos [i] .X - meteor_pos [a] .X;

+2

* 방법 * 너무 많은 코드입니다.최소한 어떤 줄이 있는지 지적 해주십시오. – BradleyDotNET

+3

지저분한 코드가있는 거대한 곳에서 반복되는 컬렉션에서 항목을 제거하면 색인이 엉망입니다. –

+2

1) [보고있는 예외가 발생할 때 중단] (https://msdn.microsoft.com/en-us/library/d14azbfh.aspx). 2) 디버그. – dbc

답변

0

나는 그 부분이 Peirre-Luc Pineault가 말하는 것이라고 생각합니다. 루프를 거치고 요소를 제거한 다음 루프를 계속 진행합니다. 이것은 때로는 범위를 벗어납니다 (가능성이 높습니다). 나는 당신이 그렇게 할 수있게 해주는 것이 사실 놀랍습니다. 여기 당신은이 목록을 통해 순환하지만, 그 루프를 사용하고 있습니다 : 업데이트 (GameTime의 gametime)를 보면 당신은 결국 볼 작동하는 경우

...

if (shot_pos.Count > 0 && meteor_pos.Count > 0) 
{ 
    for (int i = 0; i < shot_pos.Count; i++) 
    { 
     for (int a = 0; a < meteor_pos.Count; a++) 
     { 
      float xdiff = shot_pos[i].X - meteor_pos[a].X; 
      float ydiff = shot_pos[i].Y - meteor_pos[a].Y; 


      if ((xdiff * xdiff + ydiff * ydiff) < (shot_rad + meteor_rad) * (shot_rad + meteor_rad)) 
      { 
       shot_pos.RemoveAt(i); 
       shot_speed.RemoveAt(i); 
       meteor_pos.RemoveAt(a); 
       meteor_speed.RemoveAt(a); 
       continue; 
      } 
     } 
    } 
} 

나는 큰 문제가 여기에있다 생각 변수를 사용하여 4 개의 다른 목록에서 요소를 제거합니다. "shot_pos"와 "meteor_pos"의리스트를 살펴 보지만, "shot_pos"("ok"), "meteor_pos"(ok), "shot_speed"+ "meteor_speed "(whoooaaa nelly!).

shot_pos와 meteor_pos가 범위 내에 있음을 확신 할 수 있지만 확인하지 않기 때문에 shot_speed와 meteor_speed가 실제로 범위 내에 있는지 알 수 없습니다.

해결 방법 : 원본 코드를 너무 많이 수정하지 않고 단순히 유효 범위 검사를 수행하는 것이 좋습니다.

의미 : 전에에서 얻고 있었다으로

shot_pos.RemoveAt(i); 
if (i< shot_speed.Count){ 
    shot_speed.RemoveAt(i); 
} 
meteor_pos.RemoveAt(a); 
if (a<meteor_speed.Count){ 
    meteor_speed.RemoveAt(a); 
} 
continue; 

이 문제는, 당신이 그이 데이터 라인을 확인하는 방법이 없다는 것입니다. 그래서 2의 i에서 shot_speed는 2의 i에서 shot_pos를 의미합니다.

더 복잡한 솔루션은 구조 나 클래스에서 함께 사용되는 데이터를 결합하는 것입니다.

구조에 대한 MSDN의 튜토리얼은 실제로 괜찮은 : [여기] https://msdn.microsoft.com/en-us/library/aa288471%28v=vs.71%29.aspx

하지만 항상 같은 [이 사이트의 가장] http://www.dotnetperls.com/struct

0

내가 제거 할 필요가있을 때 나는 조금 다른 접근 방법을 사용하고 있습니다 총알이나 유성. 충돌시 나는 플래그를 true로 설정했습니다. 그리고 나서 그것들을 모두 제거합니다. 기본적인 의사 코드

for each m in meteors 
    for each b in bullets 
     if m.collide(b) {b.removeIt = true;} 
    next 
next 

에서

다음

bullet.removeAll(function(c) c.removeIt); 
관련 문제