Customising Mouse Cursors

Adding Physics to Cursor Movement

Is there a way to limit how fast the cursor can move across the screen? Like adding weight/momentum to it?

Abstract art representing computer programming

Adding physics to cursor movement can create interesting effects like momentum and weight. This is best achieved using custom cursor rendering rather than system cursors. Here's how to implement it:

Physics-Based Cursor Implementation

Here’s an example of a PhysicsCursor class:

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

class PhysicsCursor {
 public:
  PhysicsCursor(
    float maxSpeed = 1000.0f,
    float acceleration = 2000.0f,
    float friction = 5.0f
  ) : MaxSpeed{maxSpeed},
      Acceleration{acceleration},
      Friction{friction} {}

  void Update(float deltaTime) {
    // Get real mouse position
    int mouseX, mouseY;
    SDL_GetMouseState(&mouseX, &mouseY);

    // Calculate target vector
    float targetX{
      static_cast<float>(mouseX) - PosX};
    float targetY{
      static_cast<float>(mouseY) - PosY};

    // Apply acceleration towards target
    float distance{std::sqrt(
      targetX * targetX + targetY * targetY)};

    if (distance > 0.1f) {
      float dirX{targetX / distance};
      float dirY{targetY / distance};

      VelX += dirX * Acceleration * deltaTime;
      VelY += dirY * Acceleration * deltaTime;
    }

    // Apply friction
    VelX *= std::pow(Friction, deltaTime);
    VelY *= std::pow(Friction, deltaTime);

    // Clamp velocity to max speed
    float speed{std::sqrt(
      VelX * VelX + VelY * VelY)};
    if (speed > MaxSpeed) {
      float scale{MaxSpeed / speed};
      VelX *= scale;
      VelY *= scale;
    }

    // Update position
    PosX += VelX * deltaTime;
    PosY += VelY * deltaTime;
  }

  void Render(SDL_Renderer* renderer) {
    // Draw cursor at physics-controlled position
    SDL_SetRenderDrawColor(
      renderer, 255, 255, 255, 255);
    SDL_Rect cursorRect{
      static_cast<int>(PosX - 8),
      static_cast<int>(PosY - 8),
      16, 16
    };
    SDL_RenderFillRect(renderer, &cursorRect);
  }

 private:
  float PosX{400.0f};  // Start at screen center
  float PosY{300.0f};
  float VelX{0.0f};
  float VelY{0.0f};
  float MaxSpeed;
  float Acceleration;
  float Friction;
};

Using the Physics Cursor

Here's how to integrate it into your game loop:

int main() {
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window* window{SDL_CreateWindow(
    "Physics Cursor",
    SDL_WINDOWPOS_CENTERED,
    SDL_WINDOWPOS_CENTERED,
    800, 600, SDL_WINDOW_SHOWN
  )};

  SDL_Renderer* renderer{SDL_CreateRenderer(
    window, -1, SDL_RENDERER_ACCELERATED)};

  // Hide system cursor
  SDL_ShowCursor(SDL_DISABLE);

  PhysicsCursor cursor{500.0f, 2000.0f, 3.0f};

  Uint32 lastTime{SDL_GetTicks()};
  bool running{true};

  while (running) {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT) {
        running = false;
      }
    }

    // Calculate delta time
    Uint32 currentTime{SDL_GetTicks()};
    float deltaTime{
      (currentTime - lastTime) / 1000.0f};
    lastTime = currentTime;

    // Update and render
    cursor.Update(deltaTime);

    SDL_SetRenderDrawColor(
      renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    cursor.Render(renderer);

    SDL_RenderPresent(renderer);
  }

  SDL_DestroyRenderer(renderer);
  SDL_DestroyWindow(window);
  SDL_Quit();
  return 0;
}

The cursor's behavior can be tuned by adjusting the MaxSpeed, Acceleration, and Friction parameters.

Lower friction values create more "slippery" movement, while higher values make the cursor more responsive. Higher acceleration values make the cursor catch up to the real mouse position more quickly.

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

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:

  • 79 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 © 2025 - All Rights Reserved