Mouse State

Cursor Trail Effect

How do I implement a cursor trail effect?

Abstract art representing computer programming

A cursor trail effect can be created by storing recent mouse positions and drawing them with decreasing opacity. Here's how to implement it:

#include <SDL.h>
#include <cmath>
#include <iostream>
#include <vector>
#include "Window.h"

class CursorTrail {
 public:
  void Tick() {
    // Get current mouse position
    int MouseX, MouseY;
    SDL_GetMouseState(&MouseX, &MouseY);

    // Add new position to trail
    TrailPoints.push_back({MouseX, MouseY});

    // Remove old positions if trail is too long
    while (TrailPoints.size() > MaxTrailLength) {
      TrailPoints.erase(TrailPoints.begin());
    }

    // Print current trail for demonstration
    PrintTrail();
  }

 private:
  struct Point {
    int X, Y;
  };

  static const size_t MaxTrailLength = 10;
  std::vector<Point> TrailPoints;

  void PrintTrail() {
    std::cout << "Trail: ";
    for (size_t i = 0; i < TrailPoints.size(); ++i) {
      float Opacity = static_cast<float>(i)
        / TrailPoints.size();
      std::cout << "(" << TrailPoints[i].X
        << "," << TrailPoints[i].Y << "|"
        << std::round(Opacity * 100) << "%) ";
    }
    std::cout << "\n";
  }
};

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  Window GameWindow;
  CursorTrail Trail;
  SDL_Event E;

  while (true) {
    while (SDL_PollEvent(&E)) {
      // Handle other events...
    }

    Trail.Tick();
    GameWindow.Update();
  }

  SDL_Quit();
  return 0;
}
Trail: (100,150|10%) (102,152|20%) (105,155|30%) (108,158|40%) (112,162|50%)
Trail: (100,150|10%) (102,152|20%) (105,155|30%) (108,158|40%) (112,162|50%) (115,165|60%)

Enhanced Version

Here's a more advanced version with smoothing and custom trail behavior:

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

class AdvancedCursorTrail {
 public:
  void Tick() {
    // Get current time and position
    Uint32 CurrentTime = SDL_GetTicks();
    int MouseX, MouseY;
    SDL_GetMouseState(&MouseX, &MouseY);

    // Only add new point if moved enough
    if (TrailPoints.empty() ||
      DistanceToLastPoint(MouseX, MouseY)
        > MinDistance) {
      TrailPoint NewPoint{
        static_cast<float>(MouseX),
        static_cast<float>(MouseY),
        CurrentTime
      };

      TrailPoints.push_back(NewPoint);
    }

    // Remove expired points
    while (!TrailPoints.empty() &&
      CurrentTime - TrailPoints.front().Time
        > TrailDuration
    ) {
      TrailPoints.erase(TrailPoints.begin());
    }

    // Smooth existing points
    SmoothTrail();
  }

 private:
  struct TrailPoint {
    float X, Y;
    Uint32 Time;
  };

  std::vector<TrailPoint> TrailPoints;
  // Trail Duration in Milliseconds
  static const Uint32 TrailDuration = 500;
  static const float MinDistance = 5.0f;

  float DistanceToLastPoint(int X, int Y) {
    if (TrailPoints.empty()) {
      return MinDistance + 1;
    }

    auto& Last = TrailPoints.back();
    float DX = X - Last.X;
    float DY = Y - Last.Y;
    return std::sqrt(DX * DX + DY * DY);
  }

  void SmoothTrail() {
    for (
      size_t i = 1;
      i < TrailPoints.size() - 1;
      ++i
    ) {
      TrailPoints[i].X = (
        TrailPoints[i - 1].X +
        TrailPoints[i].X * 2 +
        TrailPoints[i + 1].X
      ) / 4;

      TrailPoints[i].Y = (
        TrailPoints[i - 1].Y +
        TrailPoints[i].Y * 2 +
        TrailPoints[i + 1].Y
      ) / 4;
    }
  }
};

This enhanced version includes:

  • Time-based trail duration instead of fixed length
  • Minimum distance between points to prevent clustering
  • Smooth interpolation between points
  • Floating-point positions for smoother curves
  • Automatic cleanup of old trail points

You can customize the trail effect by adjusting:

  • TrailDuration: How long points remain visible
  • MinDistance: Minimum distance between points
  • Smoothing algorithm parameters
  • Trail point fade out behavior
  • Trail thickness and color gradients

This system can be used for:

  • Cursor effects in menus
  • Spell casting trails in games
  • Motion visualization
  • Drawing guides in art programs

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:

  • 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