I have been making an asteroids clone, in C#. However, the ship's movement is... not quite right.
My plan is this: there is a speed, and two directions, namely the direction the ship is facing (visual), and the one is is going (motion). The ship would travel its speed in its motion direction continually (no friction). If you were to press the up key, however, it would generate a vector of a predetermined value (thrust per step), and it would add this vector with the current, and thus, go more in that direction. However, it is... not working. Here is my code:
KeyboardState keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Left))
direction -= 3;
else if (keyboard.IsKeyDown(Keys.Right))
direction += 3;
if (speed == 0)
speed = 0.1;
Vector2 currentVector;
currentVector.X = (float)(Math.Cos(DegreeToRadian.degreeToRadian(motionDirection)) * speed);
currentVector.Y = (float)(Math.Sin(DegreeToRadian.degreeToRadian(motionDirection)) * speed);
Vector2 keyVector;
keyVector.X = ((float)(Math.Cos(DegreeToRadian.degreeToRadian(direction)) * 10)) * (Keyboard.GetState().IsKeyDown(Keys.Up) ? 1 : 0);
keyVector.Y = ((float)(Math.Sin(DegreeToRadian.degreeToRadian(direction)) * 10)) * (Keyboard.GetState().IsKeyDown(Keys.Up) ? 1 : 0);
Vector2 newVector = Vector2.Add(currentVector, keyVector);
if (!(newVector.X == 0 || newVector.Y == 0))
{
speed = Math.Sqrt(Math.Pow(newVector.X, 2) + Math.Pow(newVector.Y, 2));
motionDirection = Math.Atan(newVector.Y / newVector.X);
}
if (speed > 10)
speed = 10;
position.X += (float) (Math.Cos(DegreeToRadian.degreeToRadian(motionDirection)) * speed);
position.Y += (float) (Math.Sin(DegreeToRadian.degreeToRadian(motionDirection)) * speed);
Note that this is C# code, but I think the issue is more of a non-language logic issue. Note that C#'s trig functions take radians, and the degreeToRadian works as expected. The keyboard works as you would expect, and is not the issue. The vectors are an object with and x and y, both floats.
The problem? Well, as I said, it.. doesn't really work. It visually turns correctly, but only moves to the right. Holding the up arrow increases its speed, of which the values are yet to be fine-tuned, but does not apply thrust in any direction but the way it was going, seemingly. Debugging through seems to indicate that the y values generated are exceedingly small - say, 3.1x10^-6 or similar. I cannot think of why this would be the case, however. In addition, thrusting left, goes right, so there is more than one issue at play here, it would seem.
Any ideas?
EDIT: I have revised my code to use radians, and it now looks like so:
double speed = 0;
double motionDirection;
double direction;
Polygon polygon;
Vector2 position;
public Player()
{
polygon = new Polygon();
polygon.addPoint(new Vector2(50, 0));
polygon.addPoint(new Vector2(-30, -10));
polygon.addPoint(new Vector2(-30, 10));
}
public void update()
{
KeyboardState keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Left))
direction -= 0.05;
if (keyboard.IsKeyDown(Keys.Right))
direction += 0.05;
if (speed == 0)
speed = 0.1;
Vector2 currentVector = new Vector2((float) (Math.Cos(motionDirection) * speed), (float) (Math.Sin(motionDirection) * speed));
Vector2 keyVector = keyboard.IsKeyDown(Keys.Up) ? new Vector2((float) (Math.Cos(direction)*2), (float) (Math.Sin(direction)*2)) : Vector2.Zero;
Vector2 newVector = Vector2.Add(currentVector, keyVector);
if (Vector2.Distance(Vector2.Zero, newVector) != 0)
{
speed = (float)Math.Sqrt(Math.Pow(newVector.X, 2) + Math.Pow(newVector.Y, 2));
motionDirection = (float)Math.Atan(newVector.Y / newVector.X);
}
if (speed > 2)
speed = 2;
position.X += newVector.X;
position.Y += newVector.Y;
It sort of works, and sort of does not. It seems to - but I cannot guarantee this - that it works going, if you picture a circle, in a direction that fallsin the right half, but shudders and has odd shifts of momentum while in the left half.