From 436659aaceb6914722d79b1ed812f2cd2be78041 Mon Sep 17 00:00:00 2001 From: Vincent Shields Date: Fri, 13 Feb 2026 01:04:57 -0800 Subject: [PATCH 1/3] ported shapes_simple_particles.c from the official raylib examples to Odin --- .../ports/shapes/shapes_simple_particles.odin | 306 ++++++++++++++++++ .../ports/shapes/shapes_simple_particles.png | Bin 0 -> 10261 bytes 2 files changed, 306 insertions(+) create mode 100644 raylib/ports/shapes/shapes_simple_particles.odin create mode 100644 raylib/ports/shapes/shapes_simple_particles.png diff --git a/raylib/ports/shapes/shapes_simple_particles.odin b/raylib/ports/shapes/shapes_simple_particles.odin new file mode 100644 index 00000000..13c6f53e --- /dev/null +++ b/raylib/ports/shapes/shapes_simple_particles.odin @@ -0,0 +1,306 @@ +/******************************************************************************************* +* +* raylib [shapes] example - simple particles +* +* Example complexity rating: [★★☆☆] 2/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) +* +********************************************************************************************/ +package raylib_examples + +import "core:math" +import "core:math/rand" +import rl "vendor:raylib" + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +SCREEN_WIDTH :: 800 +SCREEN_HEIGHT :: 450 +MAX_PARTICLES :: 3000 + +Particle_Type :: enum { + WATER, + SMOKE, + FIRE, +} + +PARTICLE_TYPE_NAMES :: [Particle_Type]cstring { + .WATER = "WATER", + .SMOKE = "SMOKE", + .FIRE = "FIRE", +} + +Particle :: struct { + type: Particle_Type, + position: rl.Vector2, + velocity: rl.Vector2, + radius: f32, + color: rl.Color, + life_time: f32, + alive: bool, +} + +Circular_Buffer :: struct { + head: int, + tail: int, + buffer: [MAX_PARTICLES]Particle, +} + + +cb: Circular_Buffer +emission_rate: int = -2 +current_type: Particle_Type = .WATER +emitter_position: rl.Vector2 +type_names := PARTICLE_TYPE_NAMES + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ + +main :: proc() { + + // Initialization + //-------------------------------------------------------------------------------------- + + rl.InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [shapes] example - simple particles (Odin)") + defer rl.CloseWindow() + + rl.SetTargetFPS(60) + + emitter_position = {f32(SCREEN_WIDTH) / 2.0, f32(SCREEN_HEIGHT) / 2.0} + + //-------------------------------------------------------------------------------------- + + // Main "game" loop + + for !rl.WindowShouldClose() { + // Update + //---------------------------------------------------------------------------------- + update() + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + draw() + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + // No resources to unload + //-------------------------------------------------------------------------------------- +} + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +update :: proc() { + + if emission_rate < 0 { + if rand.int31() % i32(-emission_rate) == 0 { + emit_particle() + } + } else { + for i := 0; i <= emission_rate; i += 1 { + emit_particle() + } + } + + + update_particles() + + // Remove dead particles from the circular buffer + update_circular_buffer() + + + if rl.IsKeyPressed(.UP) do emission_rate += 1 + if rl.IsKeyPressed(.DOWN) do emission_rate -= 1 + + + if rl.IsKeyPressed(.RIGHT) { + current_type = Particle_Type((int(current_type) + 1) % len(Particle_Type)) + } + if rl.IsKeyPressed(.LEFT) { + current_type = Particle_Type( + (int(current_type) + len(Particle_Type) - 1) % len(Particle_Type), + ) + } + + + if rl.IsMouseButtonDown(.LEFT) { + emitter_position = rl.GetMousePosition() + } +} + +draw :: proc() { + rl.BeginDrawing() + defer rl.EndDrawing() + + rl.ClearBackground(rl.RAYWHITE) + + + draw_particles() + + + rl.DrawRectangle(5, 5, 315, 75, rl.Fade(rl.SKYBLUE, 0.5)) + rl.DrawRectangleLines(5, 5, 315, 75, rl.BLUE) + + rl.DrawText("CONTROLS:", 15, 15, 10, rl.BLACK) + rl.DrawText("UP/DOWN: Change Particle Emission Rate", 15, 35, 10, rl.BLACK) + rl.DrawText("LEFT/RIGHT: Change Particle Type (Water, Smoke, Fire)", 15, 55, 10, rl.BLACK) + + if emission_rate < 0 { + rl.DrawText( + rl.TextFormat( + "Particles every %d frames | Type: %s", + -emission_rate, + type_names[current_type], + ), + 15, + 95, + 10, + rl.DARKGRAY, + ) + } else { + rl.DrawText( + rl.TextFormat( + "%d Particles per frame | Type: %s", + emission_rate + 1, + type_names[current_type], + ), + 15, + 95, + 10, + rl.DARKGRAY, + ) + } + + rl.DrawFPS(SCREEN_WIDTH - 80, 10) +} + +emit_particle :: proc() { + particle := add_to_circular_buffer() + if particle == nil do return + + + particle.position = emitter_position + particle.alive = true + particle.life_time = 0.0 + particle.type = current_type + + speed := f32(rand.int31() % 10) / 5.0 + + switch current_type { + case .WATER: + particle.radius = 5.0 + particle.color = rl.BLUE + case .SMOKE: + particle.radius = 7.0 + particle.color = rl.GRAY + case .FIRE: + particle.radius = 10.0 + particle.color = rl.YELLOW + speed /= 10.0 + } + + direction := f32(rand.int31() % 360) + rad := direction * math.RAD_PER_DEG + particle.velocity = {speed * math.cos(rad), speed * math.sin(rad)} +} + +add_to_circular_buffer :: proc() -> ^Particle { + // Check if buffer is full + next_head := (cb.head + 1) % MAX_PARTICLES + if next_head == cb.tail do return nil + + // Add new particle to the head position and advance head + particle := &cb.buffer[cb.head] + cb.head = next_head + return particle +} + +update_particles :: proc() { + i := cb.tail + for i != cb.head { + p := &cb.buffer[i] + + + p.life_time += 1.0 / 60.0 + + switch p.type { + case .WATER: + p.position.x += p.velocity.x + p.velocity.y += 0.2 + p.position.y += p.velocity.y + // Smoke expands and fades + case .SMOKE: + p.position.x += p.velocity.x + p.velocity.y -= 0.05 + p.position.y += p.velocity.y + p.radius += 0.5 + + if p.color.a > 4 { + p.color.a -= 4 + } else { + p.alive = false + } + + case .FIRE: + // Make fire look more natural by adding horizontal oscillation. + // Real flame does not rise in a straight line + p.position.x += p.velocity.x + math.cos(p.life_time * 215.0) + p.velocity.y -= 0.05 // Upwards + p.position.y += p.velocity.y + p.radius -= 0.15 // Fire shrinks + + + if p.color.g > 3 { + p.color.g -= 3 + } else { + p.alive = false + } + + if p.radius <= 0.02 { + p.alive = false + } + } + + // Disable particle when out of screen + if p.position.x < -p.radius || + p.position.x > f32(SCREEN_WIDTH) + p.radius || + p.position.y < -p.radius || + p.position.y > f32(SCREEN_HEIGHT) + p.radius { + p.alive = false + } + + i = (i + 1) % MAX_PARTICLES + } +} + +// Update circular buffer: advance tail over dead particles +update_circular_buffer :: proc() { + for cb.tail != cb.head && !cb.buffer[cb.tail].alive { + cb.tail = (cb.tail + 1) % MAX_PARTICLES + } +} + +draw_particles :: proc() { + i := cb.tail + for i != cb.head { + p := &cb.buffer[i] + if p.alive { + rl.DrawCircleV(p.position, p.radius, p.color) + } + i = (i + 1) % MAX_PARTICLES + } +} diff --git a/raylib/ports/shapes/shapes_simple_particles.png b/raylib/ports/shapes/shapes_simple_particles.png new file mode 100644 index 0000000000000000000000000000000000000000..d208e8f52b00288bdb919b7e0f520858c24bbd92 GIT binary patch literal 10261 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 Date: Fri, 13 Feb 2026 01:18:32 -0800 Subject: [PATCH 2/3] Remove all 'do' statements and change indentation to tabs. build with -vet -strict-style -vet-tabs -disallow-do -warnings-as-errors --- raylib/ports/shapes/shapes_simple_particles.odin | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/raylib/ports/shapes/shapes_simple_particles.odin b/raylib/ports/shapes/shapes_simple_particles.odin index 13c6f53e..d0389bf8 100644 --- a/raylib/ports/shapes/shapes_simple_particles.odin +++ b/raylib/ports/shapes/shapes_simple_particles.odin @@ -123,8 +123,8 @@ update :: proc() { update_circular_buffer() - if rl.IsKeyPressed(.UP) do emission_rate += 1 - if rl.IsKeyPressed(.DOWN) do emission_rate -= 1 + if rl.IsKeyPressed(.UP) { emission_rate += 1 } + if rl.IsKeyPressed(.DOWN) { emission_rate -= 1 } if rl.IsKeyPressed(.RIGHT) { @@ -190,7 +190,7 @@ draw :: proc() { emit_particle :: proc() { particle := add_to_circular_buffer() - if particle == nil do return + if particle == nil { return } particle.position = emitter_position @@ -221,7 +221,7 @@ emit_particle :: proc() { add_to_circular_buffer :: proc() -> ^Particle { // Check if buffer is full next_head := (cb.head + 1) % MAX_PARTICLES - if next_head == cb.tail do return nil + if next_head == cb.tail { return nil } // Add new particle to the head position and advance head particle := &cb.buffer[cb.head] @@ -242,7 +242,7 @@ update_particles :: proc() { p.position.x += p.velocity.x p.velocity.y += 0.2 p.position.y += p.velocity.y - // Smoke expands and fades + // Smoke expands and fades case .SMOKE: p.position.x += p.velocity.x p.velocity.y -= 0.05 From 1f1fd82cd4a1e896c8f8009719b3ad70a4e30e38 Mon Sep 17 00:00:00 2001 From: Vincent Shields Date: Fri, 13 Feb 2026 01:26:57 -0800 Subject: [PATCH 3/3] Add raylib/ports/shapes/shapes_simple_particles.odin to check.yml --- .github/workflows/check.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 73b767d2..416ffed5 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -81,6 +81,7 @@ jobs: odin check raylib/ports/shapes/shapes_rectangle_scaling.odin -file $FLAGS odin check raylib/ports/shapes/shapes_collision_area.odin -file $FLAGS odin check raylib/ports/shapes/shapes_logo_raylib.odin -file $FLAGS + odin check raylib/ports/shapes/shapes_simple_particles.odin -file $FLAGS odin check raylib/ports/text/text_codepoints_loading.odin -file $FLAGS odin check raylib/ports/textures/textures_gif_player.odin -file $FLAGS odin check raylib/ports/textures/textures_bunnymark.odin -file $FLAGS