From 3f30533f1c7894536c3cf1f0b9e365f4aef17638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Tue, 30 Sep 2025 12:35:15 -0400 Subject: [PATCH] [examples] Add `core_delta_time` (#5216) * delta example * clarification * made it more clear what delta time is * more explanation * vector2 positions, removed all warnings * removed keys, moved global to local, conventions & comments, show target fps * new png * remove more periods * another period * remove note about conventions, remove period --- examples/core/core_delta_time.c | 131 ++++++++++++++++++++++++++++++ examples/core/core_delta_time.png | Bin 0 -> 16554 bytes 2 files changed, 131 insertions(+) create mode 100644 examples/core/core_delta_time.c create mode 100644 examples/core/core_delta_time.png diff --git a/examples/core/core_delta_time.c b/examples/core/core_delta_time.c new file mode 100644 index 000000000..aeedd7fff --- /dev/null +++ b/examples/core/core_delta_time.c @@ -0,0 +1,131 @@ +/******************************************************************************************* +* +* raylib [core] example - delta time +* +* Example complexity rating: [★☆☆☆] 1/4 +* +* Example originally created with raylib 5.5 +* +* Example contributed by Robin (@RobinsAviary) 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-2025 Robin (@RobinsAviary) +* +********************************************************************************************/ + +#include "raylib.h" + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [core] example - delta time"); + + int currentFps = 60; + + // Store the position for the both of the circles + Vector2 deltaCircle = {0, screenHeight / 3.0f}; + Vector2 frameCircle = {0, screenHeight * (2.0f/3.0f)}; + + // The speed applied to both circles + const float speed = 10.0; + const float circleRadius = 32; + + SetTargetFPS(currentFps); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------- + if (IsKeyPressed(KEY_R)) // Reset both circles' positions when you press R + { + deltaCircle.x = 0; + frameCircle.x = 0; + } + + // Adjust the FPS target based on the mouse wheel + float mouseWheel = GetMouseWheelMove(); + if (mouseWheel != 0) + { + currentFps += (int)mouseWheel; + SetTargetFPS(currentFps); + } + + // GetFrameTime() returns the time it took to draw the last frame, in seconds (usually called delta time) + // Uses the delta time to make the circle look like it's moving at a "consistent" speed regardless of FPS + + // Multiply by 6.0 (an arbitrary value) in order to make the speed visually closer to the other circle (at 60 fps), for comparison + deltaCircle.x += GetFrameTime() * 6.0f * speed; + // This circle can move faster or slower visually depending on the FPS + frameCircle.x += .1f * speed; + + // If either circle is off the screen, reset it back to the start + if (deltaCircle.x > screenWidth) + { + deltaCircle.x = 0; + } + + if (frameCircle.x > screenWidth) + { + frameCircle.x = 0; + } + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw both circles to the screen + DrawCircleV(deltaCircle, circleRadius, RED); + DrawCircleV(frameCircle, circleRadius, BLUE); + + // Determine what help text to show depending on the current FPS target + const char* fpsText; + + if (currentFps <= 0) + { + if (currentFps < 0) + { + // Clamp values below 0 + currentFps = 0; + } + + // Special text for when the FPS target is set to 0 or less, which makes it unlimited + fpsText = TextFormat("fps: unlimited (%i)", GetFPS()); + } + else + { + fpsText = TextFormat("fps: %i (target: %i)", GetFPS(), currentFps); + } + + // Draw the help text + DrawText(fpsText, 10, 10, 20, DARKGRAY); + DrawText(TextFormat("frame time: %02.02f ms", GetFrameTime()), 10, 30, 20, DARKGRAY); + DrawText("use the scroll wheel to change the fps limit, r to reset", 10, 50, 20, DARKGRAY); + + // Draw the text above the circles + DrawText("x += GetFrameTime() * speed", 10, 90, 20, RED); + DrawText("x += speed", 10, 240, 20, BLUE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/core/core_delta_time.png b/examples/core/core_delta_time.png new file mode 100644 index 0000000000000000000000000000000000000000..cf8aa7c54e50ac477f8ea1011e0b61f1cedcb8ad GIT binary patch literal 16554 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