A cursor trail effect can be implemented by keeping track of recent cursor positions and rendering them with decreasing opacity. Here's a complete implementation:
First, we'll create a structure to store trail positions and their age:
#include <SDL.h>
#include <deque>
#include <cmath>
struct TrailPoint {
int x, y;
Uint32 timestamp;
};
class CursorTrail {
public:
static constexpr size_t MAX_POINTS{20};
static constexpr Uint32 TRAIL_DURATION{500};// milliseconds
void Update(int mouseX, int mouseY) {
auto now{SDL_GetTicks()};
// Add new point
TrailPoints.push_front({mouseX, mouseY, now});
// Remove old points
while (!TrailPoints.empty() &&
now - TrailPoints.back().timestamp > TRAIL_DURATION) {
TrailPoints.pop_back();
}
// Limit total points
while (TrailPoints.size() > MAX_POINTS) {
TrailPoints.pop_back();
}
}
void Render(SDL_Renderer* renderer) {
auto now{SDL_GetTicks()};
// Render trail points
for (size_t i{1}; i < TrailPoints.size(); ++i) {
const auto& current{TrailPoints[i - 1]};
const auto& prev{TrailPoints[i]};
// Calculate alpha based on age
float age{static_cast<float>(
now - current.timestamp) / TRAIL_DURATION
};
Uint8 alpha{static_cast<Uint8>(
255 * (1.0f - age)
)};
SDL_SetRenderDrawBlendMode(
renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(
renderer, 255, 255, 255, alpha);
SDL_RenderDrawLine(
renderer,
current.x, current.y,
prev.x, prev.y
);
}
}
private:
std::deque<TrailPoint> TrailPoints;
};
Here's how to use the trail in your game loop:
#include <SDL.h>
#include <iostream>
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window{SDL_CreateWindow(
"Cursor Trail",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
800, 600,
SDL_WINDOW_SHOWN
)};
SDL_Renderer* renderer{SDL_CreateRenderer(
window, -1, SDL_RENDERER_ACCELERATED
)};
CursorTrail trail;
bool running{true};
while (running) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
}
// Update trail
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
trail.Update(mouseX, mouseY);
// Render
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
trail.Render(renderer);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
This implementation creates a smooth trail effect that fades out over time. The trail length and duration are configurable through the constants in the CursorTrail
 class.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to control cursor visibility, switch between default system cursors, and create custom cursors