From d0466599dfe95f6c45f54e01003099c99e862b43 Mon Sep 17 00:00:00 2001 From: Daanish Date: Thu, 2 Apr 2026 23:15:03 +0100 Subject: [PATCH] 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. --- assets/images/komodo.aseprite | Bin 0 -> 952 bytes assets/images/komodo.png | Bin 0 -> 1150 bytes game/enemy/ai.rb | 15 +++++++-------- game/enemy/base.rb | 11 +++++++---- game/enemy/force.rb | 2 +- game/enemy/handler.rb | 10 ++++++---- game/enemy/komodo.rb | 17 +++++++++++++++++ todo.md | 4 ++-- utils/maze.rb | 7 ++++--- 9 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 assets/images/komodo.aseprite create mode 100644 assets/images/komodo.png create mode 100644 game/enemy/komodo.rb diff --git a/assets/images/komodo.aseprite b/assets/images/komodo.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..c5f57e9a5525ff01bf330998ec83149c32794e67 GIT binary patch literal 952 zcmdnN%)szqDISz_Vy(P2~E*?50hvAk3ak5^zA?Y|No!8c6&=*duCQvWLQv{Q`Z_J zqnqK$*Q{dQ;QS~JDC_5SV4|pU|{&q1XBeHyoxzT zr(63m8w#|oRElTl^5EdSc%daA;DAsEiz&wvJ*5W6mbU~G@am+ zHn-k*+wtEgZXLXI!p~;r`Tsv=PMx~U_2q`8I$rs)sf$YI_X&OCEq|Q1ApHI>%kEn# zSB{l`{OMJ0^}Z*d;eJB^6b~ymf~z`w>~T^li8>BOnA{k=Us+4gfWi_N(&waFq&+x@On%1Y=xHGn!?%rrQJ8NaV;oE<^^e+Fku3qk8cXsRa?7UNX z%l696o}qbj;a_GmohOIS&(7Lre|_Ozwz`b`;~^n7uErkFMRmdeZl;7x^A%vs*s=8?*WMvhP1HpBHC8 z`oHUsufg9l$tLFZ>tu`1ox6X<*nZVp^KG5(Rh9dG&P_hQ*|6&H!~Lt|FCS_3H*AZv zt^a>Bo#+1kci;2Q3C_R1(Dd0Sm9t-O+Ssjkc765zzRTGgxn3Q)-Xd^tt$Q z-0P1wFYTP}_PeHc`r5}KZ>*{{jH*-4>~oK}Blvw{aq>^ogjqBG^i9}#Y<)_e%zXjx mKFvGAy0vQyPt@)xzhiYo?63Du(=YDZH*FGmCf_>u)@%UO$cGjH literal 0 HcmV?d00001 diff --git a/assets/images/komodo.png b/assets/images/komodo.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2621b71f9519847a27f381639ae20f33cff924 GIT binary patch literal 1150 zcmeAS@N?(olHy`uVBq!ia0y~yV322EU@+idV_;x-8M5#e0|NtNage(c!@6@aFBuqE zEIeHtLn2!DM)+n(yNmn_`_wkI*F{A|IxN#=<*glzlGe*Y4;;Lf*uRZwXRBOQf%A!@ zJDvpb>{Yw|sGI-e)fMSCmoI3NzS59vu(0WZTGIsQ(vHyMp$F}CN{VL8{X286?Axd^ z`-p3^Du3^Lzqj&p+I21^XXS&%>RuxL6MGnYMc(^xr}rIu{KBS6(9?mX$SbGsXo1OZ z{VQQyuh?g?7_U8`^L4?tpouIkD%Vde^*-?OrJ-B>yrzY#GfI3`tQAq!|H{Ddzvef) zpMU>Cjm`k3q{NQy@?{%i<{e89Kc4VHi{Ze9&>2hR&IFy8OE%kit787G1ssBws`gU- z)g3MwB|gy+x$CZ){}PzU{A|YkGbfh+N#5n9fAG%Cldea)kKSis*t&CC`f!z;FL<7U|LJA37Nh2wGaz6Ct_b?Q1pLay=+rHCUvA`E-BU7Y2&pyBGb z;7O}}g=$l$UGVxA_v@6-$*XE7vwmxG2ESzHo-t$9gw~&~Oc~;yZ^Rigo_zaz-0Wwo z@aIf6lcMaO)zJ;bbB#Byd(Cp;#GyY*J8S=MoSS9Gd`7S5dcoCo=?1gTD$d^7bL<n={Eu-gDW~i|lUi!tUO) zn{*w-_8Ju3jB;<)`DHx!IY)NBPWrh$&m0rhPHkWDqUOmWt@`_S zzb_SHaPbytnV53R{Mgc|_q%o8O3j?Jih<-kO|NobjVQ+*bii9_t z2Y;Wf(QG|c`J~CceYLrBqw)=Ao#hPnJ^!chxpw<6RiB2%>#CS{?sor{{CjKSf_>?l zwx@4*ew}lA{q^P9XSsh`%-zz%^>fGhyJyb$N=!BC@wyq8AAA15iYbPcg}tj8d)I7x zt?}fsMBOxzUp>`%3J5T%e{)YS_;j^~<49Ax#39J-+@MPZC8u)vytzl`X^V;k10Qu Z!)|>}2?)>r#K6G7;OXk;vd$@?2>>RsIP?Gj literal 0 HcmV?d00001 diff --git a/game/enemy/ai.rb b/game/enemy/ai.rb index ee2d7cf..c75b58a 100644 --- a/game/enemy/ai.rb +++ b/game/enemy/ai.rb @@ -1,28 +1,27 @@ 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 @type = type + @base_speed = case type + when :komodo then 60 + when :force then 130 + end @tile_path = [] # raw tile coords from solver @waypoints = [] # actual world positions to move through @last_player_tile = nil @avoiding_obstacle = false - @speed = BASE_SPEED + @speed = @base_speed @time_since_attack = ATTACK_COOLDOWN end 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 - @speed = BASE_SPEED * 0.3 + @speed = @base_speed * 0.3 else - @speed = BASE_SPEED + @speed = @base_speed end player_tile = [(player_x - 90) / 120, (player_y - 90) / 120].map(&:round) diff --git a/game/enemy/base.rb b/game/enemy/base.rb index bcf05f7..6bc22ca 100644 --- a/game/enemy/base.rb +++ b/game/enemy/base.rb @@ -20,12 +20,14 @@ class Enemy [@i_w, @i_h, @s] end - def initialize(x, y, health = 100) + def initialize(x, y, type, health = 100) @x = x @y = y @w = 25 @h = 30 + @max_health = health @health = health + @type = type @stun = 0 @last_lock = :none @lorentz = $bus.get(:lorentz_field?) || false @@ -34,7 +36,7 @@ class Enemy @lorentz = lorentz end - @ai = EnemyAI.new(self, :chase) + @ai = EnemyAI.new(self, @type) $bus.on(:collides?) do |rect| next collides?(rect) ? :enemy : nil @@ -78,7 +80,7 @@ class Enemy end 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 @ai.update(*closest_event_horizon, dt, @last_lock != :event_horizon) @last_lock = :event_horizon @@ -108,7 +110,8 @@ class Enemy # 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) if $bus.get(:settings, :debug) diff --git a/game/enemy/force.rb b/game/enemy/force.rb index c0c91ca..7e03ba2 100644 --- a/game/enemy/force.rb +++ b/game/enemy/force.rb @@ -4,7 +4,7 @@ class Force < Enemy load 'assets/images/force.png', 21, 32, 1.7 def initialize(x, y) - super(x, y, 100) + super(x, y, :force, 100) $bus.on(:attack) do |attack_x, attack_y, range, damage| # Whoa, did'nt know ruby had hypot functions built in! diff --git a/game/enemy/handler.rb b/game/enemy/handler.rb index 76357f9..d9a56e4 100644 --- a/game/enemy/handler.rb +++ b/game/enemy/handler.rb @@ -1,4 +1,5 @@ require_relative 'force' +require_relative 'komodo' class EnemyHandler def initialize @@ -16,10 +17,11 @@ class EnemyHandler end def spawn! - # For now, just spawn a single enemy at a fixed location - start_room_coords = $bus.get(:start_room_coords) - if @enemies.empty? && start_room_coords - @enemies << Force.new((start_room_coords[0] * 2 + 1 + 4) * 60 + 30, (start_room_coords[1] * 2 + 1 + 4) * 60 + 30) + boss_rooms = $bus.get(:boss_rooms) || [] + if @enemies.count < 4 && rand < (1.0 / (60 * 10)) + boss_room = boss_rooms.sample + 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 diff --git a/game/enemy/komodo.rb b/game/enemy/komodo.rb new file mode 100644 index 0000000..13cd8d6 --- /dev/null +++ b/game/enemy/komodo.rb @@ -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 \ No newline at end of file diff --git a/todo.md b/todo.md index 1c184e1..57111c8 100644 --- a/todo.md +++ b/todo.md @@ -2,8 +2,8 @@ So, #landmines and event horizon should be easy - done -make enemy spawn in the boss rooms with randomness + enemy count -make the lizard kind of enemy with very high health + dps but slow +#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 - done make blade work as planned make bow just normal diff --git a/utils/maze.rb b/utils/maze.rb index 78447af..271d333 100644 --- a/utils/maze.rb +++ b/utils/maze.rb @@ -26,12 +26,13 @@ class MazeData end end + $bus.on(:boss_rooms) do + next @boss_rooms + end + return unless $bus.get(:settings, :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 def solve(x1, y1, x2, y2)