2011-07-25 27 views
0

我使用VS2010與C#和XNA 4.0一起。我正在關注Aaron Reed的「學習XNA 4.0」一書。我將相機遊戲組件添加到了我的項目中,但這款相機的表現真的很奇怪。移動鼠標使其「跳」,然後崩潰。我不知道是什麼原因造成的。它看起來代碼與書中的代碼幾乎完全相同。它的工作較早,但現在不是,雖然我不記得我是否改變了它(我想不是)。請注意,我只在遊戲中註冊此組件,僅此而已。它應該可以工作,但它不會。任何幫助都會很棒。這裏的代碼:我的相機有什麼問題?

using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Input; 

namespace MyGame 
{ 
    public class Camera : Microsoft.Xna.Framework.GameComponent 
    { 

     public Matrix View { get; protected set; } 
     public Matrix Projection { get; protected set; } 
     public Vector3 CameraPosition { get; protected set; } 
     public Vector3 CameraDirection { get; protected set; } 
     public Vector3 CameraUp { get; protected set; } 
     private MouseState prevMouseState; 

     public Camera(Game game, Vector3 pos, Vector3 target, Vector3 up) 
      : base(game) 
     { 
      // Some initialization of camera. 
      CameraPosition = pos; 
      CameraDirection = target - pos; 
      CameraDirection.Normalize(); 
      CameraUp = up; 
      CreateLookAt(); 

      Projection = Matrix.CreatePerspectiveFieldOfView(
       MathHelper.PiOver4,     
       (float)Game.Window.ClientBounds.Width/
       (float)Game.Window.ClientBounds.Height, 
       1f, 3000f); 
     } 

     public override void Initialize() 
     { 
      // Set mouse position and do initial get state. 
      Mouse.SetPosition(Game.Window.ClientBounds.Width/2, 
       Game.Window.ClientBounds.Height/2); 
      prevMouseState = Mouse.GetState(); 

      base.Initialize(); 
     } 


     public override void Update(GameTime gameTime) 
     { 
      // Standard WSAD keyboard movement. 
      if (Keyboard.GetState().IsKeyDown(Keys.W)) 
       CameraPosition += CameraDirection; 
      if (Keyboard.GetState().IsKeyDown(Keys.S)) 
       CameraPosition -= CameraDirection; 
      if (Keyboard.GetState().IsKeyDown(Keys.A)) 
       CameraPosition += Vector3.Cross(CameraUp, CameraDirection); 
      if (Keyboard.GetState().IsKeyDown(Keys.D)) 
       CameraPosition -= Vector3.Cross(CameraUp, CameraDirection); 

      // Yaw rotation (via mouse). 
      CameraDirection = Vector3.Transform(CameraDirection, 
       Matrix.CreateFromAxisAngle(CameraUp, (-MathHelper.PiOver4/150) * 
       (Mouse.GetState().X - prevMouseState.X) 
       )); 

      // Pitch rotation (via mouse). 
      CameraDirection = Vector3.Transform(CameraDirection, 
       Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
       (MathHelper.PiOver4/100) * 
       (Mouse.GetState().Y - prevMouseState.Y) 
       )); 

      CameraUp = Vector3.Transform(CameraUp, 
       Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
       (MathHelper.PiOver4/100) * 
       (Mouse.GetState().Y - prevMouseState.Y) 
       )); 

      prevMouseState = Mouse.GetState(); 

      CreateLookAt(); 
      base.Update(gameTime); 
     } 

     private void CreateLookAt() 
     { 
      View = Matrix.CreateLookAt(CameraPosition, 
       CameraPosition + CameraDirection, CameraUp); 
     } 
    } 
} 

有人可以請檢查此代碼是否適用於他?任何想法都會很棒!

//編輯1: 在遊戲中的初始化我使用代碼:

Camera cam = new Camera(this, new Vector3(0, 0, 100), Vector3.Zero, Vector3.Up); 
Components.Add(cam); 

,然後我畫模型。我在模型的BasicEffect中使用凸輪的視圖和投影矩陣。

//編輯2: 有些嚴重錯誤。我做了一些調試,看起來有些時候Vector3對象的X,Y,Z屬性設置爲NaN。我無法瞭解如何以及何時。另外(也許這不算什麼),運行一段時間後,gameTime顯示經過的遊戲時間僅爲16毫秒(就像跳過幀一樣),並且遊戲運行緩慢。無論何時調試,這16毫秒總是相同的。

有可能我搞砸了XNA/C#設置?如果是這樣,有人可以給我任何暗示現在該做什麼?

+1

有沒有例外?錯誤?更多詳情? – Oded

+0

沒有例外,沒有錯誤。它運作良好,但是當我移動鼠標時,屏幕變得瘋狂。然後我只看到藍屏,根本沒有模特。也許「崩潰」是一個壞詞,但這就是我的意思。 :) – freakish

+0

嘗試將(MathHelper.PiOver4/100)更改爲(MathHelper.PiOver4/100.0)並查看它是否不是整數轉換 – djdanlib

回答

2
// Pitch rotation (via mouse). 
    CameraDirection = Vector3.Transform(CameraDirection, 
     Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
     (MathHelper.PiOver4/100) * 
     (Mouse.GetState().Y - prevMouseState.Y) 
     )); 

    CameraUp = Vector3.Transform(CameraUp, 
     Matrix.CreateFromAxisAngle(Vector3.Cross(CameraUp, CameraDirection), 
     (MathHelper.PiOver4/100) * 
     (Mouse.GetState().Y - prevMouseState.Y) 
     )); 

無論何時使用CreateFromAxisAngle,第一個參數(軸)都需要是單位長度向量。如果它不是一個單位長度的向量,它將導致一個扭曲的(傾斜的)矩陣和一個超過(或低於)旋轉的矩陣。

只要你跨兩個向量,結果很少會出現單位長度向量。產生交叉單位長度的結果。試試這個:

Vector3.Transform(CameraDirection, Matrix.CreateFromAxisAngle(Vector3.Normalize(Vector3.Cross(CameraUp, CameraDirection)), ... 

通過添加'Normalize',它使交叉的結果成爲單位長度的向量。不要忘記對偏航線也一樣。

+0

它的工作!那麼,不完全如你所寫,因爲規範化方法是空洞的(至少在XNA 4.0中)。 :) 非常感謝你。儘管我感到非常驚訝,因爲代碼是從書中提取的,而且早期它的工作沒有任何問題。我想知道爲什麼會發生?無論如何謝謝你! – freakish

+0

如果你跨越兩個單位長度的向量,它們碰巧相距90度,那麼結果將是單位長度。我想知道這是否是因爲它之前爲什麼正常工作。 –

+0

是的,我知道這個理論。叉積的長度等於長度乘以矢量之間夾角餘弦的乘積。但我認爲這個長度在CreateFromAxisAngle方法中並不重要。猜猜我錯了。 :) 謝謝! – freakish