2010-08-25 60 views
4

我正在使用XNA遊戲,我正在使用ViewPort.Project和ViewPort.Unproject來轉換世界座標和從世界座標轉換。目前,我使用這些爲我用SpriteBatch繪製的每個對象。我想要做的是計算一個矩陣,我可以發送給SpriteBatch.Begin爲我進行屏幕空間轉換。XNA ViewPort投影和SpriteBatch

下面是功能我目前使用的翻譯,並從屏幕空間:

 Vector2 ToWorldCoordinates(Vector2 pixels) 
    { 
     Vector3 worldPosition = graphics.GraphicsDevice.Viewport.Unproject(new Vector3(pixels, 0), 
       Projection, View, Matrix.Identity); 
     return new Vector2(worldPosition.X, worldPosition.Y); 
    } 

    Vector2 ToScreenCoordinates(Vector2 worldCoords) 
    { 
     var screenPositon = graphics.GraphicsDevice.Viewport.Project(new Vector3(worldCoords, 0), 
       Projection, View, Matrix.Identity); 
     return new Vector2(screenPositon.X, screenPositon.Y); 
    } 

視角設定爲Matrix.Identity和投影設置像這樣:

Projection = Matrix.CreateOrthographic(40 * graphics.GraphicsDevice.Viewport.AspectRatio, 40, 0, 1); 

這裏是我目前如何畫東西:

  spriteBatch.Begin(); 
     foreach (var thing in thingsToDraw) 
     { 
      spriteBatch.Draw(thing.Texture, ToScreenCoordinates(thing.PositionInWorldCoordinates), thing.Color); 
      spriteBatch.End(); 
     } 
     spriteBatch.End(); 

這是我想要做的,而不是(使用XNA 4.0 v SpriteBatch.Begin的版爲())

  // how do I calculate this matrix? 
     Matrix myTransformationMatrix = GetMyTransformationMatrix(); 

     spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, null, 
      myTransformationMatrix); 

     foreach (var thing in thingsToDraw) 
     { 
      // note: no longer converting each object's position to screen coordinates 
      spriteBatch.Draw(thing.Texture, thing.PositionInWorldCoordinates, thing.Color); 
      spriteBatch.End(); 
     } 
     spriteBatch.End(); 

回答

12

我已經寫SpriteBatch和各種 「空間」(世界上,投影,客戶端等)hereherehere。這些答案可能值得一讀。

SpriteBatch假定您的世界空間與客戶端空間是一樣的 - 然而這是很多像素高和寬的視口,原點左上角,Y +下降。

它看起來像(根據您對CreateOrthographic的使用),您希望您的世界空間在屏幕上顯示爲40個單位高,然而許多單位將適合寬度。您還希望世界原點位於屏幕的中心,並且Y +已啓動。

因此,您必須在其間插入另一個矩陣,以將您的世界空間轉換爲客戶端空間。我相信正確的矩陣是(在psudocode):scale(40/viewport.Height) * scale(1, -1) * translate(viewport.Width/2, viewport.Height/2)。縮放,翻轉和翻譯從世界到客戶。

您還必須記住,精靈假定Y +已關閉。所以你必須將(1, -1)比例傳遞給SpriteBatch.Draw,否則它們將被反轉(並且由於背面剔除而不可見)。

+0

夢幻般的答案。對於正在閱讀的其他人,如果您還想要一個代表相機的視圖矩陣,我認爲正確的順序是執行View * scale(40/viewport.Height)* scale(1,-1)* translate(viewport。寬度/ 2,viewport.Height/2),其中視圖變換以世界空間單位表示。 – 2010-08-26 14:49:04