From 7383de3dea3037956710f2a8184665d7b925a883 Mon Sep 17 00:00:00 2001 From: Balamurugan R Date: Wed, 15 Oct 2025 23:00:37 +0530 Subject: [PATCH] feat(shapes): Add shapes_mouse_trail.c example and screenshot (#5246) Co-authored-by: Balamurugan R --- 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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

jHT7OG)qA)1=P4Tz!HW_SPD~65`rs<% zhezaSM|v~_hzkJ+eZRR@qRai}o;u8s!w614GBdubdw)I`Zyvk<|GLi+eE+LUE`Plr ze7({+^6T~aC+@rNd&cxXjv*s?IcSvTW@p#7`7T@Uvfs$}n`0rU?lU zc>Dj==RW;)y`F#h%h%1zzJB^W`&sJGTHj}}`7eIv&boH`eg3TJxxc>O{PO?vpV}=e z>+Y(3K9@atf8FeDKY#vy_3JOwhRQeK5v1xeEwx#7kER^|TsrOj^Vd4}&tH$c{ddjl zKievQ*6llY>s@-~zdhF@_sw6wxyC+zd*W%jSF_UFdk{=4S=PpFdE=iASo{{Ff2 z8d&c2o^_w9a<9j3-K&59{B_@7v!=g){@N_|dHG!S1J5=FgT|#y+>UmN)@pf84mP&? zner)kW9g**`%C}YiBJ8%^ON@J@3Wt+-Tmk9^YCf!&Ckw0@%h%X^fc%>D2> zUfue=+tyou*|Y5@!-eUf!j0j@qK`hVlTZ5Z-DNlXc8Pue^ViENLu0RJ&j#7NYR^5W z2e$o=oHu{{>Rs!uo2`HQZ_lTypS#ZP`Fy)1c71N#K8Qr=J(t^mYWBa~wYu{D_0qcg zpVivt@gMjGarKvN!55ch{@oK77Hgj!t^dE+bnWc-+t*rO+!A+fOWp0#*`;&uFU#E< zT6?$Cb^pITpKotjJAHrN|Ufew2 zx#Ra=&@f@dfve{`e{9`;^kVz|S0B|G7!v%