commit a18fd4bbabfd2c9d47c300afd9abf1b6f1a83cb3
parent c30d1375472725bf4cf82efa5358b38288cda90d
Author: brookjeynes <me@brookjeynes.dev>
Date: Thu, 30 Jul 2026 13:40:27 +1000
feat: player damage
Signed-off-by: brookjeynes <me@brookjeynes.dev>
Diffstat:
3 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/src/enemy.zig b/src/enemy.zig
@@ -6,6 +6,7 @@ const bullet = @import("./bullet.zig");
const max_spawned_bullets = 2000;
const bullet_speed: f16 = 100.0;
const bullet_spawn_cooldown: f16 = 2.0;
+pub const bullet_damage: f16 = 50.0;
pub const Enemy = @This();
diff --git a/src/main.zig b/src/main.zig
@@ -82,7 +82,9 @@ pub fn main() !void {
.gameplay => {
const delta = raylib.GetFrameTime();
+ player.tick();
player.handleMovement();
+
for (0..enemy_count) |i| {
enemies[i].handleMovement(player.position);
}
@@ -109,6 +111,33 @@ pub fn main() !void {
while (enemy_idx < enemy_count) {
const enemy = &enemies[enemy_idx];
+ for (0..enemy.bullet_pool.count) |bullet_idx| {
+ const bullet = enemy.bullet_pool.bullets[bullet_idx];
+
+ const is_collision = raylib.CheckCollisionCircleRec(
+ .{
+ .x = bullet.position.x,
+ .y = bullet.position.y,
+ },
+ Bullet.radius,
+ .{
+ .x = player.position.x,
+ .y = player.position.y,
+ .width = player.size.x,
+ .height = player.size.y,
+ },
+ );
+
+ if (is_collision) {
+ enemy.bullet_pool.despawn(bullet_idx);
+ player.health -= Enemy.bullet_damage;
+
+ if (player.health < 0) {
+ current_screen = .title;
+ }
+ }
+ }
+
for (0..player.bullet_pool.count) |bullet_idx| {
const bullet = player.bullet_pool.bullets[bullet_idx];
@@ -145,6 +174,10 @@ pub fn main() !void {
for (0..enemy_count) |idx| {
enemies[idx].render();
}
+
+ const health_percent: f16 = @max(0, @min(1, player.health / Player.max_health));
+ const damage_percent = 1 - health_percent;
+ raylib.DrawRectangle(0, 0, screen_width, screen_height, raylib.ColorAlpha(raylib.RED, damage_percent));
},
}
}
diff --git a/src/player.zig b/src/player.zig
@@ -1,7 +1,9 @@
const raylib = @import("raylib");
const raymath = @import("raymath");
+const std = @import("std");
const bullet = @import("./bullet.zig");
+const Timer = @import("./timer.zig");
pub const Player = @This();
@@ -11,11 +13,17 @@ 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;
+pub const max_health: f16 = 255;
+const health_regen_amount: f16 = 50;
movement_speed: f16 = 140.0,
size: raylib.Vector2 = .{ .x = 50, .y = 50 },
position: raylib.Vector2 = .{},
velocity: raylib.Vector2 = .{},
+health: f16 = max_health,
+health_regen_timer: Timer = .{
+ .duration = 5.0,
+},
bullet_pool: bullet.Pool(max_spawned_bullets) = .{
.fire_timer = .{
@@ -36,6 +44,12 @@ pub fn render(self: *Player) void {
});
}
+pub fn tick(self: *Player) void {
+ if (self.health_regen_timer.tick(raylib.GetFrameTime())) {
+ self.health = @min(self.health + health_regen_amount, max_health);
+ }
+}
+
pub fn handleMovement(self: *Player) void {
const delta: f32 = @min(raylib.GetFrameTime(), max_delta);