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 dd245c6dac0f507ac20e48320c590452302498ae
parent 7c9c4d12d7d6459804593ae1170777b6b3369b94
Author: brookjeynes <me@brookjeynes.dev>
Date:   Thu, 30 Jul 2026 06:32:25 +1000

feat: use mouse to shoot

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

Diffstat:
Msrc/bullet.zig | 11+++++------
Msrc/enemy.zig | 6++++--
Msrc/main.zig | 4+++-
Msrc/player.zig | 112++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
4 files changed, 80 insertions(+), 53 deletions(-)

diff --git a/src/bullet.zig b/src/bullet.zig @@ -5,7 +5,7 @@ pub const radius: f16 = 10.0; pub const Bullet = struct { position: raylib.Vector2, - direction: raylib.Vector2, + velocity: raylib.Vector2, color: raylib.Color, }; @@ -15,7 +15,6 @@ pub fn Pool(comptime upper: usize) type { bullets: [upper]Bullet = undefined, count: usize = 0, - speed: f16, fire_timer: Timer, pub fn tick(self: *Self) bool { @@ -25,12 +24,12 @@ pub fn Pool(comptime upper: usize) type { pub fn spawn( self: *Self, position: raylib.Vector2, - direction: raylib.Vector2, + velocity: raylib.Vector2, colour: raylib.Color, ) void { self.bullets[self.count] = .{ .position = position, - .direction = direction, + .velocity = velocity, .color = colour, }; self.count += 1; @@ -50,8 +49,8 @@ pub fn Pool(comptime upper: usize) type { var i: usize = 0; while (i < self.count) { var bullet = &self.bullets[i]; - bullet.position.x += bullet.direction.x * self.speed * delta; - bullet.position.y += bullet.direction.y * self.speed * delta; + bullet.position.x += bullet.velocity.x * delta; + bullet.position.y += bullet.velocity.y * delta; if (bullet.position.x < -radius * 2 or bullet.position.x > screen_size.x + radius * 2 or diff --git a/src/enemy.zig b/src/enemy.zig @@ -15,7 +15,6 @@ direction: raylib.Vector2 = .{}, position: raylib.Vector2 = .{}, bullet_pool: bullet.Pool(max_spawned_bullets) = .{ - .speed = bullet_speed, .fire_timer = .{ .duration = bullet_spawn_cooldown, }, @@ -44,7 +43,10 @@ pub fn shoot(self: *Enemy) void { .x = self.position.x + (self.size.x / 2), .y = self.position.y + (self.size.y / 2), }, - self.direction, + .{ + .x = self.direction.x * bullet_speed, + .y = self.direction.y * bullet_speed, + }, raylib.RED, ); } diff --git a/src/main.zig b/src/main.zig @@ -82,7 +82,9 @@ pub fn main() !void { for (enemy_idx..enemy_count) |i| { enemies[i] = enemies[i + 1]; } - enemy_count -= 1; + if (enemy_count != 0) { + enemy_count -= 1; + } continue; } } diff --git a/src/player.zig b/src/player.zig @@ -3,74 +3,98 @@ const raymath = @import("raymath"); const bullet = @import("./bullet.zig"); -const max_spawned_bullets = 2000; -const bullet_speed: f16 = 300.0; -const bullet_spawn_cooldown: f16 = 0.4; - pub const Player = @This(); +const max_spawned_bullets = 2000; +const bullet_speed: f32 = 300.0; +const bullet_spawn_cooldown: f32 = 0.4; +const acceleration: f32 = 10000.0; +const friction: f32 = 10000.0; +const max_delta: f32 = 1.0 / 30.0; + movement_speed: f16 = 140.0, size: raylib.Vector2 = .{ .x = 50, .y = 50 }, -direction: raylib.Vector2 = .{}, -last_known_direction: raylib.Vector2 = .{}, position: raylib.Vector2 = .{}, +velocity: raylib.Vector2 = .{}, bullet_pool: bullet.Pool(max_spawned_bullets) = .{ - .speed = bullet_speed, .fire_timer = .{ .duration = bullet_spawn_cooldown, }, }, +pub fn render(self: *Player) void { + raylib.DrawRectangleV( + self.position, + self.size, + raylib.BLUE, + ); + + self.bullet_pool.render(.{ + .x = @floatFromInt(raylib.GetScreenWidth()), + .y = @floatFromInt(raylib.GetScreenHeight()), + }); +} + pub fn handleMovement(self: *Player) void { - const delta: f32 = raylib.GetFrameTime(); + const delta: f32 = @min(raylib.GetFrameTime(), max_delta); - var direction: raymath.Vector2 = .{}; - if (raylib.IsKeyDown(raylib.KEY_RIGHT)) direction.x += 1; - if (raylib.IsKeyDown(raylib.KEY_LEFT)) direction.x -= 1; - if (raylib.IsKeyDown(raylib.KEY_UP)) direction.y -= 1; - if (raylib.IsKeyDown(raylib.KEY_DOWN)) direction.y += 1; + var input: raymath.Vector2 = .{}; + if (raylib.IsKeyDown(raylib.KEY_D)) input.x += 1; + if (raylib.IsKeyDown(raylib.KEY_A)) input.x -= 1; + if (raylib.IsKeyDown(raylib.KEY_W)) input.y -= 1; + if (raylib.IsKeyDown(raylib.KEY_S)) input.y += 1; - self.direction = @bitCast(raymath.Vector2Normalize(direction)); - self.position.x += self.direction.x * self.movement_speed * delta; - self.position.y += self.direction.y * self.movement_speed * delta; + const is_moving = input.x != 0 or input.y != 0; + + if (is_moving) { + const target = raymath.Vector2Normalize(input); + + const desired: raymath.Vector2 = .{ + .x = target.x * self.movement_speed, + .y = target.y * self.movement_speed, + }; + const t = @min(1.0, acceleration * delta / self.movement_speed); + self.velocity.x += (desired.x - self.velocity.x) * t; + self.velocity.y += (desired.y - self.velocity.y) * t; + } else { + const speed = raymath.Vector2Length(@bitCast(self.velocity)); + if (speed > 0) { + const new_speed = @max(0, speed - friction * delta); + const norm = raymath.Vector2Normalize(@bitCast(self.velocity)); + self.velocity = .{ + .x = norm.x * new_speed, + .y = norm.y * new_speed, + }; + } + } + + self.position.x += self.velocity.x * delta; + self.position.y += self.velocity.y * 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 (direction.x != 0 or direction.y != 0) { - self.last_known_direction = @bitCast(direction); - } - - if (self.last_known_direction.x != 0 or self.last_known_direction.y != 0) { - self.shoot(); - } + 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.last_known_direction, - raylib.BLUE, - ); + const mouse_pos = raylib.GetMousePosition(); + const center: raylib.Vector2 = .{ + .x = self.position.x + (self.size.x / 2), + .y = self.position.y + (self.size.y / 2), + }; + const dir = raymath.Vector2Normalize(.{ + .x = mouse_pos.x - center.x, + .y = mouse_pos.y - center.y, + }); + const bullet_vel: raylib.Vector2 = .{ + .x = dir.x * bullet_speed, + .y = dir.y * bullet_speed, + }; + self.bullet_pool.spawn(center, bullet_vel, raylib.BLUE); } } - -pub fn render(self: *Player) void { - raylib.DrawRectangleV( - self.position, - self.size, - raylib.BLUE, - ); - - self.bullet_pool.render(.{ - .x = @floatFromInt(raylib.GetScreenWidth()), - .y = @floatFromInt(raylib.GetScreenHeight()), - }); -}