1.44mb-gamejam

submission for the 1.44mb game jam - https://2pgarcade.com/contest-144mb.html
git clone git://brookjeynes.dev/bjeynes/1.44mb-gamejam.git
Log | Files | Refs

commit a7a39a80e476dac702281c6e4adb5e36d208ed0c
parent 7e3fb669f48770a55723c80e0302b661320cf331
Author: brookjeynes <me@brookjeynes.dev>
Date:   Wed, 29 Jul 2026 16:26:58 +1000

refactor: remove allocators

Adding the allocator added roughly 100kb to the executable...

Signed-off-by: brookjeynes <me@brookjeynes.dev>

Diffstat:
Msrc/bullet.zig | 95++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Msrc/main.zig | 65++++++++++++-----------------------------------------------------
Asrc/player.zig | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/timer.zig | 22++++++++++------------
4 files changed, 135 insertions(+), 110 deletions(-)

diff --git a/src/bullet.zig b/src/bullet.zig @@ -1,6 +1,5 @@ -const std = @import("std"); const raylib = @import("raylib"); -const Timer = @import("./timer.zig").Timer; +const Timer = @import("./timer.zig"); const speed: f16 = 300.0; const radius: f16 = 10.0; @@ -12,50 +11,56 @@ pub const Bullet = struct { color: raylib.Color, }; -pub const Pool = struct { - bullets: std.ArrayList(Bullet) = .empty, - fire_timer: Timer = .{ .duration = spawn_cooldown }, - - pub fn tick(self: *Pool) bool { - return self.fire_timer.tick(raylib.GetFrameTime()); - } - - pub fn spawn( - self: *Pool, - allocator: std.mem.Allocator, - position: raylib.Vector2, - direction: raylib.Vector2, - ) !void { - try self.bullets.append(allocator, .{ - .position = position, - .direction = direction, - .color = raylib.MAROON, - }); - } - - pub fn render(self: *Pool, screen_size: raylib.Vector2) void { - const delta = raylib.GetFrameTime(); - - var i: usize = 0; - while (i < self.bullets.items.len) { - var bullet = &self.bullets.items[i]; - bullet.position.x += bullet.direction.x * speed * delta; - bullet.position.y += bullet.direction.y * speed * delta; - - if (bullet.position.x < -radius * 2 or - bullet.position.x > screen_size.x + radius * 2 or - bullet.position.y < -radius * 2 or - bullet.position.y > screen_size.y + radius * 2) - { - _ = self.bullets.orderedRemove(i); - } else { +pub fn Pool(comptime upper: usize) type { + return struct { + const Self = @This(); + + bullets: [upper]Bullet = undefined, + count: usize = 0, + fire_timer: Timer = .{ .duration = spawn_cooldown }, + + pub fn tick(self: *Self) bool { + return self.fire_timer.tick(raylib.GetFrameTime()); + } + + pub fn spawn( + self: *Self, + position: raylib.Vector2, + direction: raylib.Vector2, + ) void { + self.bullets[self.count] = .{ + .position = position, + .direction = direction, + .color = raylib.MAROON, + }; + self.count += 1; + } + + pub fn render(self: *Self, screen_size: raylib.Vector2) void { + const delta = raylib.GetFrameTime(); + + var i: usize = 0; + while (i < self.count) { + var bullet = &self.bullets[i]; + bullet.position.x += bullet.direction.x * speed * delta; + bullet.position.y += bullet.direction.y * speed * delta; + + if (bullet.position.x < -radius * 2 or + bullet.position.x > screen_size.x + radius * 2 or + bullet.position.y < -radius * 2 or + bullet.position.y > screen_size.y + radius * 2) + { + for (i..self.count) |j| { + self.bullets[j] = self.bullets[j + 1]; + } + + self.count -= 1; + continue; + } + raylib.DrawCircleV(bullet.position, radius, bullet.color); i += 1; } } - } - - pub fn deinit(self: *Pool, allocator: std.mem.Allocator) void { - self.bullets.deinit(allocator); - } -}; + }; +} diff --git a/src/main.zig b/src/main.zig @@ -1,77 +1,36 @@ const std = @import("std"); -const Bullet = @import("./bullet.zig"); + const raylib = @import("raylib"); -const raymath = @import("raymath"); -pub fn main() !void { - var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); - defer arena.deinit(); - const allocator = arena.allocator(); +const bullet = @import("./bullet.zig"); +const Player = @import("./player.zig"); +const Timer = @import("./timer.zig"); +pub fn main() !void { const screen_width: f16 = 800.0; const screen_height: f16 = 1000.0; const fps: u8 = 60; - const player_movement_speed: f16 = 140.0; - const player_size: raylib.Vector2 = .{ .x = 50, .y = 50 }; - - var bullet_pool: Bullet.Pool = .{}; - defer bullet_pool.deinit(allocator); raylib.InitWindow(screen_width, screen_height, "1.44mb game jam"); defer raylib.CloseWindow(); raylib.SetTargetFPS(fps); - var player_position: raylib.Vector2 = .{ - .x = screen_width / 2, - .y = screen_height / 2, + var player: Player = .{ + .position = .{ + .x = screen_width / 2, + .y = screen_height / 2, + }, }; while (!raylib.WindowShouldClose()) { - const delta: f32 = raylib.GetFrameTime(); - - var player_direction: raylib.Vector2 = .{}; - if (raylib.IsKeyDown(raylib.KEY_RIGHT)) player_direction.x += 1; - if (raylib.IsKeyDown(raylib.KEY_LEFT)) player_direction.x -= 1; - if (raylib.IsKeyDown(raylib.KEY_UP)) player_direction.y -= 1; - if (raylib.IsKeyDown(raylib.KEY_DOWN)) player_direction.y += 1; - - player_direction = @bitCast(raymath.Vector2Normalize(@bitCast(player_direction))); - player_position.x += player_direction.x * player_movement_speed * delta; - player_position.y += player_direction.y * player_movement_speed * delta; - - const max_x: f32 = screen_width - player_size.x; - const max_y: f32 = screen_height - player_size.y; - player_position.x = @max(0, @min(max_x, player_position.x)); - player_position.y = @max(0, @min(max_y, player_position.y)); - - if (player_direction.x != 0 or player_direction.y != 0) { - if (bullet_pool.tick()) { - try bullet_pool.spawn( - allocator, - .{ - .x = player_position.x + (player_size.x / 2), - .y = player_position.y + (player_size.y / 2), - }, - player_direction, - ); - } - } + player.handleMovement(); raylib.BeginDrawing(); defer raylib.EndDrawing(); raylib.ClearBackground(raylib.RAYWHITE); - raylib.DrawRectangleV( - player_position, - player_size, - raylib.MAROON, - ); - - bullet_pool.render(.{ - .x = screen_width, - .y = screen_height, - }); + player.render(); } } diff --git a/src/player.zig b/src/player.zig @@ -0,0 +1,63 @@ +const raylib = @import("raylib"); +const raymath = @import("raymath"); + +const bullet = @import("./bullet.zig"); + +const max_bullets = 2000; + +pub const Player = @This(); + +movement_speed: f16 = 140.0, +size: raylib.Vector2 = .{ .x = 50, .y = 50 }, +direction: raylib.Vector2 = .{}, +position: raylib.Vector2 = .{}, + +bullet_pool: bullet.Pool(max_bullets) = .{}, + +pub fn handleMovement(self: *Player) void { + const delta: f32 = raylib.GetFrameTime(); + + self.direction = .{}; + if (raylib.IsKeyDown(raylib.KEY_RIGHT)) self.direction.x += 1; + if (raylib.IsKeyDown(raylib.KEY_LEFT)) self.direction.x -= 1; + if (raylib.IsKeyDown(raylib.KEY_UP)) self.direction.y -= 1; + if (raylib.IsKeyDown(raylib.KEY_DOWN)) self.direction.y += 1; + + self.direction = @bitCast(raymath.Vector2Normalize(@bitCast(self.direction))); + self.position.x += self.direction.x * self.movement_speed * delta; + self.position.y += self.direction.y * self.movement_speed * delta; + + const max_x: f32 = @as(f32, @floatFromInt(raylib.GetScreenWidth())) - self.size.x; + const max_y: f32 = @as(f32, @floatFromInt(raylib.GetScreenHeight())) - self.size.y; + self.position.x = @max(0, @min(max_x, self.position.x)); + self.position.y = @max(0, @min(max_y, self.position.y)); + + if (self.direction.x != 0 or self.direction.y != 0) { + self.shoot(); + } +} + +pub fn shoot(self: *Player) void { + if (self.bullet_pool.tick()) { + self.bullet_pool.spawn( + .{ + .x = self.position.x + (self.size.x / 2), + .y = self.position.y + (self.size.y / 2), + }, + self.direction, + ); + } +} + +pub fn render(self: *Player) void { + raylib.DrawRectangleV( + self.position, + self.size, + raylib.MAROON, + ); + + self.bullet_pool.render(.{ + .x = @floatFromInt(raylib.GetScreenWidth()), + .y = @floatFromInt(raylib.GetScreenHeight()), + }); +} diff --git a/src/timer.zig b/src/timer.zig @@ -1,15 +1,13 @@ -const std = @import("std"); +pub const Timer = @This(); -pub const Timer = struct { - duration: f32, - elapsed: f32 = 0, +duration: f32, +elapsed: f32 = 0, - pub fn tick(self: *Timer, delta: f32) bool { - self.elapsed += delta; - if (self.elapsed >= self.duration) { - self.elapsed -= self.duration; - return true; - } - return false; +pub fn tick(self: *Timer, delta: f32) bool { + self.elapsed += delta; + if (self.elapsed >= self.duration) { + self.elapsed -= self.duration; + return true; } -}; + return false; +}