2013-05-28 21 views
0

好吧,我在Visual Studio 2010中製作了一個空間入侵者類型的遊戲cna with xna studio,目前卡在子彈類中,但它生成子彈但並不會按照精靈指向的方向將其解除。子彈類說公共Vector2起源;沒有被分配給任何東西&仍然是它的默認值,但我不知道是什麼原因造成的。在c#中使用xna studio我想讓子彈在按下空格鍵後從精靈中觸發

代碼子彈

class Bullets 
    { 
     public Texture2D texture; 

     public Vector2 position; 
     public Vector2 velocity; 
     public Vector2 origin; 

     public bool isVisible; 

     public Bullets(Texture2D newTexture) 
     { 
      texture = newTexture; 
      isVisible = false; 
     } 




     public void Draw(SpriteBatch spriteBatch) 
     { 
      spriteBatch.Draw(texture, position, null, Color.White, 0f, origin, 1f, SpriteEffects.None, 1); 
     } 

    } 

代碼遊戲:

namespace Rotationgame 
{ 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game 
    { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     Vector2 spriteVelocity; 
     const float tangentialVelocity = 0f; 
     float friction = 1f; 

     Texture2D spriteTexture; 
     Rectangle spriteRectangle; 

     Rectangle screenRectangle; 

     // The centre of the image 
     Vector2 spriteOrigin; 

     Vector2 spritePosition; 
     float rotation; 

     // Background 
     Texture2D backgroundTexture; 
     Rectangle backgroundRectangle; 


     // Shield 
     Texture2D shieldTexture; 
     Rectangle shieldRectangle; 

     // Bullets 
     List<Bullets> bullets = new List<Bullets>(); 
     KeyboardState pastKey; 



     public Game1() 
     { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 

      graphics.PreferredBackBufferWidth = 1250; 
      graphics.PreferredBackBufferHeight = 930; 

      screenRectangle = new Rectangle(
       0, 
       0, 
       graphics.PreferredBackBufferWidth, 
       graphics.PreferredBackBufferHeight); 
     } 

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

      shieldTexture = Content.Load<Texture2D>("Shield"); 
      shieldRectangle = new Rectangle(517, 345, 250, 220); 

      spriteTexture = Content.Load<Texture2D>("PlayerShipup"); 
      spritePosition = new Vector2(640, 450); 

      backgroundTexture = Content.Load<Texture2D>("Background"); 
      backgroundRectangle = new Rectangle(0, 0, 1250, 930); 

      // TODO: use this.Content to load your game content here 
     } 

     /// <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 (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
       this.Exit(); 

      // TODO: Add your update logic here 

      if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space)) 
       Shoot(); 
      pastKey = Keyboard.GetState(); 

      spritePosition = spriteVelocity + spritePosition; 

      spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y, 
       spriteTexture.Width, spriteTexture.Height); 
      spriteOrigin = new Vector2(spriteRectangle.Width/2, spriteRectangle.Height/2); 

      if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f; 
      if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f; 

      if (Keyboard.GetState().IsKeyDown(Keys.Up)) 
      { 
       spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity; 
       spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity; 
      } 
      else if (Vector2.Zero != spriteVelocity) 
      { 
       float i = spriteVelocity.X; 
       float j = spriteVelocity.Y; 

       spriteVelocity.X = i -= friction * i; 
       spriteVelocity.Y = j -= friction * j; 


       base.Update(gameTime); 

      } 
     } 

     public void UpdateBullets() 
     { 
      foreach (Bullets bullet in bullets) 
      { 
       bullet.position += bullet.velocity; 
       if (Vector2.Distance(bullet.position, spritePosition) > 100) 
        bullet.isVisible = false; 
      } 
      for (int i = 0; i < bullets.Count; i++) 
      { 
       if(!bullets[i].isVisible) 
       { 
        bullets.RemoveAt(i); 
        i--; 


       } 


      } 
     } 

     public void Shoot() 
     { 
      Bullets newBullet = new Bullets(Content.Load<Texture2D>("ball")); 
      newBullet.velocity = new Vector2((float)Math.Cos(rotation),(float)Math.Sin(rotation)) * 5f + spriteVelocity; 
      newBullet.position = spritePosition + newBullet.velocity * 5; 
      newBullet.isVisible = true; 

      if(bullets.Count() < 20) 
       bullets.Add(newBullet); 
     } 



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

      spriteBatch.Begin(); 
      spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White); 
      spriteBatch.Draw(shieldTexture, shieldRectangle, Color.White); 
      foreach (Bullets bullet in bullets) 
       bullet.Draw(spriteBatch); 
      spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0); 
      spriteBatch.End(); 


      // TODO: Add your drawing code here 

      base.Draw(gameTime); 
     } 
    } 

我要去哪裏錯了?

+0

快速查看您的遊戲課程,我似乎沒有看到您在哪裏調用UpdateBullets? – borrillis

+0

中途代碼它說public void UpdateBullets() –

+0

@MarcBrooks你已經定義了方法,但你似乎沒有在你的代碼中調用它。 –

回答

2

當您繪製子彈時,您將原點作爲參數傳遞,但從未爲其設置值。你應該在想要成爲原點的圖像上找到點(因此,如果將子彈放置在0,0處,那麼圖像的一部分將位於0,0上)。

如果您沒有爲變量設置一個值,然後嘗試將其傳遞給函數,如果函數需要它,那麼這將導致程序崩潰。

嘗試0,0第一所以在類

Vector2 origin=new Vector2(0,0); 

這應該使你的代碼的工作,調整根據您的喜好原點。

而不是公開這些變量是更好的做法,使私人和創建獲取和設置功能的項目符號來設置它們或獲取值。這最大限度地減少了不可預知的訪問和修改的風險

編輯:再次看到意識到,雖然問題不是這個問題。

protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
      this.Exit(); 

     updateBullets(); 
     ... 
    } 

您需要實際調用您的更新功能updateBullets,它不會自動調用

+0

使用屬性的問題在於XNA使用了大量可能導致問題的結構體(例如obj.SomeV2.X),公共字段在許多情況下往往效果更好。 – Nate

+0

我沒有用XNA做過多的事情,也沒有遇到過這個問題,但是在C++中沒有這樣的問題。除了可讀性外,我認爲公衆對子彈屬性沒有任何好處? – user1646196

+0

自從我觸及代碼之後,我已經有一段時間了,但是我記得當我有屬性時,在XNA框架中使用的引用與值類型有問題。如果我能找到具體問題,我會發布它。 – Nate

0

我修改你的GameUpdate方法來調用你的UpdateBullets方法,現在子彈精靈將在旅行方向然後消失。

我還修復了Shoot()方法,以根據船隻旋轉的方向正確引導子彈。

protected override void Update(GameTime gameTime) 
    { 
     // Allows the game to exit 
     if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
      this.Exit(); 

     // TODO: Add your update logic here 

     if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space)) 
      Shoot(); 
     pastKey = Keyboard.GetState(); 

     spritePosition = spriteVelocity + spritePosition; 

     spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y, 
      spriteTexture.Width, spriteTexture.Height); 
     spriteOrigin = new Vector2(spriteRectangle.Width/2, spriteRectangle.Height/2); 

     if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f; 
     if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f; 

     if (Keyboard.GetState().IsKeyDown(Keys.Up)) 
     { 
      spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity; 
      spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity; 
     } 
     else if (Vector2.Zero != spriteVelocity) 
     { 
      float i = spriteVelocity.X; 
      float j = spriteVelocity.Y; 

      spriteVelocity.X = i -= friction * i; 
      spriteVelocity.Y = j -= friction * j; 


      base.Update(gameTime); 

     } 
     UpdateBullets(); 
    } 
    public void Shoot() 
    { 
     Bullets newBullet = new Bullets(Content.Load<Texture2D>("ball")); 
     newBullet.velocity = new Vector2((float)Math.Sin(rotation), (float)Math.Cos(rotation)) * new Vector2(5f,-5f) + spriteVelocity; 
     newBullet.position = spritePosition + newBullet.velocity * 5; 
     newBullet.isVisible = true; 

     if (bullets.Count < 20) 
      bullets.Add(newBullet); 
    } 
+0

是的,它可以工作,可悲的是我的方向計算是關閉的,因爲我想讓子彈從船的北點發射./ \。這是我的PlayerShipup sprite的一個例子改變了子彈的來源,使它們在。\ /產卵。然而,精靈北端的方向拉到右邊,我會改變它,以便它們在北方向發射,任何提示? –

+0

好的,我更新了我的答案,你的位置變化射擊現在應該爲你的子彈提供正確的方向。 – borrillis

+0

啊歡呼,完美的作品。 –