add health

This commit is contained in:
Rokas Puzonas 2026-01-31 14:32:39 +02:00
parent dc8d8e881a
commit 9d62e0eb2f

View File

@ -56,7 +56,10 @@ const Kinetic = struct {
const Player = struct { const Player = struct {
kinetic: Kinetic = .{}, kinetic: Kinetic = .{},
money: u32 = 0, money: u32 = 0,
health: u32 = 0,
max_health: u32 = 0,
last_shot_at: ?Nanoseconds = null, last_shot_at: ?Nanoseconds = null,
invincible_until: ?Nanoseconds = null,
pub fn getRect(self: Player) Rect { pub fn getRect(self: Player) Rect {
return getCenteredRect(self.kinetic.pos, 16); return getCenteredRect(self.kinetic.pos, 16);
@ -102,6 +105,7 @@ const Pickup = struct {
kind: Kind, kind: Kind,
}; };
const invincibility_duration_s = 0.5;
const pickup_spawn_duration_s = Range.init(1, 5); const pickup_spawn_duration_s = Range.init(1, 5);
const wave_infos = [_]Wave.Info{ const wave_infos = [_]Wave.Info{
.{ .{
@ -145,7 +149,9 @@ pub fn init(gpa: Allocator, seed: u64, assets: *Assets) !Game {
.player = .{ .player = .{
.kinetic = .{ .kinetic = .{
.pos = .init(50, 50), .pos = .init(50, 50),
} },
.health = 3,
.max_health = 3
}, },
.rng = rng .rng = rng
}; };
@ -379,6 +385,22 @@ pub fn tick(self: *Game, frame: *Engine.Frame) !void {
enemy.kinetic.update(dt, .{}); enemy.kinetic.update(dt, .{});
const enemy_rect = getCenteredRect(enemy.kinetic.pos, enemy.size); 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(.{ frame.drawRectangle(.{
.rect = enemy_rect, .rect = enemy_rect,
.color = rgb(20, 200, 20) .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); const pickup_rect = Rect.initCentered(pickup.pos.x, pickup.pos.y, 10, 10);
if (pickup_rect.hasOverlap(self.player.getRect())) { if (pickup_rect.hasOverlap(self.player.getRect())) {
switch (pickup.kind) {
.money => {
self.player.money += 1; self.player.money += 1;
}
}
destroy = true; 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, 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 { 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; const time_left_til_pickup = self.next_pickup_spawn_at - self.wave_timer;
imgui.textFmt("Waves: {}\n", .{self.waves.items.len}); 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("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}); imgui.textFmt("Time until next pickup: {d:.2}s\n", .{@as(f32, @floatFromInt(time_left_til_pickup)) / std.time.ns_per_s});
} }