diff options
| author | iamcheeseman <[email protected]> | 2026-03-06 18:55:27 -0500 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-03-06 18:55:27 -0500 |
| commit | 4c0c7682433a6da363ed8d608766fe8b52b70669 (patch) | |
| tree | 988538c2e765abe93cfcc5d82885c9814ed37c2d /src/hugbug.odin | |
| parent | 3c7c93a2d844448ac9e8234418a786206a851596 (diff) | |
yayyy hugbug
Diffstat (limited to 'src/hugbug.odin')
| -rw-r--r-- | src/hugbug.odin | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/hugbug.odin b/src/hugbug.odin new file mode 100644 index 0000000..5d27c2a --- /dev/null +++ b/src/hugbug.odin @@ -0,0 +1,114 @@ +package demonchime + +import "core:math" +import "core:math/linalg" +import "core:math/rand" + +import "phys" +import "fw" + +hugbug_stats := Enemy_Stats { + max_health = 10, +} + +Hugbug :: struct { + using enemy: Enemy, + saw_player: bool, + + spawn_position: Vec2, + target_position: Vec2, + patrol_timer: f32, +} + +make_hugbug :: proc(pos: Vec2) -> (int, ^Hugbug) { + sprite: Sprite + init_sprite(&sprite, .Hugbug) + sprite.offset = { + f32(sprite.width / 2), + f32(sprite.height / 2), + } + + body := phys.make_body( + phys.Rect{{-4, -4}, {10, 10}}, + layers = {.Enemy}, + mask = {.Player, .Hard}, + ) + phys.set_position(body, pos) + + hugbug := make_enemy( + Hugbug, + &hugbug_stats, + sprite, + body + ) + + hugbug.ai = .Hugbug + hugbug.spawn_position = pos + hugbug.target_position = pos + + return hugbug.handle, hugbug +} + +update_hugbug :: proc(e: ^Enemy, dt: f32) { + hb, is_hugbug := e.variant.(^Hugbug) + if !is_hugbug { + return + } + + pos := phys.get_position(hb.body) + player_pos := phys.get_position(player.body) + + pursuing := false + speed: f32 = HUGBUG_PATROL_SPEED + + distance := linalg.length2(player_pos - pos) + if distance < HUGBUG_PURSUE_RANGE*HUGBUG_PURSUE_RANGE { + hb.target_position = player_pos + hb.patrol_timer = HUGBUG_PATROL_TIMEOUT_MAX + speed = HUGBUG_PURSUE_SPEED + pursuing = true + } else { + hb.patrol_timer -= dt + if hb.patrol_timer < 0 { + hb.patrol_timer = rand.float32_range( + HUGBUG_PATROL_TIMEOUT_MIN, + HUGBUG_PATROL_TIMEOUT_MAX, + ) + + stay_idle := coin_flip() + if stay_idle { + hb.target_position = pos + } else { + hb.target_position = hb.spawn_position + Vec2{ + rand.float32_range(-HUGBUG_PATROL_RANGE, HUGBUG_PATROL_RANGE), + rand.float32_range(-HUGBUG_PATROL_RANGE, HUGBUG_PATROL_RANGE), + } + } + } + } + + accelerate_to_point(hb.body, hb.target_position, speed, HUGBUG_ACCEL) + + contact_damage(hb.body, HUGBUG_DAMAGE) + + hb.sprite.anim_speed = 1 + + if f32(fw.get_time()) - hb.hit_timestamp < 0.1 { + set_sprite_active_tag(&hb.sprite, "hurt") + } else { + set_sprite_active_tag(&hb.sprite, "fly") + if pursuing { + hb.sprite.anim_speed = 2 + } + } + + vel := phys.get_velocity(hb.body) + hb.sprite.scale.x = -1 if vel.x < 0 else 1 + if math.abs(vel.x) < 5 { + hb.sprite.scale.x = 1 + } +} + +object_spawner_hugbug :: proc(obj: Object_Resource) { + make_hugbug(obj.pos) +} |
