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 5c726b8e20efec56b4900f87c8489a753ef0966d
parent d4a98d928be48c21ce048e7af94d33d7b6f126ec
Author: brookjeynes <me@brookjeynes.dev>
Date:   Thu, 13 Aug 2026 13:48:35 +1000

feat: health values for enemies

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

Diffstat:
Msrc/constants.zig | 27+++++++++++++++++++++------
Msrc/enemy_types/blorb.zig | 15+++++++++++++--
Msrc/enemy_types/grunt.zig | 10++++++++--
Msrc/entity.zig | 7+++++++
Msrc/player.zig | 9++++++++-
Msrc/state.zig | 38++++++++++++++++++++++----------------
6 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/src/constants.zig b/src/constants.zig @@ -1,11 +1,26 @@ -pub const max_bullets: u8 = 255; -pub const max_enemies: u8 = 255; +// general +pub const fps: u8 = 60; + +// screen pub const screen_width: u16 = 800; pub const screen_height: u16 = 1000; pub const screen_title: [*]const u8 = "1.44mb game jam"; -pub const fps: u8 = 60; -pub const blorb_spawn_time: f32 = 5.0; -pub const grunt_spawn_time: f32 = 0.7; +// bullets +pub const max_bullets: u8 = 255; +pub const max_enemies: u8 = 255; + +// enemies +// -- blorb +pub const blorb_health: u8 = 150; +pub const blorb_bullet_damage: f32 = 80; +pub const blorb_spawn_interval: f32 = 5.0; +pub const blorb_spawn_after: f32 = 60; + +// -- grunt +pub const grunt_health: u8 = 50; +pub const grunt_bullet_damage: f32 = 30; +pub const grunt_spawn_interval: f32 = 0.7; -pub const spawn_blorb_after: f32 = 60; +// player +pub const player_bullet_damage: f32 = 50; diff --git a/src/enemy_types/blorb.zig b/src/enemy_types/blorb.zig @@ -3,8 +3,8 @@ const std = @import("std"); const raylib = @import("raylib"); const bullet = @import("../bullet.zig"); +const constants = @import("../constants.zig"); -pub const bullet_damage: f32 = 80.0; pub const size: raylib.Vector2 = .{ .x = 60, .y = 60 }; pub const Blorb = @This(); @@ -14,6 +14,7 @@ bullet_speed: f32 = 50.0, direction: raylib.Vector2 = .{}, position: raylib.Vector2 = .{}, shoot_offset: u2 = 0, +health: f32 = constants.blorb_health, bullet_pool: bullet.Pool, @@ -41,7 +42,12 @@ pub fn shoot(self: *Blorb) void { 2 => .{ .x = 0, .y = self.bullet_speed }, else => .{ .x = -self.bullet_speed, .y = 0 }, }; - self.bullet_pool.spawn(spawn_position, bullet_velocity, raylib.PURPLE, bullet_damage); + self.bullet_pool.spawn( + spawn_position, + bullet_velocity, + raylib.PURPLE, + constants.blorb_bullet_damage, + ); } self.shoot_offset +%= 1; @@ -55,6 +61,11 @@ pub fn setRandomDirection(self: *Blorb) void { }; } +pub fn handleDamage(self: *Blorb, damage: f32) bool { + self.health -= damage; + return self.health <= 0; +} + pub fn handleMovement(self: *Blorb) void { const delta: f32 = raylib.GetFrameTime(); diff --git a/src/enemy_types/grunt.zig b/src/enemy_types/grunt.zig @@ -2,8 +2,8 @@ const raylib = @import("raylib"); const raymath = @import("raymath"); const bullet = @import("../bullet.zig"); +const constants = @import("../constants.zig"); -pub const bullet_damage: f32 = 50.0; pub const size: raylib.Vector2 = .{ .x = 40, .y = 40 }; pub const Grunt = @This(); @@ -12,6 +12,7 @@ movement_speed: f32 = 40.0, bullet_speed: f32 = 100.0, direction: raylib.Vector2 = .{}, position: raylib.Vector2 = .{}, +health: f32 = constants.grunt_health, bullet_pool: bullet.Pool, @@ -30,7 +31,7 @@ pub fn shoot(self: *Grunt) void { .y = self.direction.y * self.bullet_speed, }, raylib.RED, - bullet_damage, + constants.grunt_bullet_damage, ); } @@ -48,6 +49,11 @@ pub fn handleMovement(self: *Grunt, target: raylib.Vector2) void { self.position.y = @max(0, @min(max_y, self.position.y)); } +pub fn handleDamage(self: *Grunt, damage: f32) bool { + self.health -= damage; + return self.health <= 0; +} + pub fn render(self: *Grunt) void { raylib.DrawRectangleV( self.position, diff --git a/src/entity.zig b/src/entity.zig @@ -16,6 +16,13 @@ pub const Entity = union(EntityType) { } } + pub fn handleDamage(entity: *Entity, damage: f32) bool { + return switch (entity.*) { + .grunt => |*grunt| grunt.handleDamage(damage), + .blorb => |*blorb| blorb.handleDamage(damage), + }; + } + pub fn move(entity: *Entity, target_position: raylib.Vector2) void { switch (entity.*) { .grunt => |*grunt| grunt.handleMovement(target_position), diff --git a/src/player.zig b/src/player.zig @@ -2,6 +2,7 @@ const raylib = @import("raylib"); const raymath = @import("raymath"); const bullet = @import("./bullet.zig"); +const constants = @import("./constants.zig"); const Timer = @import("./timer.zig"); pub const Player = @This(); @@ -20,6 +21,7 @@ position: raylib.Vector2 = .{}, velocity: raylib.Vector2 = .{}, max_health: f32 = starting_max_health, health: f32 = starting_max_health, + health_regen_timer: Timer = .{ .duration = 5.0, }, @@ -108,6 +110,11 @@ pub fn shoot(self: *Player) void { .x = dir.x * self.bullet_speed, .y = dir.y * self.bullet_speed, }; - self.bullet_pool.spawn(center, bullet_vel, raylib.BLUE, 1); + self.bullet_pool.spawn( + center, + bullet_vel, + raylib.BLUE, + constants.player_bullet_damage, + ); } } diff --git a/src/state.zig b/src/state.zig @@ -28,8 +28,8 @@ pub const GameState = struct { enemies: [constants.max_enemies]Entity, enemy_count: u8, - grunt_spawn_time: Timer = .{ .duration = constants.grunt_spawn_time }, - blorb_spawn_time: Timer = .{ .duration = constants.blorb_spawn_time }, + grunt_spawn_time: Timer = .{ .duration = constants.grunt_spawn_interval }, + blorb_spawn_time: Timer = .{ .duration = constants.blorb_spawn_interval }, orphaned_bullet_pool: Bullet.Pool, @@ -89,8 +89,8 @@ pub const GameState = struct { self.orphaned_bullet_pool.count = 0; - self.grunt_spawn_time = .{ .duration = constants.grunt_spawn_time }; - self.blorb_spawn_time = .{ .duration = constants.blorb_spawn_time }; + self.grunt_spawn_time = .{ .duration = constants.grunt_spawn_interval }; + self.blorb_spawn_time = .{ .duration = constants.blorb_spawn_interval }; self.upgrades.apply(&self.player); self.player.health = self.player.max_health; @@ -109,8 +109,8 @@ pub const GameState = struct { const delta = raylib.GetFrameTime(); self.time += delta; - self.grunt_spawn_time.duration = @max(0.15, constants.grunt_spawn_time / difficulty); - self.blorb_spawn_time.duration = @max(0.15, constants.blorb_spawn_time / difficulty); + self.grunt_spawn_time.duration = @max(0.15, constants.grunt_spawn_interval / difficulty); + self.blorb_spawn_time.duration = @max(0.15, constants.blorb_spawn_interval / difficulty); self.player.tick(); if (self.player.health <= 0) { @@ -133,12 +133,12 @@ pub const GameState = struct { self.spawn_enemy(grunt); } - if (self.time > constants.spawn_blorb_after) { + if (self.time > constants.blorb_spawn_after) { if (self.blorb_spawn_time.tick(delta)) { const blorb = createEnemy( .{ .x = constants.screen_width, .y = constants.screen_height }, self.player, - difficulty - constants.spawn_blorb_after, + difficulty, .blorb, Blorb.size, ); @@ -196,10 +196,13 @@ pub const GameState = struct { if (is_collision) { self.player.bullet_pool.despawn(player_bullet_idx); - self.orphaned_bullet_pool.transferFrom(&grunt.bullet_pool); - self.despawn_enemy(enemy_idx); - self.enemies_killed += 1; - continue :lbl; + + if (grunt.handleDamage(constants.player_bullet_damage)) { + self.orphaned_bullet_pool.transferFrom(&grunt.bullet_pool); + self.despawn_enemy(enemy_idx); + self.enemies_killed += 1; + continue :lbl; + } } } }, @@ -246,11 +249,14 @@ pub const GameState = struct { ); if (is_collision) { - self.orphaned_bullet_pool.transferFrom(&blorb.bullet_pool); self.player.bullet_pool.despawn(player_bullet_idx); - self.despawn_enemy(enemy_idx); - self.enemies_killed += 1; - continue :lbl; + + if (blorb.handleDamage(constants.player_bullet_damage)) { + self.orphaned_bullet_pool.transferFrom(&blorb.bullet_pool); + self.despawn_enemy(enemy_idx); + self.enemies_killed += 1; + continue :lbl; + } } } },