2011-07-11 116 views
0

我正在爲一臺簡單的基於XNA的PC遊戲工作,其中我有一個1024×768的遊戲屏幕窗口大小,我希望按照我移動鼠標的方向滾動一個1280 X 1280的線性包裹旋轉紋理。XNA:滾動線性包裹,旋轉紋理,向上,向下,向左和向右:

這個紋理的起源已經被設置爲中心點(640,640),然後我將這個紋理放置在我的遊戲窗口的中間位置(512,384)。

我到目前爲止的代碼(粘貼在下面的完整部分)完美地工作,直到我將旋轉引入混合。

public class Game1 : Microsoft.Xna.Framework.Game 
{ 

    GraphicsDeviceManager graphics; 

    SpriteBatch spriteBatch; 

    int x; 
    int y; 

    float z = 250f; 

    Texture2D Overlay; 

    Texture2D RotatingBackground; 

    Rectangle? sourceRectangle; 

    Color color; 

    float rotation; 

    Vector2 ScreenCenter; 

    Vector2 Origin; 

    Vector2 scale; 

    Vector2 Direction; 

    SpriteEffects effects; 

    float layerDepth; 

    public Game1() 
    { 

     graphics = new GraphicsDeviceManager(this); 

     Content.RootDirectory = "Content"; 

    } 

    protected override void Initialize() 
    { 

     graphics.PreferredBackBufferWidth = 1024; 

     graphics.PreferredBackBufferHeight = 768; 

     graphics.ApplyChanges(); 

     Direction = Vector2.Zero;  

     IsMouseVisible = true; 

     ScreenCenter = new Vector2(graphics.PreferredBackBufferWidth/2, graphics.PreferredBackBufferHeight/2); 

     Mouse.SetPosition((int)graphics.PreferredBackBufferWidth/2, (int)graphics.PreferredBackBufferHeight/2); 

     sourceRectangle = null; 

     color = Color.White; 

     rotation = 0.0f; 

     scale = new Vector2(1.0f, 1.0f); 

     effects = SpriteEffects.None; 

     layerDepth = 1.0f; 

     base.Initialize(); 

    } 

    protected override void LoadContent() 
    { 

     spriteBatch = new SpriteBatch(GraphicsDevice); 

     Overlay = Content.Load<Texture2D>("Overlay"); 

     RotatingBackground = Content.Load<Texture2D>("Background"); 

     Origin = new Vector2((int)RotatingBackground.Width/2, (int)RotatingBackground.Height/2); 

    } 


    protected override void UnloadContent() 
    { 

    } 

    protected override void Update(GameTime gameTime) 
    { 

     float timePassed = (float)gameTime.ElapsedGameTime.TotalSeconds; 

     MouseState ms = Mouse.GetState(); 

     Vector2 MousePosition = new Vector2(ms.X, ms.Y); 

     Direction = ScreenCenter - MousePosition; 

     if (Direction != Vector2.Zero) 
     { 

      Direction.Normalize(); 

     } 

     x += (int)(Direction.X * z * timePassed); 

     y += (int)(Direction.Y * z * timePassed); 


     //No rotation = texture scrolls as intended, With rotation = texture no longer scrolls in the direction of the mouse. My update method needs to somehow compensate for this.   
     //rotation += 0.01f; 

     base.Update(gameTime); 

    } 

    protected override void Draw(GameTime gameTime) 
    { 

     spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null); 

     spriteBatch.Draw(RotatingBackground, ScreenCenter, new Rectangle(x, y, RotatingBackground.Width, RotatingBackground.Height), color, rotation, Origin, scale, effects, layerDepth); 

     spriteBatch.Draw(Overlay, Vector2.Zero, Color.White); 

     spriteBatch.End(); 

     base.Draw(gameTime); 

    } 
} 

例如,如果我是紋理向右旋轉,然後從屏幕的中心直線上升移動鼠標使紋理向上斜向滾動到正確的 - 這不是我的意圖 - 如果我移動我的鼠標在任何方向上,我都希望我的紋理在這個方向上滾動,就像我從未將旋轉引入混音一樣。

我該如何改變我的Update()方法來實現這個?

感謝您的閱讀.....

回答

0

從你的問題,據我瞭解,你想要的鼠標控制攝像頭,旋轉隻影響質感。 對此,所需的更改會影響Draw方法。當調用Spritebatch.Begin時,應該使用x和y值傳遞一個變換矩陣作爲參數。這使您可以在世界座標中旋轉紋理,同時獨立於旋轉移動相機。

檢查此問題 - Spritebatch.Begin() Transform Matrix - 瞭解變換矩陣的工作原理。

+0

感謝您的回覆,Elideb。我所有的'相機'組成的是一個矩形,它顯示了我的1280 X 1280線性包裹紋理的一部分。我可能是錯的,但我不相信我需要一個轉換矩陣來做我想做的事情,因爲我發佈的代碼工作得很好,直到我在其原點周圍引入了紋理旋轉。我需要以某種方式調整x和y值以補償旋轉運動。例如 - 如果我將鼠標水平移動到左側,我希望紋理在繞其原點旋轉的同時向左滾動。 –

0

這似乎工作。可能有一個更優雅的解決方案,但它確實是一個需要解決的問題。

public class Game1 : Microsoft.Xna.Framework.Game 
{ 

    GraphicsDeviceManager graphics; 

    SpriteBatch spriteBatch; 

    int x; 
    int y; 

    float z = 250f; 

    Texture2D Overlay; 

    Texture2D RotatingBackground; 

    Rectangle? sourceRectangle; 

    Color color; 

    float rotation; 

    Vector2 ScreenCenter; 

    Vector2 Origin; 

    Vector2 scale; 

    Vector2 Direction; 

    SpriteEffects effects; 

    float layerDepth; 

    public Game1() 
    { 

     graphics = new GraphicsDeviceManager(this); 

     Content.RootDirectory = "Content"; 

    } 

    protected override void Initialize() 
    { 

     graphics.PreferredBackBufferWidth = 1024; 

     graphics.PreferredBackBufferHeight = 768; 

     graphics.ApplyChanges(); 

     Direction = Vector2.Zero; 

     IsMouseVisible = true; 

     ScreenCenter = new Vector2(graphics.PreferredBackBufferWidth/2, graphics.PreferredBackBufferHeight/2); 

     Mouse.SetPosition((int)graphics.PreferredBackBufferWidth/2, (int)graphics.PreferredBackBufferHeight/2); 

     sourceRectangle = null; 

     color = Color.White; 

     rotation = 0.0f; 

     scale = new Vector2(1.0f, 1.0f); 

     effects = SpriteEffects.None; 

     layerDepth = 1.0f; 

     base.Initialize(); 

    } 

    protected override void LoadContent() 
    { 

     spriteBatch = new SpriteBatch(GraphicsDevice); 

     Overlay = Content.Load<Texture2D>("Overlay"); 

     RotatingBackground = Content.Load<Texture2D>("Background"); 

     Origin = new Vector2((int)RotatingBackground.Width/2, (int)RotatingBackground.Height/2); 

    } 


    protected override void UnloadContent() 
    { 

    } 

    protected override void Update(GameTime gameTime) 
    { 
     float timePassed = (float)gameTime.ElapsedGameTime.TotalSeconds; 

     MouseState ms = Mouse.GetState(); 

     Vector2 MousePosition = new Vector2(ms.X, ms.Y); 

     Direction = ScreenCenter - MousePosition; 

     if (Direction != Vector2.Zero) 
     { 

      float angle = 0; 
      angle = (float)Math.Atan2(Direction.Y, Direction.X) - rotation; 
      Direction.X = (float)Math.Cos(angle); 
      Direction.Y = (float)Math.Sin(angle); 
      Direction.Normalize(); 
     } 

     x += (int)(Direction.X * z * timePassed); 
     y += (int)(Direction.Y * z * timePassed); 


     //No rotation = texture scrolls as intended, With rotation = texture no longer scrolls in the direction of the mouse. My update method needs to somehow compensate for this.   
     rotation += .01f ; 
     if (rotation > MathHelper.Pi * 2) 
     { 
      rotation -= (MathHelper.Pi * 2); 
     } 
     base.Update(gameTime); 

    } 

    protected override void Draw(GameTime gameTime) 
    { 

     spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null); 

     spriteBatch.Draw(RotatingBackground, ScreenCenter, new Rectangle(x, y, RotatingBackground.Width, RotatingBackground.Height), color, rotation, Origin, scale, effects, layerDepth); 
     spriteBatch.Draw(Overlay, Vector2.Zero, Color.White); 

     spriteBatch.End(); 

     base.Draw(gameTime); 

    } 
} 
相關問題