/******************************************************************************************* * * raylib [shapes] example - starfield * * Example complexity rating: [★☆☆☆] 1/4 * * Example originally created with raylib 5.5, last time updated with raylib 5.6-dev * * 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; }