Tick Rate and Time Deltas

Smooth Acceleration and Deceleration

How can we create smooth acceleration and deceleration effects using time deltas?

Abstract art representing computer programming

Creating smooth acceleration and deceleration effects is a common requirement in game development, especially for character movement or vehicle simulations. By using time deltas, we can ensure these effects are consistent across different frame rates. Let's explore how to implement this:

Linear Acceleration

The simplest form of acceleration is linear. Here's how you can implement it:

#include <SDL.h>
#include <iostream>

class MovingObject {
private:
  float position = 0.0f;
  float velocity = 0.0f;

  // Units per second squared
  float acceleration = 5.0f;

  // Maximum velocity
  float maxVelocity = 10.0f;

public:
  void update(float dt) {
    // Apply acceleration
    velocity += acceleration * dt;

    // Clamp velocity to maximum
    if (velocity > maxVelocity) velocity =
      maxVelocity;

    // Update position
    position += velocity * dt;

    std::cout << "Position: " << position <<
      ", Velocity: " << velocity << "\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  MovingObject obj;
  Uint64 previousTime = SDL_GetTicks64();

  for (int i = 0; i < 100; ++i) {
    Uint64 currentTime = SDL_GetTicks64();
    float dt = (currentTime - previousTime) /
      1000.0f;
    previousTime = currentTime;

    obj.update(dt);

    SDL_Delay(16); // Simulate ~60 FPS
  }

  SDL_Quit();
  return 0;
}
Position: 0, Velocity: 0
Position: 0.001445, Velocity: 0.085
Position: 0.004335, Velocity: 0.17
Position: 0.008335, Velocity: 0.25
Position: 0.01403, Velocity: 0.335
Position: 0.02067, Velocity: 0.415
...

This creates a linear acceleration effect. The object starts from rest and gradually increases its speed until it reaches the maximum velocity.

Smooth Acceleration and Deceleration

For a smoother, more natural-feeling acceleration and deceleration, we can use easing functions. One common approach is to use a sigmoid function:

#include <SDL.h>
#include <cmath>
#include <iostream>

class SmoothMovingObject {
private:
  float position = 0.0f;
  float targetPosition = 100.0f;
  // Maximum speed
  float maxSpeed = 50.0f;
  // Higher values make the motion smoother
  float smoothness = 2.0f;

public:
  void update(float dt) {
    float distanceToTarget = targetPosition -
      position;
    float speed =
      maxSpeed *
      (2 / (1 + std::exp(
        -smoothness * distanceToTarget /
        maxSpeed)) - 1);

    position += speed * dt;

    std::cout << "Position: " << position <<
      ", Speed: " << speed << "\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  SmoothMovingObject obj;
  Uint64 previousTime = SDL_GetTicks64();

  for (int i = 0; i < 600; ++i) {
    Uint64 currentTime = SDL_GetTicks64();
    float dt = (currentTime - previousTime) /
      1000.0f;
    previousTime = currentTime;

    obj.update(dt);

    SDL_Delay(16); // Simulate ~60 FPS
  }

  SDL_Quit();
  return 0;
}

This implementation uses a sigmoid function to create a smooth S-curve for acceleration and deceleration. In this example, the object decelerates as it approaches the target position.

Position: 0, Speed: 48.2014
Position: 0.819423, Speed: 48.2014
Position: 1.63785, Speed: 48.1426
Position: 2.45524, Speed: 48.0819
Position: 3.27157, Speed: 48.0194
...

Interpolation for Smooth Movement

Another approach is to use interpolation, which can create very smooth movement between two points:

#include <SDL.h>
#include <iostream>

class InterpolatingObject {
private:
  float startPosition = 0.0f;
  float endPosition = 100.0f;

  // Interpolation factor
  float t = 0.0f;

  // Time to complete the movement
  float duration = 2.0f;

public:
  void update(float dt) {
    t += dt / duration;
    if (t > 1.0f) t = 1.0f;

    // Smooth step function for easing
    float smoothT = t * t * (3 - 2 * t);

    float position = startPosition + (
      endPosition - startPosition) * smoothT;

    std::cout << "Position: " << position <<
      ", T: " << t << "\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  InterpolatingObject obj;
  Uint64 previousTime = SDL_GetTicks64();

  while (true) {
    Uint64 currentTime = SDL_GetTicks64();
    float dt = (currentTime - previousTime) /
      1000.0f;
    previousTime = currentTime;

    obj.update(dt);

    SDL_Delay(16); // Simulate ~60 FPS

    // Stop after 2 seconds
    if (dt >= 2.0f) break;
  }

  SDL_Quit();
  return 0;
}
Position: 0, T: 0
Position: 0.0215522, T: 0.0085
Position: 0.0807766, T: 0.0165
Position: 0.184375, T: 0.025
...
Position: 99.9332, T: 0.985
Position: 99.9874, T: 0.9935
Position: 100, T: 1

This method uses a smooth step function to interpolate between the start and end positions, creating a smooth acceleration and deceleration effect.

By using these techniques with time deltas, you can create smooth, frame-rate independent acceleration and deceleration effects in your games. Remember to experiment with different easing functions and parameters to find the feel that best suits your game's needs.

This Question is from the Lesson:

Tick Rate and Time Deltas

Learn how to create smooth, time-aware game loops that behave consistently across different hardware configurations

Answers to questions are automatically generated and may not have been reviewed.

This Question is from the Lesson:

Tick Rate and Time Deltas

Learn how to create smooth, time-aware game loops that behave consistently across different hardware configurations

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 67 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved