diff --git a/src/game.zig b/src/game.zig index 069f355..5e02801 100644 --- a/src/game.zig +++ b/src/game.zig @@ -56,7 +56,10 @@ const Kinetic = struct { const Player = struct { kinetic: Kinetic = .{}, money: u32 = 0, + health: u32 = 0, + max_health: u32 = 0, last_shot_at: ?Nanoseconds = null, + invincible_until: ?Nanoseconds = null, pub fn getRect(self: Player) Rect { return getCenteredRect(self.kinetic.pos, 16); @@ -102,6 +105,7 @@ const Pickup = struct { kind: Kind, }; +const invincibility_duration_s = 0.5; const pickup_spawn_duration_s = Range.init(1, 5); const wave_infos = [_]Wave.Info{ .{ @@ -145,7 +149,9 @@ pub fn init(gpa: Allocator, seed: u64, assets: *Assets) !Game { .player = .{ .kinetic = .{ .pos = .init(50, 50), - } + }, + .health = 3, + .max_health = 3 }, .rng = rng }; @@ -379,6 +385,22 @@ pub fn tick(self: *Game, frame: *Engine.Frame) !void { enemy.kinetic.update(dt, .{}); const enemy_rect = getCenteredRect(enemy.kinetic.pos, enemy.size); + + if (enemy_rect.hasOverlap(self.player.getRect())) { + var is_invincible = false; + if (self.player.invincible_until) |invincible_until| { + is_invincible = frame.time_ns < invincible_until; + } + + if (self.player.health > 0 and !is_invincible) { + self.player.health -= 1; + + var invincible_until = frame.time_ns; + invincible_until += @as(Nanoseconds, @intFromFloat(invincibility_duration_s * std.time.ns_per_s)); + self.player.invincible_until = invincible_until; + } + } + frame.drawRectangle(.{ .rect = enemy_rect, .color = rgb(20, 200, 20) @@ -394,7 +416,11 @@ pub fn tick(self: *Game, frame: *Engine.Frame) !void { const pickup_rect = Rect.initCentered(pickup.pos.x, pickup.pos.y, 10, 10); if (pickup_rect.hasOverlap(self.player.getRect())) { - self.player.money += 1; + switch (pickup.kind) { + .money => { + self.player.money += 1; + } + } destroy = true; } @@ -442,6 +468,7 @@ pub fn tick(self: *Game, frame: *Engine.Frame) !void { }); frame.drawTextFormat(.init(10, 30), text_opts, "{d}", .{ self.player.money }); + frame.drawTextFormat(.init(10, 50), text_opts, "{d}/{d}", .{ self.player.health, self.player.max_health }); } pub fn debug(self: *Game) !void { @@ -461,6 +488,7 @@ pub fn debug(self: *Game) !void { const time_left_til_pickup = self.next_pickup_spawn_at - self.wave_timer; imgui.textFmt("Waves: {}\n", .{self.waves.items.len}); + imgui.textFmt("Bullets: {}\n", .{self.bullets.items.len}); imgui.textFmt("Enemies: {}\n", .{self.enemies.items.len}); imgui.textFmt("Time until next pickup: {d:.2}s\n", .{@as(f32, @floatFromInt(time_left_til_pickup)) / std.time.ns_per_s}); }