Refactor enemy system: enhance EnemyAI with attack cooldown, update Force class to handle damage, and improve EnemyHandler for enemy removal; add OccamsRazor weapon with attack mechanics.

This commit is contained in:
2026-03-30 19:39:43 +00:00
parent 60a89ed128
commit 0369d24338
9 changed files with 93 additions and 37 deletions
+17 -18
View File
@@ -2,6 +2,7 @@ class EnemyAI
AGGRO_RADIUS = 2000
BASE_SPEED = 130.0
CORNER_OFFSET = 35 # how far from tile center to place corner waypoint
ATTACK_COOLDOWN = 0.2 # seconds
def initialize(enemy, type)
@enemy = enemy
@@ -11,22 +12,14 @@ class EnemyAI
@last_player_tile = nil
@avoiding_obstacle = false
@speed = BASE_SPEED
@lorentz_effect_active = false
$bus.on(:lorentz_field) do
@lorentz_effect_active = true
end
$bus.on(:lorentz_field_end) do
@lorentz_effect_active = false
end
@time_since_attack = ATTACK_COOLDOWN
end
def update(player_x, player_y, dt)
distance = Math.sqrt((player_x - @enemy.x)**2 + (player_y - @enemy.y)**2)
return unless distance < AGGRO_RADIUS
if @lorentz_effect_active && distance < 230
if @enemy.lorentz && distance < 230
@speed = BASE_SPEED * 0.3
else
@speed = BASE_SPEED
@@ -42,7 +35,14 @@ class EnemyAI
enemy_tile[0] > start_room_tile[0] - 1 && enemy_tile[0] < start_room_tile[0] + 3 &&
enemy_tile[1] > start_room_tile[1] - 1 && enemy_tile[1] < start_room_tile[1] + 3
return if $bus.get_all(:collides?, @enemy.rect)&.include?(:character)
if $bus.get_all(:collides?, @enemy.rect)&.include?(:character)
if @time_since_attack >= ATTACK_COOLDOWN
$bus.emit(:enemy_attack, 10) # deal 10 damage
@time_since_attack = 0
end
@time_since_attack += dt
return
end
prop_in_tile = $bus.get(:prop_at, enemy_tile[0], enemy_tile[1])
@@ -150,15 +150,14 @@ class EnemyAI
end
def move_towards(target_x, target_y, dt)
angle = Gosu.angle(@enemy.x, @enemy.y, target_x, target_y)
dx = Gosu.offset_x(angle, @speed * dt)
dy = Gosu.offset_y(angle, @speed * dt)
dx_raw = target_x - @enemy.x
dy_raw = target_y - @enemy.y
angle = Math.atan2(dy_raw, dx_raw)
dx = Math.cos(angle) * @speed * dt
dy = Math.sin(angle) * @speed * dt
@enemy.x += dx
@enemy.y += dy
if $bus.get_all(:collides?, @enemy.rect)&.include?(:character)
# Attack player
end
end
end
+25 -9
View File
@@ -1,14 +1,14 @@
require_relative 'ai'
class Enemy
attr_accessor :x, :y, :w, :h
attr_accessor :x, :y, :w, :h, :lorentz
def self.load(path, w, h, s)
# Once artwork is done need to load each animation here.
# But as artwork takes time, for now just load a single image.
@sprite = Gosu::Image.new(path, retro: true)
@i_w = w
@i_h = h
@i_w = w * s
@i_h = h * s
@s = s
end
@@ -20,11 +20,17 @@ class Enemy
[@i_w, @i_h, @s]
end
def initialize(x, y)
def initialize(x, y, health = 100)
@x = x
@y = y
@w = 25
@h = 30
@health = health
@lorentz = false
$bus.on(:lorentz_field?) do |lorentz|
@lorentz = lorentz
end
@ai = EnemyAI.new(self, :chase)
@@ -33,6 +39,15 @@ class Enemy
end
end
def take_damage(amount)
@health -= amount
pp "Enemy takes #{amount} damage, health now #{@health}"
if @health <= 0
pp "Enemy dies"
$bus.emit(:enemy_died, self)
end
end
def rect
[@x - @w / 2, @y - @h / 2, @w, @h]
end
@@ -53,16 +68,17 @@ class Enemy
screen_x = @x - cam_x
screen_y = @y - cam_y
self.class.sprite.draw(
screen_x - self.class.frame_size[0],
screen_y - self.class.frame_size[1],
screen_y - self.class.frame_size[1],
screen_x - self.class.frame_size[0] / 2,
screen_y - self.class.frame_size[1] / 2,
screen_y - self.class.frame_size[1] / 2 + 10,
self.class.frame_size[2],
self.class.frame_size[2]
)
Gosu.draw_rect(screen_x - @w / 2, screen_y - @h / 2, @w, @h, Gosu::Color.new(0x40FF0000), Float::INFINITY) if $bus.get(:settings, :debug)
if $bus.get(:settings, :debug)
Gosu.draw_rect(screen_x - @w / 2, screen_y - @h / 2, @w, @h, Gosu::Color.new(0x40FF0000), Float::INFINITY)
end
@ai.draw
end
+8 -3
View File
@@ -4,8 +4,13 @@ class Force < Enemy
load 'assets/images/force.png', 21, 32, 1.7
def initialize(x, y)
super
@w = 20
@h = 20
super(x, y, 100)
$bus.on(:occams_razor_attack) do |attack_x, attack_y, range, damage|
# Whoa, did'nt know ruby had hypot functions built in!
if Math.hypot(@x - attack_x, @y - attack_y) <= range
take_damage(damage)
end
end
end
end
+5
View File
@@ -3,6 +3,11 @@ require_relative 'force'
class EnemyHandler
def initialize
@enemies = []
$bus.on(:enemy_died) do |enemy|
$bus.remove_owner(enemy)
@enemies.delete(enemy)
end
end
def update(dt)