private void UpdatePosition(GameTime gameTime)
{
/* Basing my calculations on this:
* Velocity.X = VelocityFactor * MaxVelocity.X * cos(Rotation)
* Velocity.Y = VelocityFactor * MaxVelocity.X * sin(Rotation)
*
* OldVelocity = Velocity;
* Position += (OldVelocity + Velocity) * 0.5 * dt;
*
* Fixed thanks to Daniel G.
*/
if (kb.IsKeyDown(Keys.W))
velocityFactor = 1;
if (kb.IsKeyDown(Keys.S))
velocityFactor = -1;
if (kb.IsKeyDown(Keys.W) && kb.IsKeyDown(Keys.S))
velocityFactor = 0;
if (World.Console.PromptActive)
velocityFactor = 0;
oldPosition = Position;
oldVelocity = Velocity;
oldAngularVelocity = AngularVelocity;
oldRotation = Rotation;
if (kb.IsKeyDown(Keys.W) || kb.IsKeyDown(Keys.S))
{
newVelocity = new Vector2((Single)Math.Cos(Rotation - Math.PI / 2),
(Single)Math.Sin(Rotation - Math.PI / 2));
newVelocity *= velocityFactor *= maxVelocity;
}
else
{
newVelocity = Vector2.Zero;
}
if (kb.IsKeyDown(Keys.A))
angularVelocityFactor = -1;
if (kb.IsKeyDown(Keys.D))
angularVelocityFactor = 1;
if (kb.IsKeyDown(Keys.A) && kb.IsKeyDown(Keys.D))
angularVelocityFactor = 0;
if (World.Console.PromptActive)
angularVelocityFactor = 0;
if (kb.IsKeyDown(Keys.A) || kb.IsKeyDown(Keys.D))
newAngularVelocity = angularVelocityFactor * maxAngularVelocity;
else
newAngularVelocity = 0;
// update based on newly found out velocities/positions
Velocity = (oldVelocity + newVelocity) * 0.5f;
newPosition += Velocity * (Single)gameTime.ElapsedGameTime.TotalSeconds;
AngularVelocity = MathHelper.WrapAngle((Single)(newAngularVelocity + oldAngularVelocity) * 0.5f);
newRotation += AngularVelocity * (Single)gameTime.ElapsedGameTime.TotalSeconds;
// check for any collisions at our new location
Single overlap;
Vector2 collisionProjection;
if (FindNearestCollision(World.MapGrid.PotentialIntersects(this), out overlap, out collisionProjection))
{
// move our position back to old position
newPosition += overlap * collisionProjection;
oldPosition = newPosition;
}
// finally confirm our position
Position = newPosition;
Rotation = newRotation;
// now see if we should send out a MsgPlayerClientUpdate
if ((lastMsgUpdate + msgUpdateFrequency) < gameTime.TotalGameTime)
{
lastMsgUpdate = gameTime.TotalGameTime;
NetOutgoingMessage playerClientUpdateMessage = World.ServerLink.CreateMessage();
MsgPlayerClientUpdatePacket playerClientUpdatePacket = new MsgPlayerClientUpdatePacket(Position, Rotation);
playerClientUpdateMessage.Write((Byte)playerClientUpdatePacket.MsgType);
playerClientUpdatePacket.Write(playerClientUpdateMessage);
World.ServerLink.SendMessage(playerClientUpdateMessage, NetDeliveryMethod.UnreliableSequenced, 0);
}
}