raylib-zig/examples/audio/module_playing.zig
2025-03-12 21:21:15 +01:00

142 lines
5.0 KiB
Zig

const rl = @import("raylib");
const MAX_CIRCLES = 64;
const CircleWave = struct {
position: rl.Vector2,
radius: f32,
alpha: f32,
speed: f32,
color: rl.Color,
};
const screenWidth = 800;
const screenHeight = 450;
const colors = [14]rl.Color{ .orange, .red, .gold, .lime, .blue, .violet, .brown, .light_gray, .pink, .yellow, .green, .sky_blue, .purple, .beige };
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
pub fn main() !void {
// Initialization
//--------------------------------------------------------------------------------------
rl.setConfigFlags(rl.ConfigFlags{ .msaa_4x_hint = true }); // NOTE: Try to enable MSAA 4X
rl.initWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)");
defer rl.closeWindow(); // Close window and OpenGL context
rl.initAudioDevice(); // Initialize audio device
defer rl.closeAudioDevice(); // Close audio device (music streaming is automatically stopped)
// Creates some circles for visual effect
var circles: [MAX_CIRCLES]CircleWave = undefined;
for (&circles) |*circle| {
initCircle(circle);
}
var music: rl.Music = try rl.loadMusicStream("resources/audio/mini1111.xm");
defer rl.unloadMusicStream(music); // Unload music stream buffers from RAM
music.looping = false;
var pitch: f32 = 1;
rl.playMusicStream(music);
var timePlayed: f32 = 0;
var pause: bool = false;
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
// Update
//----------------------------------------------------------------------------------
rl.updateMusicStream(music); // Update music buffer with new stream data
// Restart music playing (stop and play)
if (rl.isKeyPressed(.space)) {
rl.stopMusicStream(music);
rl.playMusicStream(music);
pause = false;
}
// Pause/Resume music playing
if (rl.isKeyPressed(.p)) {
pause = !pause;
if (pause) {
rl.pauseMusicStream(music);
} else {
rl.resumeMusicStream(music);
}
}
if (rl.isKeyDown(.down)) {
pitch -= 0.01;
} else if (rl.isKeyDown(.up)) {
pitch += 0.01;
}
rl.setMusicPitch(music, pitch);
// Get timePlayed scaled to bar dimensions
timePlayed = rl.getMusicTimePlayed(music) / rl.getMusicTimeLength(music) * (screenWidth - 40);
if (!pause) {
for (&circles) |*circle| {
circle.alpha += circle.speed;
circle.radius += circle.speed * 10.0;
if (circle.alpha > 1.0) circle.speed *= -1;
if (circle.alpha <= 0.0) {
initCircle(circle);
}
}
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
rl.beginDrawing();
rl.clearBackground(.white);
for (circles) |circle| {
rl.drawCircleV(circle.position, circle.radius, .fade(circle.color, circle.alpha));
}
// Draw time bar
rl.drawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, .light_gray);
rl.drawRectangle(20, screenHeight - 20 - 12, @intFromFloat(timePlayed), 12, .maroon);
rl.drawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, .gray);
// Draw help instructions
rl.drawRectangle(20, 20, 425, 145, .white);
rl.drawRectangleLines(20, 20, 425, 145, .gray);
rl.drawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, .black);
rl.drawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, .black);
rl.drawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, .black);
rl.drawText(rl.textFormat("SPEED: %f", .{pitch}), 40, 130, 20, .maroon);
rl.endDrawing();
//----------------------------------------------------------------------------------
}
}
fn initCircle(circle: *CircleWave) void {
circle.alpha = 0.0;
circle.radius = getRandomValuef32(10, 40);
circle.position.x = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenWidth - circle.radius));
circle.position.y = getRandomValuef32(@intFromFloat(circle.radius), @intFromFloat(screenHeight - circle.radius));
circle.speed = getRandomValuef32(1, 100) / 2000.0;
circle.color = colors[@intCast(rl.getRandomValue(0, 13))];
}
fn getRandomValuef32(min: i32, max: i32) f32 {
return @as(f32, @floatFromInt(rl.getRandomValue(min, max)));
}