Merge branch 'master' into master

This commit is contained in:
Victor Suarez 2025-10-15 20:36:56 +02:00 • committed by GitHub
commit 07bd2bbcb7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 19564 additions and 2921 deletions

View file

@ -68,8 +68,8 @@ int main(void)
// Draw circle to bullet texture, then draw bullet using DrawTexture()
// NOTE: This is done to improve the performance, since DrawCircle() is very slow
BeginTextureMode(bulletTexture);
DrawCircle(12, 12, bulletRadius, WHITE);
DrawCircleLines(12, 12, bulletRadius, BLACK);
DrawCircle(12, 12, (float)bulletRadius, WHITE);
DrawCircleLines(12, 12, (float)bulletRadius, BLACK);
EndTextureMode();
bool drawInPerformanceMode = true; // Switch between DrawCircle() and DrawTexture()
@ -192,8 +192,8 @@ int main(void)
if (!bullets[i].disabled)
{
DrawTexture(bulletTexture.texture,
bullets[i].position.x - bulletTexture.texture.width*0.5f,
bullets[i].position.y - bulletTexture.texture.height*0.5f,
(int)(bullets[i].position.x - bulletTexture.texture.width*0.5f),
(int)(bullets[i].position.y - bulletTexture.texture.height*0.5f),
bullets[i].color);
}
}
@ -206,8 +206,8 @@ int main(void)
// Do not draw disabled bullets (out of screen)
if (!bullets[i].disabled)
{
DrawCircleV(bullets[i].position, bulletRadius, bullets[i].color);
DrawCircleLinesV(bullets[i].position, bulletRadius, BLACK);
DrawCircleV(bullets[i].position, (float)bulletRadius, bullets[i].color);
DrawCircleLinesV(bullets[i].position, (float)bulletRadius, BLACK);
}
}
}

View file

@ -0,0 +1,227 @@
/*******************************************************************************************
*
* raylib [shapes] example - clock of clocks
*
* Example complexity rating: [★★☆☆] 2/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()
#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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -68,7 +68,7 @@ int main(void)
ClearBackground(RAYWHITE);
// Draw the dashed line with the current properties
DrawLineDashed(lineStartPosition, lineEndPosition, dashLength, blankLength, lineColors[colorIndex]);
DrawLineDashed(lineStartPosition, lineEndPosition, (int)dashLength, (int)blankLength, lineColors[colorIndex]);
// Draw UI and Instructions
DrawRectangle(5, 5, 265, 95, Fade(SKYBLUE, 0.5f));

View file

@ -15,6 +15,8 @@
*
********************************************************************************************/
#define _CRT_SECURE_NO_WARNINGS // Disable some Visual Studio warnings
#include "raylib.h"
#include <math.h> // Required for: cosf(), sinf()
@ -158,7 +160,7 @@ static void UpdateClock(Clock *clock)
clock->minute.value = timeinfo->tm_min;
clock->hour.value = timeinfo->tm_hour;
clock->hour.angle = (timeinfo->tm_hour%12)*180.0/6.0f;
clock->hour.angle = (timeinfo->tm_hour%12)*180.0f/6.0f;
clock->hour.angle += (timeinfo->tm_min%60)*30/60.0f;
clock->hour.angle -= 90;
@ -175,8 +177,8 @@ static void UpdateClock(Clock *clock)
static void DrawClockAnalog(Clock clock, Vector2 position)
{
// Draw clock base
DrawCircleV(position, clock.second.length + 40, LIGHTGRAY);
DrawCircleV(position, 12, GRAY);
DrawCircleV(position, clock.second.length + 40.0f, LIGHTGRAY);
DrawCircleV(position, 12.0f, GRAY);
// Draw clock minutes/seconds lines
for (int i = 0; i < 60; i++)
@ -192,15 +194,15 @@ static void DrawClockAnalog(Clock clock, Vector2 position)
}
// Draw hand seconds
DrawRectanglePro((Rectangle){ position.x, position.y, clock.second.length, clock.second.thickness },
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.second.length, (float)clock.second.thickness },
(Vector2){ 0.0f, clock.second.thickness/2.0f }, clock.second.angle, clock.second.color);
// Draw hand minutes
DrawRectanglePro((Rectangle){ position.x, position.y, clock.minute.length, clock.minute.thickness },
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.minute.length, (float)clock.minute.thickness },
(Vector2){ 0.0f, clock.minute.thickness/2.0f }, clock.minute.angle, clock.minute.color);
// Draw hand hours
DrawRectanglePro((Rectangle){ position.x, position.y, clock.hour.length, clock.hour.thickness },
DrawRectanglePro((Rectangle){ position.x, position.y, (float)clock.hour.length, (float)clock.hour.thickness },
(Vector2){ 0.0f, clock.hour.thickness/2.0f }, clock.hour.angle, clock.hour.color);
}
@ -212,14 +214,14 @@ static void DrawClockDigital(Clock clock, Vector2 position)
DrawDisplayValue((Vector2){ position.x, position.y }, clock.hour.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 120, position.y }, clock.hour.value%10, RED, Fade(LIGHTGRAY, 0.3f));
DrawCircle(position.x + 240, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle(position.x + 240, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle((int)position.x + 240, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle((int)position.x + 240, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 260, position.y }, clock.minute.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 380, position.y }, clock.minute.value%10, RED, Fade(LIGHTGRAY, 0.3f));
DrawCircle(position.x + 500, position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle(position.x + 500, position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle((int)position.x + 500, (int)position.y + 70, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawCircle((int)position.x + 500, (int)position.y + 150, 12, (clock.second.value%2)? RED : Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 520, position.y }, clock.second.value/10, RED, Fade(LIGHTGRAY, 0.3f));
DrawDisplayValue((Vector2){ position.x + 640, position.y }, clock.second.value%10, RED, Fade(LIGHTGRAY, 0.3f));

View file

@ -21,7 +21,7 @@
// Constant for Simulation
#define SIMULATION_STEPS 30
#define G 9.81
#define G 9.81f
//----------------------------------------------------------------------------------
// Module Functions Declaration
@ -43,9 +43,9 @@ int main(void)
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
// Simulation Paramters
float l1 = 15, m1 = 0.2, theta1 = DEG2RAD*170, w1 = 0;
float l2 = 15, m2 = 0.1, theta2 = DEG2RAD*0, w2 = 0;
float lengthScaler = 0.1;
float l1 = 15.0f, m1 = 0.2f, theta1 = DEG2RAD*170, w1 = 0;
float l2 = 15.0f, m2 = 0.1f, theta2 = DEG2RAD*0, w2 = 0;
float lengthScaler = 0.1f;
float totalM = m1 + m2;
Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
@ -57,8 +57,8 @@ int main(void)
float L2 = l2*lengthScaler;
// Draw parameters
int lineThick = 20, trailThick = 2;
float fateAlpha = 0.01;
float lineThick = 20, trailThick = 2;
float fateAlpha = 0.01f;
// Create framebuffer
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
@ -129,15 +129,15 @@ int main(void)
ClearBackground(BLACK);
// Draw trails texture
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
// Draw double pendulum
DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10*l1, lineThick },
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta1, RAYWHITE);
DrawRectanglePro((Rectangle){ screenWidth/2.0f, screenHeight/2.0f - 100, 10*l1, lineThick },
(Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta1, RAYWHITE);
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10*l2, lineThick },
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta2, RAYWHITE);
DrawRectanglePro((Rectangle){ screenWidth/2.0f + endpoint1.x, screenHeight/2.0f - 100 + endpoint1.y, 10*l2, lineThick },
(Vector2){0, lineThick*0.5f}, 90 - RAD2DEG*theta2, RAYWHITE);
EndDrawing();
//----------------------------------------------------------------------------------
@ -159,7 +159,7 @@ int main(void)
// Calculate pendulum end point
static Vector2 CalculatePendulumEndPoint(float l, float theta)
{
return (Vector2){ 10*l*sin(theta), 10*l*cos(theta) };
return (Vector2){ 10*l*sinf(theta), 10*l*cosf(theta) };
}
// Calculate double pendulum end point

View file

@ -0,0 +1,92 @@
/*******************************************************************************************
*
* raylib [shapes] example - kaleidoscope
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by Hugo ARNAL (@hugoarnal) 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 Hugo ARNAL (@hugoarnal)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - kaleidoscope");
int symmetry = 6;
float angle = 360.0f/(float)symmetry;
float thickness = 3.0f;
Vector2 prevMousePos = { 0 };
SetTargetFPS(60);
ClearBackground(BLACK);
Vector2 offset = { (float)screenWidth/2.0f, (float)screenHeight/2.0f };
Camera2D camera = { 0 };
camera.target = (Vector2){ 0 };
camera.offset = offset;
camera.rotation = 0.0f;
camera.zoom = 1.0f;
Vector2 scaleVector = { 1.0f, -1.0f };
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
Vector2 mousePos = GetMousePosition();
Vector2 lineStart = Vector2Subtract(mousePos, offset);
Vector2 lineEnd = Vector2Subtract(prevMousePos, offset);
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
BeginMode2D(camera);
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) {
for (int i = 0; i < symmetry; i++) {
lineStart = Vector2Rotate(lineStart, angle*DEG2RAD);
lineEnd = Vector2Rotate(lineEnd, angle*DEG2RAD);
DrawLineEx(lineStart, lineEnd, thickness, WHITE);
Vector2 reflectLineStart = Vector2Multiply(lineStart, scaleVector);
Vector2 reflectLineEnd = Vector2Multiply(lineEnd, scaleVector);
DrawLineEx(reflectLineStart, reflectLineEnd, thickness, WHITE);
}
}
prevMousePos = mousePos;
EndMode2D();
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -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 - 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -0,0 +1,224 @@
/*******************************************************************************************
*
* raylib [shapes] example - pie chart
*
* Example complexity rating: [★☆☆☆] 1/4
*
* Example originally created with raylib 5.5, last time updated with raylib 5.6
*
* Example contributed by Gideon Serfontein (@GideonSerf) 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 Gideon Serfontein (@GideonSerf)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#include <stdio.h>
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - pie chart");
#define MAX_SLICES 10
int sliceCount = 7;
float values[MAX_SLICES] = {300.0f, 100.0f, 450.0f, 350.0f, 600.0f, 380.0f, 750.0f}; //initial slice values
char labels[MAX_SLICES][32];
bool editingLabel[MAX_SLICES] = {false};
for (int i = 0; i < MAX_SLICES; i++)
snprintf(labels[i], 32, "Slice %i", i + 1);
bool showValues = true;
bool showPercentages = false;
int hoveredSlice = -1;
Rectangle scrollPanelBounds = {0};
Vector2 scrollContentOffset = {0};
Rectangle view = {0};
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose())
{
// Update
//----------------------------------------------------------------------------------
//UI layout parameters
const int panelWidth = 270;
const int panelMargin = 5;
// UI Panel top-left anchor
const Vector2 panelPos = {
(float)screenWidth - panelMargin - panelWidth,
(float)panelMargin
};
// UI Panel rectangle
const Rectangle panelRect = {
panelPos.x, panelPos.y,
(float)panelWidth,
(float)screenHeight - 2.0f*panelMargin
};
// Pie chart geometry
const Rectangle canvas = { 0, 0, panelPos.x, (float)screenHeight };
const Vector2 center = {canvas.width / 2.0f, canvas.height / 2.0f};
const float radius = 205.0f;
// Calculate total value for percentage calculations
float totalValue = 0.0f;
for (int i = 0; i < sliceCount; i++)
totalValue += values[i];
// Check for mouse hover over slices
hoveredSlice = -1; // Reset hovered slice
Vector2 mousePos = GetMousePosition();
if (CheckCollisionPointRec(mousePos, canvas)) // Only check if mouse is inside the canvas
{
float dx = mousePos.x - center.x;
float dy = mousePos.y - center.y;
float distance = sqrtf(dx * dx + dy * dy);
if (distance <= radius) // Inside the pie radius
{
float angle = atan2f(dy, dx) * RAD2DEG;
if (angle < 0)
angle += 360;
float currentAngle = 0.0f;
for (int i = 0; i < sliceCount; i++)
{
float sweep = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
if (angle >= currentAngle && angle < (currentAngle + sweep))
{
hoveredSlice = i;
break;
}
currentAngle += sweep;
}
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw the pie chart on the canvas
//------------------------------------------------------------------------------
float startAngle = 0.0f;
for (int i = 0; i < sliceCount; i++)
{
float sweepAngle = (totalValue > 0) ? (values[i] / totalValue) * 360.0f : 0.0f;
float midAngle = startAngle + sweepAngle / 2.0f; // Middle angle for label positioning
Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
float currentRadius = radius;
// Make the hovered slice pop out by adding 5 pixels to its radius
if (i == hoveredSlice)
currentRadius += 5.0f;
// Draw the pie slice using raylib's DrawCircleSector function
DrawCircleSector(center, currentRadius, startAngle, startAngle + sweepAngle, 120, color);
// Draw the label for the current slice
if (values[i] > 0)
{
char labelText[64];
if (showValues && showPercentages)
snprintf(labelText, 64, "%.1f (%.0f%%)", values[i], (values[i] / totalValue) * 100.0f);
else if (showValues)
snprintf(labelText, 64, "%.1f", values[i]);
else if (showPercentages)
snprintf(labelText, 64, "%.0f%%", (values[i] / totalValue) * 100.0f);
else
labelText[0] = '\0';
Vector2 textSize = MeasureTextEx(GetFontDefault(), labelText, 18, 1);
float labelRadius = radius * 0.7f;
Vector2 labelPos = {
center.x + cosf(midAngle * DEG2RAD) * labelRadius - textSize.x / 2,
center.y + sinf(midAngle * DEG2RAD) * labelRadius - textSize.y / 2};
DrawText(labelText, (int)labelPos.x, (int)labelPos.y, 18, WHITE);
}
startAngle += sweepAngle;
}
//------------------------------------------------------------------------------
// UI control panel
//------------------------------------------------------------------------------
DrawRectangleRec(panelRect, Fade(LIGHTGRAY, 0.5f));
DrawRectangleLinesEx(panelRect, 1.0f, GRAY);
int currentY = (int)panelPos.y + 12; // Start a bit lower for margin
GuiSpinner((Rectangle){ panelPos.x + 95, (float)currentY, 125, 25 }, "Slices ", &sliceCount, 1, MAX_SLICES, false);
currentY += 40;
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Values", &showValues);
currentY += 30;
GuiCheckBox((Rectangle){ panelPos.x + 20, (float)currentY, 20, 20 }, "Show Percentages", &showPercentages);
currentY += 40;
GuiLine((Rectangle){ panelPos.x + 10, (float)currentY, panelRect.width - 20, 1 }, NULL);
currentY += 20;
// Scrollable area for slice editors
scrollPanelBounds = (Rectangle){ panelPos.x+panelMargin, (float)currentY, panelRect.width-panelMargin*2, panelRect.y + panelRect.height - currentY - panelMargin };
int contentHeight = sliceCount * 35;
GuiScrollPanel(scrollPanelBounds, NULL,
(Rectangle){ 0, 0, panelRect.width - 20, (float)contentHeight },
&scrollContentOffset, &view);
const float contentX = view.x + scrollContentOffset.x; // left of content
const float contentY = view.y + scrollContentOffset.y; // top of content
BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height);
for (int i = 0; i < sliceCount; i++)
{
const int rowY = (int)(contentY + 5 + i * 35);
// Color indicator
Color color = ColorFromHSV((float)i / sliceCount * 360.0f, 0.75f, 0.9f);
DrawRectangle((int)(contentX + 15), rowY + 5, 20, 20, color);
// Label textbox
if (GuiTextBox((Rectangle){contentX + 45, (float)rowY, 75, 30}, labels[i], 32, editingLabel[i]))
editingLabel[i] = !editingLabel[i];
GuiSliderBar((Rectangle){contentX + 130, (float)rowY, 110, 30},
NULL, NULL, &values[i], 0.0f, 1000.0f);
}
EndScissorMode();
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,141 @@
/*******************************************************************************************
*
* raylib [shapes] example - recursive tree
*
* Example complexity rating: [★★★☆] 3/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example contributed by Jopestpe (@jopestpe)
*
* 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 Jopestpe (@jopestpe)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct {
Vector2 start;
Vector2 end;
float angle;
float length;
} Branch;
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - recursive tree");
Vector2 start = { (screenWidth/2.0f) - 125.0f, (float)screenHeight };
float angle = 40.0f;
float thick = 1.0f;
float treeDepth = 10.0f;
float branchDecay = 0.66f;
float length = 120.0f;
bool bezier = false;
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
//----------------------------------------------------------------------------------
float theta = angle*DEG2RAD;
int maxBranches = (int)(powf(2, floorf(treeDepth)));
Branch branches[1024] = { 0 };
int count = 0;
Vector2 initialEnd = CalculateBranchEnd(start, 0.0f, length);
branches[count++] = (Branch){start, initialEnd, 0.0f, length};
for (int i = 0; i < count; i++)
{
Branch branch = branches[i];
if (branch.length < 2) continue;
float nextLength = branch.length*branchDecay;
if (count < maxBranches && nextLength >= 2)
{
Vector2 branchStart = branch.end;
Vector2 branchEnd1 = CalculateBranchEnd(branchStart, branch.angle + theta, nextLength);
Vector2 branchEnd2 = CalculateBranchEnd(branchStart, branch.angle - theta, nextLength);
branches[count++] = (Branch){branchStart, branchEnd1, branch.angle + theta, nextLength};
branches[count++] = (Branch){branchStart, branchEnd2, branch.angle - theta, nextLength};
}
}
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for (int i = 0; i < count; i++)
{
Branch branch = branches[i];
if (branch.length >= 2)
{
if (!bezier) DrawLineEx(branch.start, branch.end, thick, RED);
else DrawLineBezier(branch.start, branch.end, thick, RED);
}
}
DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
// Draw GUI controls
//------------------------------------------------------------------------------
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Angle", TextFormat("%.0f", angle), &angle, 0, 180);
GuiSliderBar((Rectangle){ 640, 70, 120, 20 }, "Length", TextFormat("%.0f", length), &length, 12.0f, 240.0f);
GuiSliderBar((Rectangle){ 640, 100, 120, 20}, "Decay", TextFormat("%.2f", branchDecay), &branchDecay, 0.1f, 0.78f);
GuiSliderBar((Rectangle){ 640, 130, 120, 20 }, "Depth", TextFormat("%.0f", treeDepth), &treeDepth, 1.0f, 10.f);
GuiSliderBar((Rectangle){ 640, 160, 120, 20}, "Thick", TextFormat("%.0f", thick), &thick, 1, 8);
GuiCheckBox((Rectangle){ 640, 190, 20, 20 }, "Bezier", &bezier);
//------------------------------------------------------------------------------
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
static Vector2 CalculateBranchEnd(Vector2 start, float angle, float length)
{
return (Vector2){ start.x + length*sinf(angle), start.y - length*cosf(angle) };
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,276 @@
/*******************************************************************************************
*
* raylib [shapes] example - simple particles
*
* Example complexity rating: [★☆☆☆] 1/4
*
* Example originally created with raylib 5.6, last time updated with raylib 5.6
*
* Example contributed by Jordi Santonja (@JordSant)
*
* 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 Jordi Santonja (@JordSant)
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h> // Required for: calloc(), free()
#include <math.h> // Required for: cosf(), sinf()
#define MAX_PARTICLES 3000 // Max number particles
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum ParticleType {
WATER = 0,
SMOKE,
FIRE
} ParticleType;
static const char particleTypeNames[3][10] = { "WATER", "SMOKE", "FIRE" };
typedef struct Particle {
ParticleType type; // Particle type (WATER, SMOKE, FIRE)
Vector2 position; // Particle position on screen
Vector2 velocity; // Particle current speed and direction
float radius; // Particle radius
Color color; // Particle color
float lifeTime; // Particle life time
bool alive; // Particle alive: inside screen and life time
} Particle;
typedef struct CircularBuffer {
int head; // Index for the next write
int tail; // Index for the next read
Particle *buffer; // Particle buffer array
} CircularBuffer;
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type);
static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer);
static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight);
static void UpdateCircularBuffer(CircularBuffer *circularBuffer);
static void DrawParticles(CircularBuffer *circularBuffer);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - simple particles");
// Definition of particles
Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array
CircularBuffer circularBuffer = { 0, 0, particles };
// Particle emitter parameters
int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame
ParticleType currentType = WATER;
Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.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
//----------------------------------------------------------------------------------
// Emit new particles: when emissionRate is 1, emit every frame
if (emissionRate < 0)
{
if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType);
}
else
{
for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType);
}
// Update the parameters of each particle
UpdateParticles(&circularBuffer, screenWidth, screenHeight);
// Remove dead particles from the circular buffer
UpdateCircularBuffer(&circularBuffer);
// Change Particle Emission Rate (UP/DOWN arrows)
if (IsKeyPressed(KEY_UP)) emissionRate++;
if (IsKeyPressed(KEY_DOWN)) emissionRate--;
// Change Particle Type (LEFT/RIGHT arrows)
if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++;
if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--;
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition();
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Call the function with a loop to draw all particles
DrawParticles(&circularBuffer);
// Draw UI and Instructions
DrawRectangle(5, 5, 315, 75, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(5, 5, 315, 75, BLUE);
DrawText("CONTROLS:", 15, 15, 10, BLACK);
DrawText("UP/DOWN: Change Particle Emission Rate", 15, 35, 10, BLACK);
DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 10, BLACK);
if (emissionRate < 0) DrawText(TextFormat("Particles every %d frames | Type: %s", -emissionRate, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
DrawFPS(screenWidth - 80, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
RL_FREE(particles); // Free particles array data
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
static void EmitParticle(CircularBuffer *circularBuffer, Vector2 emitterPosition, ParticleType type)
{
Particle *newParticle = AddToCircularBuffer(circularBuffer);
// If buffer is full, newParticle is NULL
if (newParticle != NULL)
{
// Fill particle properties
newParticle->position = emitterPosition;
newParticle->alive = true;
newParticle->lifeTime = 0.0f;
newParticle->type = type;
float speed = (float)(rand()%10)/5.0f;
switch (type)
{
case WATER:
{
newParticle->radius = 5.0f;
newParticle->color = BLUE;
} break;
case SMOKE:
{
newParticle->radius = 7.0f;
newParticle->color = GRAY;
} break;
case FIRE:
{
newParticle->radius = 10.0f;
newParticle->color = YELLOW;
speed /= 10.0f;
} break;
default: break;
}
float direction = (float)(rand()%360);
newParticle->velocity = (Vector2){ speed*cosf(direction*DEG2RAD), speed*sinf(direction*DEG2RAD) };
}
}
static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer)
{
Particle *particle = NULL;
// Check if buffer full
if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail)
{
// Add new particle to the head position and advance head
particle = &circularBuffer->buffer[circularBuffer->head];
circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES;
}
return particle;
}
static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight)
{
for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
{
// Update particle life and positions
circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame
switch (circularBuffer->buffer[i].type)
{
case WATER:
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
circularBuffer->buffer[i].velocity.y += 0.2f; // Gravity
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
break;
case SMOKE:
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands
circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades
if (circularBuffer->buffer[i].color.a < 4) // If alpha transparent, particle dies
circularBuffer->buffer[i].alive = false;
break;
case FIRE:
// Add a little horizontal oscillation to fire particles
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x + cosf(circularBuffer->buffer[i].lifeTime*215.0f);
circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks
circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow
if (circularBuffer->buffer[i].radius <= 0.02f) // If radius too small, particle dies
circularBuffer->buffer[i].alive = false;
break;
default: break;
}
// Disable particle when out of screen
Vector2 center = circularBuffer->buffer[i].position;
float radius = circularBuffer->buffer[i].radius;
if ((center.x < -radius) || (center.x > screenWidth + radius) ||
(center.y < -radius) || (center.y > screenHeight + radius))
circularBuffer->buffer[i].alive = false;
}
}
static void UpdateCircularBuffer(CircularBuffer *circularBuffer)
{
// Update circular buffer: advance tail over dead particles
while ((circularBuffer->tail != circularBuffer->head) &&
!circularBuffer->buffer[circularBuffer->tail].alive)
{
circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES;
}
}
static void DrawParticles(CircularBuffer *circularBuffer)
{
for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
{
if (circularBuffer->buffer[i].alive)
{
DrawCircleV(circularBuffer->buffer[i].position,
circularBuffer->buffer[i].radius,
circularBuffer->buffer[i].color);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1,143 @@
/*******************************************************************************************
*
* 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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1,106 @@
/*******************************************************************************************
*
* raylib [shapes] example - triangle strip
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev
*
* Example contributed by Jopestpe (@jopestpe)
*
* 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 Jopestpe (@jopestpe)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - triangle strip");
Vector2 points[120] = { 0 };
Vector2 center = { (screenWidth/2.0f) - 125.f, screenHeight/2.0f };
float segments = 6.0f;
float insideRadius = 100.0f;
float outsideRadius = 150.0f;
bool outline = true;
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
//----------------------------------------------------------------------------------
int pointCount = (int)(segments);
float angleStep = (360.0f/pointCount)*DEG2RAD;
for (int i = 0, i2 = 0; i < pointCount; i++, i2 += 2)
{
float angle1 = i*angleStep;
points[i2] = (Vector2){ center.x + cosf(angle1)*insideRadius, center.y + sinf(angle1)*insideRadius };
float angle2 = angle1 + angleStep/2.0f;
points[i2 + 1] = (Vector2){ center.x + cosf(angle2)*outsideRadius, center.y + sinf(angle2)*outsideRadius };
}
points[pointCount*2] = points[0];
points[pointCount*2 + 1] = points[1];
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
for (int i = 0, i2 = 0; i < pointCount; i++, i2 += 2)
{
float angle1 = i*angleStep;
Color color = ColorFromHSV(angle1*RAD2DEG, 1.0f, 1.0f);
DrawTriangle(points[i2 + 2], points[i2 + 1], points[i2], color);
if (outline) DrawTriangleLines(points[i2], points[i2 + 1], points[i2 + 2], BLACK);
float angle2 = angle1 + angleStep/2.0f;
color = ColorFromHSV(angle2*RAD2DEG, 1.0f, 1.0f);
DrawTriangle(points[i2 + 3], points[i2 + 1], points[i2 + 2], color);
if (outline) DrawTriangleLines(points[i2 + 2], points[i2 + 1], points[i2 + 3], BLACK);
}
DrawLine(580, 0, 580, GetScreenHeight(), (Color){ 218, 218, 218, 255 });
DrawRectangle(580, 0, GetScreenWidth(), GetScreenHeight(), (Color){ 232, 232, 232, 255 });
// Draw GUI controls
//------------------------------------------------------------------------------
GuiSliderBar((Rectangle){ 640, 40, 120, 20}, "Segments", TextFormat("%.0f", segments), &segments, 6.0f, 60.f);
GuiCheckBox((Rectangle){ 640, 70, 20, 20 }, "Outline", &outline);
//------------------------------------------------------------------------------
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show more