REVIEWED: examples: Replace TABS and Remove trailing spaces

This commit is contained in:
Ray 2025-11-19 13:18:10 +01:00
parent bd21d74914
commit 0b9f463e64
36 changed files with 440 additions and 447 deletions

View File

@ -35,122 +35,122 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
int main(void) int main(void)
{ {
// Initialization // Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
const char *voxFileNames[] = { const char *voxFileNames[] = {
"resources/models/vox/chr_knight.vox", "resources/models/vox/chr_knight.vox",
"resources/models/vox/chr_sword.vox", "resources/models/vox/chr_sword.vox",
"resources/models/vox/monu9.vox", "resources/models/vox/monu9.vox",
"resources/models/vox/fez.vox" "resources/models/vox/fez.vox"
}; };
InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox"); InitWindow(screenWidth, screenHeight, "raylib [models] example - loading vox");
// Define the camera to look into our 3d world // Define the camera to look into our 3d world
Camera camera = { 0 }; Camera camera = { 0 };
camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y camera.fovy = 45.0f; // Camera field-of-view Y
camera.projection = CAMERA_PERSPECTIVE; // Camera projection type camera.projection = CAMERA_PERSPECTIVE; // Camera projection type
// Load MagicaVoxel files // Load MagicaVoxel files
Model models[MAX_VOX_FILES] = { 0 }; Model models[MAX_VOX_FILES] = { 0 };
for (int i = 0; i < MAX_VOX_FILES; i++) for (int i = 0; i < MAX_VOX_FILES; i++)
{ {
// Load VOX file and measure time // Load VOX file and measure time
double t0 = GetTime()*1000.0; double t0 = GetTime()*1000.0;
models[i] = LoadModel(voxFileNames[i]); models[i] = LoadModel(voxFileNames[i]);
double t1 = GetTime()*1000.0; double t1 = GetTime()*1000.0;
TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0)); TraceLog(LOG_INFO, TextFormat("[%s] Model file loaded in %.3f ms", voxFileNames[i], t1 - t0));
// Compute model translation matrix to center model on draw position (0, 0 , 0) // Compute model translation matrix to center model on draw position (0, 0 , 0)
BoundingBox bb = GetModelBoundingBox(models[i]); BoundingBox bb = GetModelBoundingBox(models[i]);
Vector3 center = { 0 }; Vector3 center = { 0 };
center.x = bb.min.x + (((bb.max.x - bb.min.x)/2)); center.x = bb.min.x + (((bb.max.x - bb.min.x)/2));
center.z = bb.min.z + (((bb.max.z - bb.min.z)/2)); center.z = bb.min.z + (((bb.max.z - bb.min.z)/2));
Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z); Matrix matTranslate = MatrixTranslate(-center.x, 0, -center.z);
models[i].transform = matTranslate; models[i].transform = matTranslate;
} }
int currentModel = 0; int currentModel = 0;
Vector3 modelpos = { 0 }; Vector3 modelpos = { 0 };
Vector3 camerarot = { 0 }; Vector3 camerarot = { 0 };
// Load voxel shader // Load voxel shader
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION), Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/voxel_lighting.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION)); TextFormat("resources/shaders/glsl%i/voxel_lighting.fs", GLSL_VERSION));
// Get some required shader locations // Get some required shader locations
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos"); shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
// NOTE: "matModel" location name is automatically assigned on shader loading, // NOTE: "matModel" location name is automatically assigned on shader loading,
// no need to get the location again if using that uniform name // no need to get the location again if using that uniform name
//shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel"); //shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
// Ambient light level (some basic lighting) // Ambient light level (some basic lighting)
int ambientLoc = GetShaderLocation(shader, "ambient"); int ambientLoc = GetShaderLocation(shader, "ambient");
SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4); SetShaderValue(shader, ambientLoc, (float[4]) { 0.1f, 0.1f, 0.1f, 1.0f }, SHADER_UNIFORM_VEC4);
// Assign out lighting shader to model // Assign out lighting shader to model
for (int i = 0; i < MAX_VOX_FILES; i++) for (int i = 0; i < MAX_VOX_FILES; i++)
{ {
for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader; for (int j = 0; j < models[i].materialCount; j++) models[i].materials[j].shader = shader;
} }
// Create lights // Create lights
Light lights[MAX_LIGHTS] = { 0 }; Light lights[MAX_LIGHTS] = { 0 };
lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader); lights[0] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, -20 }, Vector3Zero(), GRAY, shader);
lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader); lights[1] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, 20 }, Vector3Zero(), GRAY, shader);
lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader); lights[2] = CreateLight(LIGHT_POINT, (Vector3) { -20, 20, 20 }, Vector3Zero(), GRAY, shader);
lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader); lights[3] = CreateLight(LIGHT_POINT, (Vector3) { 20, -20, -20 }, Vector3Zero(), GRAY, shader);
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)) if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
{ {
const Vector2 mouseDelta = GetMouseDelta(); const Vector2 mouseDelta = GetMouseDelta();
camerarot.x = mouseDelta.x*0.05f; camerarot.x = mouseDelta.x*0.05f;
camerarot.y = mouseDelta.y*0.05f; camerarot.y = mouseDelta.y*0.05f;
} }
else else
{ {
camerarot.x = 0; camerarot.x = 0;
camerarot.y = 0; camerarot.y = 0;
} }
UpdateCameraPro(&camera, UpdateCameraPro(&camera,
(Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward (Vector3){ (IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - (IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f, // Move forward-backward
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left (IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - (IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f, // Move right-left
0.0f }, // Move up-down 0.0f }, // Move up-down
camerarot, // Camera rotation camerarot, // Camera rotation
GetMouseWheelMove()*-2.0f); // Move to target (zoom) GetMouseWheelMove()*-2.0f); // Move to target (zoom)
// Cycle between models on mouse click // Cycle between models on mouse click
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES; if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES;
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }) // Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z }; float cameraPos[3] = { camera.position.x, camera.position.y, camera.position.z };
SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3); SetShaderValue(shader, shader.locs[SHADER_LOC_VECTOR_VIEW], cameraPos, SHADER_UNIFORM_VEC3);
// Update light values (actually, only enable/disable them) // Update light values (actually, only enable/disable them)
for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]); for (int i = 0; i < MAX_LIGHTS; i++) UpdateLightValues(shader, lights[i]);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
BeginDrawing(); BeginDrawing();
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
@ -175,17 +175,17 @@ int main(void)
DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE); DrawText("- UP-DOWN-LEFT-RIGHT KEYS: MOVE CAMERA", 20, 90, 10, BLUE);
DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY); DrawText(TextFormat("Model file: %s", GetFileName(voxFileNames[currentModel])), 10, 10, 20, GRAY);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
} }
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Unload models data (GPU VRAM) // Unload models data (GPU VRAM)
for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]); for (int i = 0; i < MAX_VOX_FILES; i++) UnloadModel(models[i]);
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -16,6 +16,7 @@
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "raymath.h" #include "raymath.h"
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -23,122 +24,114 @@
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
int main(void) int main(void)
{ {
// Initialization // Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
const int screenWidth = 800; const int screenWidth = 800;
const int screenHeight = 450; const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing"); InitWindow(screenWidth, screenHeight, "raylib [shapes] example - lines drawing");
// Hint text that shows before you click the screen // Hint text that shows before you click the screen
bool startText = true; bool startText = true;
// The mouse's position on the previous frame // The mouse's position on the previous frame
Vector2 mousePositionPrevious = GetMousePosition(); Vector2 mousePositionPrevious = GetMousePosition();
// The canvas to draw lines on // The canvas to draw lines on
RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight); RenderTexture canvas = LoadRenderTexture(screenWidth, screenHeight);
// The background color of the canvas // The line's thickness
const Color backgroundColor = RAYWHITE; float lineThickness = 8.0f;
// The lines hue (in HSV, from 0-360)
float lineHue = 0.0f;
// The line's thickness // Clear the canvas to the background color
float lineThickness = 8.0f; BeginTextureMode(canvas);
// The lines hue (in HSV, from 0-360) ClearBackground(RAYWHITE);
float lineHue = 0.0f; EndTextureMode();
// Clear the canvas to the background color
BeginTextureMode(canvas);
ClearBackground(backgroundColor);
EndTextureMode();
SetTargetFPS(60); SetTargetFPS(60);
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Disable the hint text once the user clicks // Disable the hint text once the user clicks
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) startText = false; if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) && startText) startText = false;
// Clear the canvas when the user middle-clicks // Clear the canvas when the user middle-clicks
if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE)) if (IsMouseButtonPressed(MOUSE_BUTTON_MIDDLE))
{ {
BeginTextureMode(canvas); BeginTextureMode(canvas);
ClearBackground(backgroundColor); ClearBackground(RAYWHITE);
EndTextureMode(); EndTextureMode();
} }
// Store whether the left and right buttons are down // Store whether the left and right buttons are down
bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT); bool leftButtonDown = IsMouseButtonDown(MOUSE_BUTTON_LEFT);
bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT); bool rightButtonDown = IsMouseButtonDown(MOUSE_BUTTON_RIGHT);
if (leftButtonDown || rightButtonDown) if (leftButtonDown || rightButtonDown)
{ {
// The color for the line // The color for the line
Color drawColor = WHITE; Color drawColor = WHITE;
if (leftButtonDown) if (leftButtonDown)
{ {
// Increase the hue value by the distance our cursor has moved since the last frame (divided by 3) // Increase the hue value by the distance our cursor has moved since the last frame (divided by 3)
lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f; lineHue += Vector2Distance(mousePositionPrevious, GetMousePosition())/3.0f;
// While the hue is >=360, subtract it to bring it down into the range 0-360 // While the hue is >=360, subtract it to bring it down into the range 0-360
// This is more visually accurate than resetting to zero // This is more visually accurate than resetting to zero
while (lineHue >= 360.0f) lineHue -= 360.0f; while (lineHue >= 360.0f) lineHue -= 360.0f;
// Create the final color // Create the final color
drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f); drawColor = ColorFromHSV(lineHue, 1.0f, 1.0f);
} }
else if (rightButtonDown) else if (rightButtonDown) drawColor = RAYWHITE; // Use the background color as an "eraser"
{
// Use the background color as an "eraser"
drawColor = backgroundColor;
}
// Draw the line onto the canvas // Draw the line onto the canvas
BeginTextureMode(canvas); BeginTextureMode(canvas);
// Circles act as "caps", smoothing corners
DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor);
DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor);
DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor);
EndTextureMode();
}
// Circles act as "caps", smoothing corners // Update line thickness based on mousewheel
DrawCircleV(mousePositionPrevious, lineThickness/2.0f, drawColor); lineThickness += GetMouseWheelMove();
DrawCircleV(GetMousePosition(), lineThickness/2.0f, drawColor); lineThickness = Clamp(lineThickness, 1.0, 500.0f);
DrawLineEx(mousePositionPrevious, GetMousePosition(), lineThickness, drawColor);
EndTextureMode(); // Update mouse's previous position
} mousePositionPrevious = GetMousePosition();
//----------------------------------------------------------------------------------
// Update line thickness based on mousewheel // Draw
lineThickness += GetMouseWheelMove(); //----------------------------------------------------------------------------------
lineThickness = Clamp(lineThickness, 1.0, 500.0f); BeginDrawing();
// Update mouse's previous position // Draw the render texture to the screen, flipped vertically to make it appear top-side up
mousePositionPrevious = GetMousePosition(); DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE);
//----------------------------------------------------------------------------------
// Draw // Draw the preview circle
//---------------------------------------------------------------------------------- if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 });
BeginDrawing();
// Draw the render texture to the screen, flipped vertically to make it appear top-side up
DrawTextureRec(canvas.texture, (Rectangle){ 0.0f, 0.0f, (float)canvas.texture.width,(float)-canvas.texture.height }, Vector2Zero(), WHITE);
// Draw the preview circle // Draw the hint text
if (!leftButtonDown) DrawCircleLinesV(GetMousePosition(), lineThickness/2.0f, (Color){ 127, 127, 127, 127 }); if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY);
// Draw the hint text EndDrawing();
if (startText) DrawText("try clicking and dragging!", 275, 215, 20, LIGHTGRAY); //----------------------------------------------------------------------------------
EndDrawing(); }
//----------------------------------------------------------------------------------
}
// De-Initialization // De-Initialization
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Unload the canvas render texture UnloadRenderTexture(canvas); // Unload the canvas render texture
UnloadRenderTexture(canvas);
CloseWindow(); // Close window and OpenGL context CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -36,7 +36,7 @@ static const char particleTypeNames[3][10] = { "WATER", "SMOKE", "FIRE" };
typedef struct Particle { typedef struct Particle {
ParticleType type; // Particle type (WATER, SMOKE, FIRE) ParticleType type; // Particle type (WATER, SMOKE, FIRE)
Vector2 position; // Particle position on screen Vector2 position; // Particle position on screen
Vector2 velocity; // Particle current speed and direction Vector2 velocity; // Particle current speed and direction
float radius; // Particle radius float radius; // Particle radius
Color color; // Particle color Color color; // Particle color
@ -45,9 +45,9 @@ typedef struct Particle {
} Particle; } Particle;
typedef struct CircularBuffer { typedef struct CircularBuffer {
int head; // Index for the next write int head; // Index for the next write
int tail; // Index for the next read int tail; // Index for the next read
Particle *buffer; // Particle buffer array Particle *buffer; // Particle buffer array
} CircularBuffer; } CircularBuffer;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -73,12 +73,12 @@ int main(void)
// Definition of particles // Definition of particles
Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array Particle *particles = (Particle*)RL_CALLOC(MAX_PARTICLES, sizeof(Particle)); // Particle array
CircularBuffer circularBuffer = { 0, 0, particles }; CircularBuffer circularBuffer = { 0, 0, particles };
// Particle emitter parameters // Particle emitter parameters
int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame int emissionRate = -2; // Negative: on average every -X frames. Positive: particles per frame
ParticleType currentType = WATER; ParticleType currentType = WATER;
Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f }; Vector2 emitterPosition = { screenWidth/2.0f, screenHeight/2.0f };
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -88,7 +88,7 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Emit new particles: when emissionRate is 1, emit every frame // Emit new particles: when emissionRate is 1, emit every frame
if (emissionRate < 0) if (emissionRate < 0)
{ {
if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType); if (rand()%(-emissionRate) == 0) EmitParticle(&circularBuffer, emitterPosition, currentType);
@ -96,9 +96,9 @@ int main(void)
else else
{ {
for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType); for (int i = 0; i <= emissionRate; ++i) EmitParticle(&circularBuffer, emitterPosition, currentType);
} }
// Update the parameters of each particle // Update the parameters of each particle
UpdateParticles(&circularBuffer, screenWidth, screenHeight); UpdateParticles(&circularBuffer, screenWidth, screenHeight);
// Remove dead particles from the circular buffer // Remove dead particles from the circular buffer
@ -112,7 +112,7 @@ int main(void)
if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++; if (IsKeyPressed(KEY_RIGHT)) (currentType == FIRE)? (currentType = WATER) : currentType++;
if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--; if (IsKeyPressed(KEY_LEFT)) (currentType == WATER)? (currentType = FIRE) : currentType--;
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition(); if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) emitterPosition = GetMousePosition();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw
@ -121,7 +121,7 @@ int main(void)
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
// Call the function with a loop to draw all particles // Call the function with a loop to draw all particles
DrawParticles(&circularBuffer); DrawParticles(&circularBuffer);
// Draw UI and Instructions // Draw UI and Instructions
@ -133,7 +133,7 @@ int main(void)
DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 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); 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); else DrawText(TextFormat("%d Particles per frame | Type: %s", emissionRate + 1, particleTypeNames[currentType]), 15, 95, 10, DARKGRAY);
DrawFPS(screenWidth - 80, 10); DrawFPS(screenWidth - 80, 10);
@ -200,12 +200,12 @@ static Particle *AddToCircularBuffer(CircularBuffer *circularBuffer)
// Check if buffer full // Check if buffer full
if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail) if (((circularBuffer->head + 1)%MAX_PARTICLES) != circularBuffer->tail)
{ {
// Add new particle to the head position and advance head // Add new particle to the head position and advance head
particle = &circularBuffer->buffer[circularBuffer->head]; particle = &circularBuffer->buffer[circularBuffer->head];
circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES; circularBuffer->head = (circularBuffer->head + 1)%MAX_PARTICLES;
} }
return particle; return particle;
} }
static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight) static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int screenHeight)
@ -213,7 +213,7 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int
for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES) for (int i = circularBuffer->tail; i != circularBuffer->head; i = (i + 1)%MAX_PARTICLES)
{ {
// Update particle life and positions // Update particle life and positions
circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame circularBuffer->buffer[i].lifeTime += 1.0f/60.0f; // 60 FPS -> 1/60 seconds per frame
switch (circularBuffer->buffer[i].type) switch (circularBuffer->buffer[i].type)
{ {
@ -226,22 +226,22 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int
case SMOKE: case SMOKE:
{ {
circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x; circularBuffer->buffer[i].position.x += circularBuffer->buffer[i].velocity.x;
circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards circularBuffer->buffer[i].velocity.y -= 0.05f; // Upwards
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y; circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands circularBuffer->buffer[i].radius += 0.5f; // Increment radius: smoke expands
circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades circularBuffer->buffer[i].color.a -= 4; // Decrement alpha: smoke fades
// If alpha transparent, particle dies // If alpha transparent, particle dies
if (circularBuffer->buffer[i].color.a < 4) circularBuffer->buffer[i].alive = false; if (circularBuffer->buffer[i].color.a < 4) circularBuffer->buffer[i].alive = false;
} break; } break;
case FIRE: case FIRE:
{ {
// Add a little horizontal oscillation to fire particles // 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].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].velocity.y -= 0.05f; // Upwards
circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y; circularBuffer->buffer[i].position.y += circularBuffer->buffer[i].velocity.y;
circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks circularBuffer->buffer[i].radius -= 0.15f; // Decrement radius: fire shrinks
circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow circularBuffer->buffer[i].color.g -= 3; // Decrement green: fire turns reddish starting from yellow
// If radius too small, particle dies // If radius too small, particle dies
if (circularBuffer->buffer[i].radius <= 0.02f) circularBuffer->buffer[i].alive = false; if (circularBuffer->buffer[i].radius <= 0.02f) circularBuffer->buffer[i].alive = false;
@ -249,9 +249,9 @@ static void UpdateParticles(CircularBuffer *circularBuffer, int screenWidth, int
default: break; default: break;
} }
// Disable particle when out of screen // Disable particle when out of screen
Vector2 center = circularBuffer->buffer[i].position; Vector2 center = circularBuffer->buffer[i].position;
float radius = circularBuffer->buffer[i].radius; float radius = circularBuffer->buffer[i].radius;
if ((center.x < -radius) || (center.x > (screenWidth + radius)) || if ((center.x < -radius) || (center.x > (screenWidth + radius)) ||
(center.y < -radius) || (center.y > (screenHeight + radius))) (center.y < -radius) || (center.y > (screenHeight + radius)))
@ -267,7 +267,7 @@ static void UpdateCircularBuffer(CircularBuffer *circularBuffer)
while ((circularBuffer->tail != circularBuffer->head) && !circularBuffer->buffer[circularBuffer->tail].alive) while ((circularBuffer->tail != circularBuffer->head) && !circularBuffer->buffer[circularBuffer->tail].alive)
{ {
circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES; circularBuffer->tail = (circularBuffer->tail + 1)%MAX_PARTICLES;
} }
} }
static void DrawParticles(CircularBuffer *circularBuffer) static void DrawParticles(CircularBuffer *circularBuffer)