Selaa lähdekoodia

Added clock of clocks example (#5263)

themushroompirates 2 kuukautta sitten
vanhempi
sitoutus
1c45776bb7

+ 227 - 0
examples/shapes/shapes_clock_of_clocks.c

@@ -0,0 +1,227 @@
+/*******************************************************************************************
+*
+*   raylib [shapes] example - clock of clocks
+*
+*   Example complexity rating: [★★☆☆] 2/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()
+#include <time.h>       // Required for: time(), localtime()
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+
+    SetConfigFlags(FLAG_MSAA_4X_HINT);
+    InitWindow(screenWidth, screenHeight, "raylib [shapes] example - clock of clocks");
+    
+    const Color bgColor = ColorLerp(DARKBLUE, BLACK, 0.75f);
+    const Color handsColor = ColorLerp(YELLOW, RAYWHITE, .25f);
+    
+    const float clockFaceSize = 24;
+    const float clockFaceSpacing = 8.0f;
+    const float sectionSpacing = 16.0f;
+    
+    const Vector2 TL = (Vector2){   0.0f,  90.0f }; // Top-left corner
+    const Vector2 TR = (Vector2){  90.0f, 180.0f }; // Top-right corner
+    const Vector2 BR = (Vector2){ 180.0f, 270.0f }; // Bottom-right corner
+    const Vector2 BL = (Vector2){   0.0f, 270.0f }; // Bottom-left corner
+    const Vector2 HH = (Vector2){   0.0f, 180.0f }; // Horizontal line
+    const Vector2 VV = (Vector2){  90.0f, 270.0f }; // Vertical line
+    const Vector2 ZZ = (Vector2){ 135.0f, 135.0f }; // Not relevant
+    
+    const Vector2 digitAngles[10][24] = {
+        /* 0 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,VV,VV,VV,/* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+        /* 1 */ { TL,HH,TR,ZZ, /* */ BL,TR,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ ZZ,VV,VV,ZZ,/* */ TL,BR,BL,TR,/* */ BL,HH,HH,BR },
+        /* 2 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,HH,BR },
+        /* 3 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+        /* 4 */ { TL,TR,TL,TR, /* */ VV,VV,VV,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
+        /* 5 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+        /* 6 */ { TL,HH,HH,TR, /* */ VV,TL,HH,BR,/* */ VV,BL,HH,TR,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+        /* 7 */ { TL,HH,HH,TR, /* */ BL,HH,TR,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,VV,VV,/* */ ZZ,ZZ,BL,BR },
+        /* 8 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,HH,BR },
+        /* 9 */ { TL,HH,HH,TR, /* */ VV,TL,TR,VV,/* */ VV,BL,BR,VV,/* */ BL,HH,TR,VV,/* */ TL,HH,BR,VV,/* */ BL,HH,HH,BR },
+    };
+    // Time for the hands to move to the new position (in seconds); this must be <1s
+    const float handsMoveDuration = .5f;
+    
+    // We store the previous seconds value so we can see if the time has changed
+    int prevSeconds = -1;
+    
+    // This represents the real position where the hands are right now
+    Vector2 currentAngles[6][24] = { 0 };
+    
+    // This is the position where the hands were moving from
+    Vector2 srcAngles[6][24] = { 0 };
+    // This is the position where the hands are moving to
+    Vector2 dstAngles[6][24] = { 0 };
+    
+    // Current animation timer
+    float handsMoveTimer = 0.0f;
+    
+    // 12 or 24 hour mode
+    int hourMode = 24;
+
+    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
+        //----------------------------------------------------------------------------------
+        
+        // Get the current time
+        time_t rawtime;
+        struct tm *timeinfo;
+
+        time(&rawtime);
+        timeinfo = localtime(&rawtime);
+        
+        if (timeinfo->tm_sec != prevSeconds) {
+            // The time has changed, so we need to move the hands to the new positions
+            prevSeconds = timeinfo->tm_sec;
+        
+            // Format the current time so we can access the individual digits
+            const char *clockDigits = TextFormat("%02d%02d%02d", timeinfo->tm_hour % hourMode, timeinfo->tm_min, timeinfo->tm_sec);
+        
+            // Fetch where we want all the hands to be
+            for (int digit = 0; digit < 6; digit++) {
+                for (int cell = 0; cell < 24; cell++) {
+                    srcAngles[digit][cell] = currentAngles[digit][cell];
+                    dstAngles[digit][cell] = digitAngles[ clockDigits[digit] - '0' ][cell];
+                    
+                    // Quick exception for 12h mode
+                    if (digit == 0 && hourMode == 12 && clockDigits[0] == '0') {
+                        dstAngles[digit][cell] = ZZ;
+                    }
+                    
+                    if (srcAngles[digit][cell].x > dstAngles[digit][cell].x) {
+                        srcAngles[digit][cell].x -= 360.0f;
+                    }
+                    if (srcAngles[digit][cell].y > dstAngles[digit][cell].y) {
+                        srcAngles[digit][cell].y -= 360.0f;
+                    }
+                }
+            }
+            
+            // Reset the timer
+            handsMoveTimer = -GetFrameTime();
+        }
+        
+        // Now let's animate all the hands if we need to
+        if (handsMoveTimer < handsMoveDuration) {
+            // Increase the timer but don't go above the maximum
+            handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration);
+            
+            // Calculate the % completion of the animation
+            float t = handsMoveTimer / handsMoveDuration;
+            
+            // A little cheeky smoothstep
+            t = t * t * (3.0f - 2.0f * t);
+            
+            for (int digit = 0; digit < 6; digit++) {
+                for (int cell = 0; cell < 24; cell++) {
+                    currentAngles[digit][cell].x = Lerp(srcAngles[digit][cell].x, dstAngles[digit][cell].x, t);
+                    currentAngles[digit][cell].y = Lerp(srcAngles[digit][cell].y, dstAngles[digit][cell].y, t);
+                }
+            }
+            
+            if (handsMoveTimer == handsMoveDuration) {
+                // The animation has now finished
+            }
+        }
+        
+        // Handle input
+        
+        // Toggle between 12 and 24 hour mode with space
+        if (IsKeyPressed(KEY_SPACE)) {
+            hourMode = 36 - hourMode;
+        }
+        
+        
+        
+        //----------------------------------------------------------------------------------
+
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(bgColor);
+            
+            DrawText(TextFormat("%d-h mode, space to change", hourMode), 10, 30, 20, RAYWHITE);
+            
+            float xOffset = 4.0f;
+            
+            for (int digit = 0; digit < 6; digit++) {
+            
+                for (int row = 0; row < 6; row++) {
+                    for (int col = 0; col < 4; col++) {
+                        Vector2 centre = (Vector2){
+                            xOffset + col*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f,
+                            100 + row*(clockFaceSize+clockFaceSpacing) + clockFaceSize * .5f
+                        };
+                        DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, DARKGRAY);
+                        
+                        // Big hand
+                        DrawRectanglePro(
+                            (Rectangle){centre.x, centre.y, clockFaceSize*.5f+4.0f, 4.0f},
+                            (Vector2){ 2.0f, 2.0f },
+                            currentAngles[digit][row*4+col].x,
+                            handsColor
+                        );
+                        
+                        // Little hand
+                        DrawRectanglePro(
+                            (Rectangle){centre.x, centre.y, clockFaceSize*.5f+2.0f, 4.0f},
+                            (Vector2){ 2.0f, 2.0f },
+                            currentAngles[digit][row*4+col].y,
+                            handsColor
+                        );
+                    }
+                }
+                
+                xOffset += (clockFaceSize+clockFaceSpacing) * 4;
+                if (digit % 2 == 1) {
+                    
+                    DrawRing((Vector2){xOffset + 4.0f, 160.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
+                    DrawRing((Vector2){xOffset + 4.0f, 225.0f}, 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
+                    
+                    xOffset += sectionSpacing;
+                    
+                }
+            }
+            
+            DrawFPS(10, 10);
+            
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+
+    CloseWindow();          // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}

BIN
examples/shapes/shapes_clock_of_clocks.png