# 2D Topdown Shooter - Player Movement Relative to Mouse

I'm trying to make a topdown 2D space game for my school project. I'm almost done but I just want to add a few little things to make the game more fun to play.

``````if (keystate.IsKeyDown(Keys.W))
{
vPlayerPos += Vector2.Normalize(new Vector2(Mouse.GetState().X - vPlayerPos.X, Mouse.GetState().Y - vPlayerPos.Y)) * 3;

rPlayer.X = (int)vPlayerPos.X;
rPlayer.Y = (int)vPlayerPos.Y;
}

if (keystate.IsKeyDown(Keys.S))
{
vPlayerPos += Vector2.Normalize(new Vector2(Mouse.GetState().X - vPlayerPos.X, Mouse.GetState().Y - vPlayerPos.Y)) * -3;
rPlayer.X = (int)vPlayerPos.X;
rPlayer.Y = (int)vPlayerPos.Y;
}
``````

This is what i use to move towards and away from my mouse crossair. I tried to make a somewhat similar function to make it strafe with "A" and "D". But for some reason I just couldn't get it done.

Any thoughts?

-
So you are not having problems with W and S, just A and D? – Jonathan Dickinson Nov 22 '11 at 11:24
Jonathan Dickinson's got an answer for you: rotate your normal 90 degrees to get a tangent. A solution based on polar-coordinates would be more accurate. But is perhaps unnecessary (depends how fast you are moving - and how far per frame). – Andrew Russell Nov 22 '11 at 12:21
@AndrewRussell would using a normalized vector really be less accurate than polar coords? I mean, you would need to be moving pretty damn fast in order hit IEEE float inaccuracies. – Jonathan Dickinson Nov 22 '11 at 16:14

## 1 Answer

I assume you mean that forwards and backwards are working fine (from what I can tell they should). In order to move left and right you merely need to make the `Vector2` perpendicular and use almost the exact same logic:

``````public static class Vector2Extensions
{
public static Vector2 Perpendicular(this Vector2 vector)
{
// Swap y and x, and negate y.
return new Vector2(-vector.Y, vector.X);
}
}
``````

Now your logic would look something like (notice I have improved the layout and made it easier to understand):

``````var mouseState = Mouse.GetState();
var mouseOffset = new Vector2(mouseState.X - vPlayerPos.X, mouseState.Y - vPlayerPos.Y);
var movement = mouseOffset.Normalize()
// Your game is currently frame-rate dependant, you should be doing this.
// See: http://gamedev.stackexchange.com/q/19529/1494
* 3000 * (float)gameTime.ElapsedGameTime.TotalSeconds;
var perpendicular = movement.Perpendicular();

if (keystate.IsKeyDown(Keys.W))
vPlayerPos += movement;
if (keystate.IsKeyDown(Keys.S))
vPlayerPos -= movement;

// You might need change the +/- here around.
if (keystate.IsKeyDown(Keys.A))
vPlayerPos += perpendicular;
if (keystate.IsKeyDown(Keys.D))
vPlayerPos -= perpendicular;

// You shouldn't do this. If you need them as int cast them when you need them as such.
// rPlayer.X = (int)vPlayerPos.X;
// rPlayer.Y = (int)vPlayerPos.Y;
``````

Side note: Good thinking with using a normalized vector to determine movement, this is probably the 'best' way to do something like this.

-
var movement = mouseOffset.Normalize() // Your game is currently frame-rate dependant, you should be doing this. // See: gamedev.stackexchange.com/q/19529/1494 * 3000 * (float)gameTime.ElapsedGameTime.TotalSeconds; – Jarmo Dec 1 '11 at 17:45
For some reason i acn't get that part right... – Jarmo Dec 1 '11 at 17:45
@Jarmo that value will need tweaking, get it working with framerate dependance first if you are having problems - then progress to framerate independance. – Jonathan Dickinson Dec 1 '11 at 23:00