XNA - Use Mouse To Rotate & Arrow Keys To Scroll A Linearly Wrapped Texture:
- by The Thing
Using XNA I'm working on my first, relatively simple, videogame for the PC.
At the moment my game window is 1024 X 768 and I have a 'Starfield' linearly wrapped background texture 1280 X 1280 in size whose origin has been set to its center point (width / 2, height / 2).
This texture is drawn onscreen using (graphics.PreferredBackBufferWidth / 2, graphics.PreferredBackBufferHeight / 2) to place the origin in the center of the window.
I want to be able to use the horizontal movement of the mouse to rotate my texture left or right and use the arrow keys to scroll the texture in four directions.
From my own related coding experiments I have found that once I rotate the texture it no longer scrolls in the direction I want, it's as if somehow the XNA framework's 'sense of direction' has been 'rotated' along with the texture.
As an example of what I've described above lets say I rotate the texture 45 degrees to the right, then pressing the up arrow key results in the texture scrolling diagonally from top-right to bottom-left. This is not what I want, regardless of the degree or direction of rotation I want my texture to scroll straight up, straight down, or to the left or right depending on which arrow key was pressed.
How do I go about accomplishing this? Any help or guidance is appreciated.
To finish up there are two points I'd like to clarify:
[1] The reason I'm using linear wrapping on my starfield texture is that it gives a nice impression of an endless starfield.
[2] Using a texture at least 1280 X 1280 in conjunction with a game window of 1024 X 768 means that at no point in it's rotation will the edges of the texture become visible.
Thanks for reading.....
Update # 1 - as requested by RCIX:
The code below is what I was referring to earlier when I mentioned 'related coding experiments'. As you can see I am scrolling a linearly wrapped texture in the direction I've moved the mouse relative to the center of the screen. This works perfectly if I don't rotate the texture, but once I do rotate it the direction of the scrolling gets messed up for some reason.
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);
}
}