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:
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()),
- });
-}