aboutsummaryrefslogtreecommitdiff
path: root/src/hugbug.odin
diff options
context:
space:
mode:
Diffstat (limited to 'src/hugbug.odin')
-rw-r--r--src/hugbug.odin114
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)
+}