GRAVITY :: Vector2.{0, 3000}; RECT_SIZE :: 10; SPAWN_UPS :: 1.0 / 60; particle :: struct { pos : Vector2; vel : Vector2; } main :: () { InitWindow(800, 600, "Droplets"); defer CloseWindow(); SetTargetFPS(240); high_fps := true; particles: [..]particle; mouse_drag := new_ring(); defer array_free(mouse_drag.data); spawn_d := SPAWN_UPS; while !WindowShouldClose() { dt := GetFrameTime(); width := GetScreenWidth(); height := GetScreenHeight(); if IsMouseButtonPressed(.MOUSE_BUTTON_MIDDLE) { if !high_fps SetTargetFPS(240); if high_fps SetTargetFPS(60); high_fps = !high_fps; } if IsMouseButtonDown(.MOUSE_BUTTON_RIGHT) { spawn_d -= dt; if spawn_d < 0 { pos := GetMousePosition(); array_add(*particles, .{pos, .{0, 0}}); spawn_d = SPAWN_UPS; } } if IsMouseButtonReleased(.MOUSE_BUTTON_RIGHT) { spawn_d = SPAWN_UPS; } if IsMouseButtonDown(.MOUSE_BUTTON_LEFT) { del := GetMouseDelta() / dt; ring_add(*mouse_drag, del); } if IsMouseButtonReleased(.MOUSE_BUTTON_LEFT) { pos := GetMousePosition(); { max_x := cast(float) GetScreenWidth(); max_y := cast(float) GetScreenHeight(); using pos; if x > max_x x = max_x; if x < 0 x = 0; if y > max_y y = max_y; if y < 0 y = 0; } vel := ring_avg(*mouse_drag); ring_reset(*mouse_drag); array_add(*particles, .{pos, vel}); } for *p : particles { using p; if pos.y + RECT_SIZE < xx height vel += GRAVITY * dt; pos += vel * dt; if pos.x <= 0 { vel.x = -(vel.x * 0.5); pos.x = 0; } if pos.x + RECT_SIZE >= xx width { vel.x = -(vel.x * 0.5); pos.x = xx (width - RECT_SIZE); } if pos.y <= 0 { vel.y = -(vel.y * 0.5); vel.x *= 0.75; pos.y = 0; } if pos.y + RECT_SIZE > xx height { vel.y = -(vel.y * 0.5); vel.x *= 0.75; if abs(vel.y) < abs((GRAVITY * dt).y) vel = .{0, 0}; pos.y = xx (height - RECT_SIZE); } } BeginDrawing(); ClearBackground(RAYWHITE); for p : particles { DrawRectangleV(p.pos, .{RECT_SIZE, RECT_SIZE}, SKYBLUE); } EndDrawing(); } } #import "raylib"; #import "Basic";