From 1c39d47b5b517d06b997bd68f05cc20cb480f6f2 Mon Sep 17 00:00:00 2001 From: themushroompirates <59015901+themushroompirates@users.noreply.github.com> Date: Wed, 15 Oct 2025 19:34:39 +0200 Subject: [PATCH] Added simple starfield example (#5255) --- examples/Makefile | 1 + examples/Makefile.Web | 1 + examples/README.md | 3 +- examples/shapes/shapes_starfield.c | 143 +++++++++++++++++++++++++++ examples/shapes/shapes_starfield.png | Bin 0 -> 20913 bytes 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 examples/shapes/shapes_starfield.c create mode 100644 examples/shapes/shapes_starfield.png diff --git a/examples/Makefile b/examples/Makefile index 69d100fdb..523339d06 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -566,6 +566,7 @@ SHAPES = \ shapes/shapes_ring_drawing \ shapes/shapes_rounded_rectangle_drawing \ shapes/shapes_splines_drawing \ + shapes/shapes_starfield \ shapes/shapes_top_down_lights \ shapes/shapes_triangle_strip \ shapes/shapes_vector_angle diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 933ea3499..c5e9138f5 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -566,6 +566,7 @@ SHAPES = \ shapes/shapes_ring_drawing \ shapes/shapes_rounded_rectangle_drawing \ shapes/shapes_splines_drawing \ + shapes/shapes_starfield \ shapes/shapes_top_down_lights \ shapes/shapes_triangle_strip \ shapes/shapes_vector_angle diff --git a/examples/README.md b/examples/README.md index 9757cea60..16e44aa2b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -67,7 +67,7 @@ Examples using raylib[core](../src/rcore.c) platform functionality like window c | [core_input_actions](core/core_input_actions.c) | core_input_actions | ⭐⭐☆☆ | 5.5 | 5.6 | [Jett](https://github.com/JettMonstersGoBoom) | | [core_directory_files](core/core_directory_files.c) | core_directory_files | ⭐☆☆☆ | 5.5 | 5.6 | [Hugo ARNAL](https://github.com/hugoarnal) | -### category: shapes [26] +### category: shapes [27] Examples using raylib shapes drawing functionality, provided by raylib [shapes](../src/rshapes.c) module. @@ -93,6 +93,7 @@ Examples using raylib shapes drawing functionality, provided by raylib [shapes]( | [shapes_top_down_lights](shapes/shapes_top_down_lights.c) | shapes_top_down_lights | ⭐⭐⭐⭐️ | 4.2 | 4.2 | [Jeffery Myers](https://github.com/JeffM2501) | | [shapes_rectangle_advanced](shapes/shapes_rectangle_advanced.c) | shapes_rectangle_advanced | ⭐⭐⭐⭐️ | 5.5 | 5.5 | [Everton Jr.](https://github.com/evertonse) | | [shapes_splines_drawing](shapes/shapes_splines_drawing.c) | shapes_splines_drawing | ⭐⭐⭐☆ | 5.0 | 5.0 | [Ramon Santamaria](https://github.com/raysan5) | +| [shapes_starfield](shapes/shapes_starfield.c) | shapes_starfield | ⭐⭐⭐☆ | 5.5 | 5.5 | [JP Mortiboys](https://github.com/themushroompirates) | | [shapes_digital_clock](shapes/shapes_digital_clock.c) | shapes_digital_clock | ⭐⭐⭐⭐️ | 5.5 | 5.6 | [Hamza RAHAL](https://github.com/hmz-rhl) | | [shapes_double_pendulum](shapes/shapes_double_pendulum.c) | shapes_double_pendulum | ⭐⭐☆☆ | 5.5 | 5.5 | [JoeCheong](https://github.com/Joecheong2006) | | [shapes_dashed_line](shapes/shapes_dashed_line.c) | shapes_dashed_line | ⭐☆☆☆ | 5.5 | 5.5 | [Luís Almeida](https://github.com/luis605) | diff --git a/examples/shapes/shapes_starfield.c b/examples/shapes/shapes_starfield.c new file mode 100644 index 000000000..457912dec --- /dev/null +++ b/examples/shapes/shapes_starfield.c @@ -0,0 +1,143 @@ +/******************************************************************************************* +* +* raylib [shapes] example - simple starfield +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* Example originally created with raylib 5.5 +* +* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@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) 2025 JP Mortiboys (@themushroompirates) +* +********************************************************************************************/ + +#include "raylib.h" + +#include "raymath.h" // Required for: Lerp() + +#define STAR_COUNT 420 + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [shapes] example - starfield"); + + Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.69f); + + // Speed at which we fly forward + float speed = 10.0f/9.0f; + + // We're either drawing lines or circles + bool drawLines = true; + + Vector3 stars[STAR_COUNT] = { 0 }; + Vector2 starsScreenPos[STAR_COUNT] = { 0 }; + + // Setup the stars with a random position + for (int i = 0; i < STAR_COUNT; i++) { + stars[i].x = GetRandomValue(-screenWidth*.5, screenWidth*.5); + stars[i].y = GetRandomValue(-screenHeight*.5, screenHeight*.5); + stars[i].z = 1.0f; + } + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + // Change speed based on number keys + for (int i = 0; i <= 9; i++) { + if (IsKeyPressed(KEY_ZERO + i)) { + speed = 2.0f * (float)i / 9.0f; + } + } + + // Toggle lines / points with space bar + if (IsKeyPressed(KEY_SPACE)) { + drawLines = !drawLines; + } + + float dt = GetFrameTime(); + for (int i = 0; i < STAR_COUNT; i++) { + // Update star's timer + stars[i].z -= dt * speed; + // Calculate the screen position + starsScreenPos[i] = (Vector2) { + screenWidth*.5f + stars[i].x / stars[i].z, + screenHeight*.5f + stars[i].y / stars[i].z, + }; + // If the star is too old, or offscreen, it dies and we make a new random one + if (stars[i].z < 0.0f + || starsScreenPos[i].x < 0 || starsScreenPos[i].y < 0.0f + || starsScreenPos[i].x > screenWidth || starsScreenPos[i].y > screenHeight) { + stars[i].x = GetRandomValue(-screenWidth*.5, screenWidth*.5); + stars[i].y = GetRandomValue(-screenHeight*.5, screenHeight*.5); + stars[i].z = 1.0f; + } + } + + + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(bgColor); + + for (int i = 0; i < STAR_COUNT; i++) { + if (drawLines) { + // Get the time a little while ago for this star, but clamp it + float t = Clamp(stars[i].z + 1.0f/32.0f, 0.0f, 1.0f); + // If it's different enough from the current time, we proceed + if (t - stars[i].z > 1e-3) { + // Calculate the screen position of the old point + Vector2 startPos = (Vector2) { + screenWidth*.5f + stars[i].x / t, + screenHeight*.5f + stars[i].y / t, + }; + // Draw a line connecting the old point to the current point + DrawLineV(startPos, starsScreenPos[i], RAYWHITE); + } + } + else { + // Make the radius grow as the star ages + float radius = Lerp(stars[i].z, 1.0f, 5.0f); + // Draw the circle + DrawCircleV(starsScreenPos[i], radius, RAYWHITE); + } + } + + DrawFPS(10, 10); + + DrawText(TextFormat("Current Speed: %.0f [Number keys to change]", 9.0f * speed / 2.0f), 10, 30, 20, RAYWHITE); + DrawText(TextFormat("Drawing %s [Space to change]", drawLines ? "Lines" : "Circles"), 10, 50, 20, RAYWHITE); + + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_starfield.png b/examples/shapes/shapes_starfield.png new file mode 100644 index 0000000000000000000000000000000000000000..6903f222b5e0e25b22be5717b79da5b66f6503d5 GIT binary patch literal 20913 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 KelF{r5}E)p$5%7} literal 0 HcmV?d00001