From 8b91192b9b9eaaf54074384556bb9be3192bcf70 Mon Sep 17 00:00:00 2001 From: Balamurugan R Date: Thu, 9 Oct 2025 12:23:52 +0530 Subject: [PATCH] feat(shapes): Add shapes_mouse_trail.c example and screenshot --- examples/shapes/shapes_mouse_trail.c | 106 +++++++++++++++++++++++++ examples/shapes/shapes_mouse_trail.png | Bin 0 -> 5525 bytes 2 files changed, 106 insertions(+) create mode 100644 examples/shapes/shapes_mouse_trail.c create mode 100644 examples/shapes/shapes_mouse_trail.png diff --git a/examples/shapes/shapes_mouse_trail.c b/examples/shapes/shapes_mouse_trail.c new file mode 100644 index 000000000..b1cb706f2 --- /dev/null +++ b/examples/shapes/shapes_mouse_trail.c @@ -0,0 +1,106 @@ +#include "raylib.h" +#include "raymath.h" + +/******************************************************************************************* +* +* raylib [shapes] example - Draw a mouse trail (position history) +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* Example originally created with raylib 5.6 +* +* Example contributed by [Balamurugan R] (@[Bala050814]]) and reviewed by [Ray] (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2024 [Balamurugan R] (@[Bala050814]) +* +********************************************************************************************/ + +// Define the maximum number of positions to store in the trail +#define MAX_TRAIL_LENGTH 30 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - Draw a mouse trail"); + + // Array to store the history of mouse positions (our fixed-size queue) + Vector2 trailPositions[MAX_TRAIL_LENGTH] = { 0 }; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + Vector2 mousePosition = GetMousePosition(); + + // 1. Shift all existing positions backward by one slot in the array + // The last element (the oldest position) is dropped. + for (int i = MAX_TRAIL_LENGTH - 1; i > 0; i--) + { + trailPositions[i] = trailPositions[i - 1]; + } + + // 2. Store the new, current mouse position at the start of the array (Index 0) + trailPositions[0] = mousePosition; + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + // Use BLACK for a darker background to make the colored trail pop + ClearBackground(BLACK); + + // 3. Draw the trail by looping through the history array + for (int i = 0; i < MAX_TRAIL_LENGTH; i++) + { + // Ensure we skip drawing if the array hasn't been fully filled on startup + if (trailPositions[i].x != 0.0f || trailPositions[i].y != 0.0f) + { + // Calculate relative trail strength (ratio is near 1.0 for new, near 0.0 for old) + float ratio = (float)(MAX_TRAIL_LENGTH - i) / MAX_TRAIL_LENGTH; + + // Fade effect: oldest positions are more transparent + // Fade (color, alpha) - alpha is 0.5 to 1.0 based on ratio + Color trailColor = Fade(SKYBLUE, ratio * 0.5f + 0.5f); + + // Size effect: oldest positions are smaller + float trailRadius = 15.0f * ratio; + + DrawCircleV(trailPositions[i], trailRadius, trailColor); + } + } + + // Draw a distinct white circle for the current mouse position (Index 0) + DrawCircleV(mousePosition, 15.0f, WHITE); + + DrawText("Move the mouse to see the trail effect!", + 10, screenHeight - 30, 20, LIGHTGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + + // No resources loaded, nothing to unload. + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_mouse_trail.png b/examples/shapes/shapes_mouse_trail.png new file mode 100644 index 0000000000000000000000000000000000000000..aa64efcdf420f0fa303aec119ce48dd5e9f20759 GIT binary patch literal 5525 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