Add Komodo enemy class and enhance enemy spawning logic
- Introduce Komodo class with high health and attack mechanics. - Modify Enemy class to accept type parameter during initialization. - Update EnemyAI to set speed based on enemy type. - Implement random spawning of enemies in boss rooms. - Adjust health bar calculations to use max health.
This commit is contained in:
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
+7
-8
@@ -1,28 +1,27 @@
|
|||||||
class EnemyAI
|
class EnemyAI
|
||||||
AGGRO_RADIUS = 2000
|
|
||||||
BASE_SPEED = 130.0
|
|
||||||
CORNER_OFFSET = 35 # how far from tile center to place corner waypoint
|
CORNER_OFFSET = 35 # how far from tile center to place corner waypoint
|
||||||
ATTACK_COOLDOWN = 0.2 # seconds
|
ATTACK_COOLDOWN = 0.2 # seconds
|
||||||
|
|
||||||
def initialize(enemy, type)
|
def initialize(enemy, type)
|
||||||
@enemy = enemy
|
@enemy = enemy
|
||||||
@type = type
|
@type = type
|
||||||
|
@base_speed = case type
|
||||||
|
when :komodo then 60
|
||||||
|
when :force then 130
|
||||||
|
end
|
||||||
@tile_path = [] # raw tile coords from solver
|
@tile_path = [] # raw tile coords from solver
|
||||||
@waypoints = [] # actual world positions to move through
|
@waypoints = [] # actual world positions to move through
|
||||||
@last_player_tile = nil
|
@last_player_tile = nil
|
||||||
@avoiding_obstacle = false
|
@avoiding_obstacle = false
|
||||||
@speed = BASE_SPEED
|
@speed = @base_speed
|
||||||
@time_since_attack = ATTACK_COOLDOWN
|
@time_since_attack = ATTACK_COOLDOWN
|
||||||
end
|
end
|
||||||
|
|
||||||
def update(player_x, player_y, dt, force = false)
|
def update(player_x, player_y, dt, force = false)
|
||||||
distance = Math.sqrt((player_x - @enemy.x)**2 + (player_y - @enemy.y)**2)
|
|
||||||
return unless distance < AGGRO_RADIUS
|
|
||||||
|
|
||||||
if @enemy.lorentz && distance < 230
|
if @enemy.lorentz && distance < 230
|
||||||
@speed = BASE_SPEED * 0.3
|
@speed = @base_speed * 0.3
|
||||||
else
|
else
|
||||||
@speed = BASE_SPEED
|
@speed = @base_speed
|
||||||
end
|
end
|
||||||
|
|
||||||
player_tile = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
player_tile = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round)
|
||||||
|
|||||||
+7
-4
@@ -20,12 +20,14 @@ class Enemy
|
|||||||
[@i_w, @i_h, @s]
|
[@i_w, @i_h, @s]
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(x, y, health = 100)
|
def initialize(x, y, type, health = 100)
|
||||||
@x = x
|
@x = x
|
||||||
@y = y
|
@y = y
|
||||||
@w = 25
|
@w = 25
|
||||||
@h = 30
|
@h = 30
|
||||||
|
@max_health = health
|
||||||
@health = health
|
@health = health
|
||||||
|
@type = type
|
||||||
@stun = 0
|
@stun = 0
|
||||||
@last_lock = :none
|
@last_lock = :none
|
||||||
@lorentz = $bus.get(:lorentz_field?) || false
|
@lorentz = $bus.get(:lorentz_field?) || false
|
||||||
@@ -34,7 +36,7 @@ class Enemy
|
|||||||
@lorentz = lorentz
|
@lorentz = lorentz
|
||||||
end
|
end
|
||||||
|
|
||||||
@ai = EnemyAI.new(self, :chase)
|
@ai = EnemyAI.new(self, @type)
|
||||||
|
|
||||||
$bus.on(:collides?) do |rect|
|
$bus.on(:collides?) do |rect|
|
||||||
next collides?(rect) ? :enemy : nil
|
next collides?(rect) ? :enemy : nil
|
||||||
@@ -78,7 +80,7 @@ class Enemy
|
|||||||
end
|
end
|
||||||
|
|
||||||
player_pos = $bus.get(:player_position)
|
player_pos = $bus.get(:player_position)
|
||||||
closest_event_horizon = $bus.get(:closest_event_horizon, @x, @y, 200)
|
closest_event_horizon = $bus.get(:closest_event_horizon, @x, @y, 2000)
|
||||||
if closest_event_horizon
|
if closest_event_horizon
|
||||||
@ai.update(*closest_event_horizon, dt, @last_lock != :event_horizon)
|
@ai.update(*closest_event_horizon, dt, @last_lock != :event_horizon)
|
||||||
@last_lock = :event_horizon
|
@last_lock = :event_horizon
|
||||||
@@ -108,7 +110,8 @@ class Enemy
|
|||||||
|
|
||||||
# Health bar
|
# Health bar
|
||||||
|
|
||||||
health_width = (@w * @health / 100.0)
|
health_width = (@w * @health / @max_health)
|
||||||
|
Gosu::draw_rect(screen_x - @w / 2, screen_y - @h / 2 - 10, @w, 5, Gosu::Color.new(0xFF555555), Float::INFINITY)
|
||||||
Gosu.draw_rect(screen_x - @w / 2, screen_y - @h / 2 - 10, health_width, 5, Gosu::Color.new(0xFF00FF00), Float::INFINITY)
|
Gosu.draw_rect(screen_x - @w / 2, screen_y - @h / 2 - 10, health_width, 5, Gosu::Color.new(0xFF00FF00), Float::INFINITY)
|
||||||
|
|
||||||
if $bus.get(:settings, :debug)
|
if $bus.get(:settings, :debug)
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ class Force < Enemy
|
|||||||
load 'assets/images/force.png', 21, 32, 1.7
|
load 'assets/images/force.png', 21, 32, 1.7
|
||||||
|
|
||||||
def initialize(x, y)
|
def initialize(x, y)
|
||||||
super(x, y, 100)
|
super(x, y, :force, 100)
|
||||||
|
|
||||||
$bus.on(:attack) do |attack_x, attack_y, range, damage|
|
$bus.on(:attack) do |attack_x, attack_y, range, damage|
|
||||||
# Whoa, did'nt know ruby had hypot functions built in!
|
# Whoa, did'nt know ruby had hypot functions built in!
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
require_relative 'force'
|
require_relative 'force'
|
||||||
|
require_relative 'komodo'
|
||||||
|
|
||||||
class EnemyHandler
|
class EnemyHandler
|
||||||
def initialize
|
def initialize
|
||||||
@@ -16,10 +17,11 @@ class EnemyHandler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def spawn!
|
def spawn!
|
||||||
# For now, just spawn a single enemy at a fixed location
|
boss_rooms = $bus.get(:boss_rooms) || []
|
||||||
start_room_coords = $bus.get(:start_room_coords)
|
if @enemies.count < 4 && rand < (1.0 / (60 * 10))
|
||||||
if @enemies.empty? && start_room_coords
|
boss_room = boss_rooms.sample
|
||||||
@enemies << Force.new((start_room_coords[0] * 2 + 1 + 4) * 60 + 30, (start_room_coords[1] * 2 + 1 + 4) * 60 + 30)
|
type = rand < 0.1 ? Komodo : Force
|
||||||
|
@enemies << (type).new((boss_room[0] * 2 + 4) * 60 + 30, (boss_room[1] * 2 + 4) * 60 + 30)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
require_relative 'base'
|
||||||
|
|
||||||
|
class Komodo < Enemy
|
||||||
|
load 'assets/images/komodo.png', 31, 48, 1.7
|
||||||
|
|
||||||
|
def initialize(x, y)
|
||||||
|
super(x, y, :komodo, 1000)
|
||||||
|
|
||||||
|
$bus.on(:attack) do |attack_x, attack_y, range, damage|
|
||||||
|
if Math.hypot(@x - attack_x, @y - attack_y) <= range
|
||||||
|
take_damage(damage)
|
||||||
|
next true
|
||||||
|
end
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -2,8 +2,8 @@ So,
|
|||||||
|
|
||||||
#landmines and event horizon should be easy - done
|
#landmines and event horizon should be easy - done
|
||||||
|
|
||||||
make enemy spawn in the boss rooms with randomness + enemy count
|
#make enemy spawn in the boss rooms with randomness + enemy count - done
|
||||||
make the lizard kind of enemy with very high health + dps but slow
|
#make the lizard kind of enemy with very high health + dps but slow - done
|
||||||
|
|
||||||
make blade work as planned
|
make blade work as planned
|
||||||
make bow just normal
|
make bow just normal
|
||||||
|
|||||||
+4
-3
@@ -26,12 +26,13 @@ class MazeData
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
$bus.on(:boss_rooms) do
|
||||||
|
next @boss_rooms
|
||||||
|
end
|
||||||
|
|
||||||
return unless $bus.get(:settings, :debug)
|
return unless $bus.get(:settings, :debug)
|
||||||
|
|
||||||
print_debug
|
print_debug
|
||||||
$bus.on(:boss_room_coords) do
|
|
||||||
next @boss_rooms.first ? [@boss_rooms.first[0] * 2 + 1, @boss_rooms.first[1] * 2 + 1] : nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def solve(x1, y1, x2, y2)
|
def solve(x1, y1, x2, y2)
|
||||||
|
|||||||
Reference in New Issue
Block a user