Search code examples
c#xna

How to control acceleration and de-acceleration in my C# game


I am building a driving game. The view is a perspective one and the player's perspective is from behind the car which is driving forward. When the car is driving forward, all the environment around it moves downwards and scales (This is looking quite good now) which gives the impression of the car moving forward. Now, I want to have some realistic driving controls, so that the car builds up speed and then slows down gradually when the up arrow is released. Currently, I call all the move functions for several sprites when the up arrow is pressed. I am looking for a way to control this so that the functions are not called as often when the car is slow etc etc. The code I have so far is:

   protected void Drive()
    {
        KeyboardState keyState = Keyboard.GetState();

        if (keyState.IsKeyDown(Keys.Up))
        {
            MathHelper.Clamp(++TruckSpeed, 0, 100);
        }
        else
        {
            MathHelper.Clamp(--TruckSpeed, 0, 100);
        }

        // Instead of using the condition below, I want to use the TruckSpeed
        // variable some way to control the rate at which these are called 
        // so I can give the impression of acceleration and de-acceleration.

        if (keyState.IsKeyDown(Keys.Up))
        {
            // Lots of update calls in here
        }
   }

I thought this should be easy but for some reason, I cannot make any sense out of it. Would really appreciate some help here! Thanks


Solution

  • First suggestion, don't use ++ and --. Make your TruckSpeed increase at a rate multiplied by the Delta Time. This means that your acceleration and deceleration will work the same on slower and faster computers and will be independent of frame rate hickups. You can also have different increase and decrease rates for better control over your gameplay.

    Something along the lines of:

    protected void Drive(GameTime gameTime) // Pass your game time
    {
        KeyboardState keyState = Keyboard.GetState();
        if (keyState.IsKeyDown(Keys.Up))
        {
            TruckSpeed += AccelerationRatePerSecond * gameTime.ElapsedGameTime.TotalSeconds;
        }
        else
        {
            TruckSpeed -= DecelerationRatePerSecond * gameTime.ElapsedGameTime.TotalSeconds;
        }
        MathHelper.Clamp(TruckSpeed, 0, 100);
        ...
    

    Also, you can probably replace

    if (keyState.IsKeyDown(Keys.Up))
    

    by

    if (TruckSpeed > 0)
    

    It's probably simpler to attach the camera to your model and move that in the environment instead of moving your entire environment around the Truck though...