From 129d7f1a064692e714236f9698a286b3aa8d4c93 Mon Sep 17 00:00:00 2001 From: a327ex Date: Fri, 2 Apr 2021 23:53:12 -0300 Subject: [PATCH] Day 45 --- arena.lua | 2 +- assets/sounds/Crickets Chirping 4.ogg | Bin 0 -> 10162 bytes assets/sounds/Critters eating 2.ogg | Bin 0 -> 16765 bytes devlog.md | 9 +- enemies.lua | 156 +++++++++++++++++++++++++- main.lua | 3 + objects.lua | 6 + player.lua | 2 +- todo | 13 ++- 9 files changed, 176 insertions(+), 15 deletions(-) create mode 100644 assets/sounds/Crickets Chirping 4.ogg create mode 100644 assets/sounds/Critters eating 2.ogg diff --git a/arena.lua b/arena.lua index 556c750..e2730df 100644 --- a/arena.lua +++ b/arena.lua @@ -36,7 +36,7 @@ function Arena:on_enter(from, level, units) self.damage_dealt = 0 self.damage_taken = 0 self.main_slow_amount = 1 - self.enemies = {Seeker} + self.enemies = {Seeker, EnemyCritter} self.color = self.color or fg[0] -- Spawn solids and player diff --git a/assets/sounds/Crickets Chirping 4.ogg b/assets/sounds/Crickets Chirping 4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..57a215c8f043541185d37f372a6393b59bf8539d GIT binary patch literal 10162 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 literal 0 HcmV?d00001 diff --git a/assets/sounds/Critters eating 2.ogg b/assets/sounds/Critters eating 2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..4f83f180b9a345f779dbc7278e38d951c56dbe37 GIT binary patch literal 16765 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 K0rZO|@V@{~iH-UI literal 0 HcmV?d00001 diff --git a/devlog.md b/devlog.md index f43fa07..64f8eff 100644 --- a/devlog.md +++ b/devlog.md @@ -760,7 +760,7 @@ objects and the last thing I need is random bugs because a function or variable Added a spawn marker so that it's easier for the player to tell where enemies are spawning and to give a chance to avoid unfair deaths. Slowly getting back into it now... -# Day 44 - 01/04/21 +# Day 43-44 - 31/03/21-01/04/21 * Added a spawn marker before enemies spawn to help with avoiding enemies spawning on top of the player * Prevent spawning of units that cost 3 or more gold on the first level @@ -773,3 +773,10 @@ Added a spawn marker so that it's easier for the player to tell where enemies ar * green - Grant nearby enemies a speed boost on death * blue - Explode into projectiles on death * orange - Charge up and headbutt towards the player at increased speed and damage + +# Day 45 - 02/04/21 + +* Added more enemy modifiers + * yellow - Resistance to knockback and increased HP + * white - Remain static and shoot projectiles + * purple - Explodes into critters on death diff --git a/enemies.lua b/enemies.lua index bf71c32..35e62ca 100644 --- a/enemies.lua +++ b/enemies.lua @@ -13,12 +13,16 @@ function Seeker:init(args) self:calculate_stats(true) self:set_as_steerable(self.v, 2000, 4*math.pi, 4) + self.spawner = random:bool(25) + + --[[ if random:bool(35) then local n = random:int(1, 3) self.speed_booster = n == 1 self.exploder = n == 2 self.headbutter = n == 3 end + ]]-- if self.speed_booster then self.color = green[0]:clone() @@ -46,8 +50,25 @@ function Seeker:init(args) end) elseif self.tank then self.color = yellow[0]:clone() + self.buff_hp_m = 1.5 + (0.05*self.level) + self:calculate_stats() + self.hp = self.max_hp elseif self.shooter then - self.color = white[0]:clone() + self.color = fg[0]:clone() + self.t:after({2, 4}, function() + self.shooting = true + self.t:every({3, 5}, function() + for i = 1, 3 do + self.t:after((1 - self.level*0.01)*0.15*(i-1), function() + shoot1:play{pitch = random:float(0.95, 1.05), volume = 0.1} + self.hfx:use('hit', 0.25, 200, 10, 0.1) + local r = self.r + HitCircle{group = main.current.effects, x = self.x + 0.8*self.shape.w*math.cos(r), y = self.y + 0.8*self.shape.w*math.sin(r), rs = 6} + EnemyProjectile{group = main.current.main, x = self.x + 1.6*self.shape.w*math.cos(r), y = self.y + 1.6*self.shape.w*math.sin(r), color = fg[0], r = r, v = 150 + 5*self.level, dmg = 2*self.dmg} + end) + end + end, nil, nil, 'shooter') + end) elseif self.spawner then self.color = purple[0]:clone() end @@ -71,6 +92,10 @@ function Seeker:update(dt) end self:calculate_stats() + if self.shooter then + self.t:set_every_multiplier('shooter', (1 - self.level*0.02)) + end + if self.being_pushed then local v = math.length(self:get_velocity()) if v < 25 then @@ -80,7 +105,7 @@ function Seeker:update(dt) self:set_angular_damping(0) end else - if self.headbutt_charging then + if self.headbutt_charging or self.shooting then self:set_damping(10) self:rotate_towards_object(main.current.player, 0.5) elseif not self.headbutting then @@ -135,7 +160,7 @@ function Seeker:on_collision_enter(other, contact) end -function Seeker:hit(damage) +function Seeker:hit(damage, projectile) if self.dead then return end self.hfx:use('hit', 0.25, 200, 10) self:show_hp() @@ -170,11 +195,99 @@ function Seeker:hit(damage) end end) end + + if self.spawner then + critter1:play{pitch = random:float(0.95, 1.05), volume = 0.35} + trigger:after(0.01, function() + for i = 1, random:int(3, 6) do + EnemyCritter{group = main.current.main, x = self.x, y = self.y, color = purple[0], r = random:float(0, 2*math.pi), v = 5 + 0.1*self.level, dmg = self.dmg, projectile = projectile} + end + end) + end end end function Seeker:push(f, r) + local n = 1 + if self.tank then n = 0.4 - 0.01*self.level end + self.push_force = n*f + self.being_pushed = true + self.steering_enabled = false + self:apply_impulse(n*f*math.cos(r), n*f*math.sin(r)) + self:apply_angular_impulse(random:table{random:float(-12*math.pi, -4*math.pi), random:float(4*math.pi, 12*math.pi)}) + self:set_damping(1.5*(1/n)) + self:set_angular_damping(1.5*(1/n)) +end + + +function Seeker:speed_boost(duration) + self.speed_boosting = love.timer.getTime() + self.t:after(duration, function() self.speed_boosting = false end, 'speed_boost') +end + + + + +EnemyCritter = Object:extend() +EnemyCritter:implement(GameObject) +EnemyCritter:implement(Physics) +EnemyCritter:implement(Unit) +function EnemyCritter:init(args) + self:init_game_object(args) + self:init_unit() + self:set_as_rectangle(7, 4, 'dynamic', 'enemy_projectile') + self:set_restitution(0.5) + + self.classes = {'enemy_critter'} + self:calculate_stats(true) + self:set_as_steerable(self.v, 400, math.pi, 1) + self:push(args.v, args.r) + self.invulnerable_to = args.projectile + self.t:after(0.5, function() self.invulnerable_to = nil end) +end + + +function EnemyCritter:update(dt) + self:update_game_object(dt) + + if self.being_pushed then + local v = math.length(self:get_velocity()) + if v < 50 then + self.being_pushed = false + self.steering_enabled = true + self:set_damping(0) + self:set_angular_damping(0) + end + else + local player = main.current.player + self:seek_point(player.x, player.y) + self:wander(50, 200, 50) + self:steering_separate(8, main.current.enemies) + self:rotate_towards_velocity(1) + end + self.r = self:get_angle() +end + + +function EnemyCritter:draw() + graphics.push(self.x, self.y, self.r, self.hfx.hit.x, self.hfx.hit.x) + graphics.rectangle(self.x, self.y, self.shape.w, self.shape.h, 2, 2, self.hfx.hit.f and fg[0] or self.color) + graphics.pop() +end + + +function EnemyCritter:hit(damage, projectile) + if self.dead then return end + if projectile == self.invulnerable_to then return end + self.hfx:use('hit', 0.25, 200, 10) + self.hp = self.hp - damage + self:show_hp() + if self.hp <= 0 then self:die() end +end + + +function EnemyCritter:push(f, r) self.push_force = f self.being_pushed = true self.steering_enabled = false @@ -185,9 +298,40 @@ function Seeker:push(f, r) end -function Seeker:speed_boost(duration) - self.speed_boosting = love.timer.getTime() - self.t:after(duration, function() self.speed_boosting = false end, 'speed_boost') +function EnemyCritter:die(x, y, r, n) + if self.dead then return end + x = x or self.x + y = y or self.y + n = n or random:int(2, 3) + for i = 1, n do HitParticle{group = main.current.effects, x = x, y = y, r = random:float(0, 2*math.pi), color = self.color} end + HitCircle{group = main.current.effects, x = x, y = y}:scale_down() + self.dead = true + _G[random:table{'enemy_die1', 'enemy_die2'}]:play{pitch = random:float(0.9, 1.1), volume = 0.5} + critter2:play{pitch = random:float(0.95, 1.05), volume = 0.2} +end + + +function EnemyCritter:on_collision_enter(other, contact) + local x, y = contact:getPositions() + local nx, ny = contact:getNormal() + local r = 0 + if nx == 0 and ny == -1 then r = -math.pi/2 + elseif nx == 0 and ny == 1 then r = math.pi/2 + elseif nx == -1 and ny == 0 then r = math.pi + else r = 0 end + + if other:is(Wall) then + self.hfx:use('hit', 0.15, 200, 10, 0.1) + self:bounce(contact:getNormal()) + end +end + + +function EnemyCritter:on_trigger_enter(other, contact) + if other:is(Player) then + self:die(self.x, self.y, nil, random:int(2, 3)) + other:hit(self.dmg) + end end diff --git a/main.lua b/main.lua index fb49a7d..6d5a06a 100644 --- a/main.lua +++ b/main.lua @@ -25,6 +25,8 @@ function init() ui_transition1 = Sound('Wind Bolt 8.ogg', s) ui_transition2 = Sound('Wind Bolt 12.ogg', s) headbutt1 = Sound('Wind Bolt 14.ogg', s) + critter1 = Sound('Critters eating 2.ogg', s) + critter2 = Sound('Crickets Chirping 4.ogg', s) error1 = Sound('Error 2.ogg', s) coins1 = Sound('Coins 7.ogg', s) coins2 = Sound('Coins 8.ogg', s) @@ -261,6 +263,7 @@ function init() ['enchanter'] = {hp = 1.2, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1.2, mvspd = 1.2}, ['psy'] = {hp = 1.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 0.5, mvspd = 1}, ['seeker'] = {hp = 0.5, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.3}, + ['enemy_critter'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 0.5}, ['saboteur'] = {hp = 1, dmg = 1, aspd = 1, area_dmg = 1, area_size = 1, def = 1, mvspd = 1.4}, } diff --git a/objects.lua b/objects.lua index 2c79fcf..a9da518 100644 --- a/objects.lua +++ b/objects.lua @@ -236,6 +236,12 @@ function Unit:calculate_stats(first_run) self.base_hp = 100*math.pow(2, self.level-1) self.base_dmg = 10*math.pow(2, self.level-1) self.base_mvspd = 75 + elseif self:is(EnemyCritter) then + local x = self.level + local y = {0, 1, 4, 2, 3, 6, 3, 5, 9, 4, 6, 11, 7, 9, 15, 8, 10, 18, 9, 11, 21, 14, 15, 24, 25} + self.base_hp = 25 + 30*y[x] + self.base_dmg = 10 + 3*y[x] + self.base_mvspd = 60 + 3*y[x] end self.base_aspd_m = 1 self.base_area_dmg_m = 1 diff --git a/player.lua b/player.lua index 0d54138..3c6f5c5 100644 --- a/player.lua +++ b/player.lua @@ -823,7 +823,7 @@ function Projectile:on_trigger_enter(other, contact) hit3:play{pitch = random:float(0.95, 1.05), volume = 0.35} end - other:hit(self.dmg) + other:hit(self.dmg, self) if self.character == 'hunter' and random:bool(40) then trigger:after(0.01, function() diff --git a/todo b/todo index 256e5ef..b6ec0bf 100644 --- a/todo +++ b/todo @@ -11,9 +11,9 @@ * green - Grant nearby enemies a speed boost on death * blue - Explode into projectiles on death * orange - Charge up and headbutt towards the player at increased speed and damage - yellow - Resistance to knockback - white - Remain static and shoot projectiles - purple - Explodes into critters on death + * yellow - Resistance to knockback and increased HP + * white - Remain static and shoot projectiles + * purple - Explodes into critters on death 6. Mini boss every 3rd level This is just a special enemy with more HP and ability to buff nearby enemies with modifiers, no additional AI or attack patterns @@ -131,15 +131,16 @@ Boss ideas Pretends to be dead, grants speed buffs to enemies after death, especially if the round has gone on for too long which means the player is surviving with 1 unit Uses Psykino's tech to pull enemies together into a point and have that point move around and bounce on edges, thus having a ball of enemies moving around that occasionally explodes -Map modifiers - Wall spikes: walls damage you when you hit it - Engine improvements for after SNKRX release + Node refactor: described partly somewhere in the devlog + Rewrite SNKRX: using this game as a target for the node refactor will yield good results for both the refactor and future SNKRX updates, if any on_hit: on_collision_enter/exit are automatically called and automatically call on_hit/on_leave for each object This enables the definition of on_hit on each object and the question of where the logic should stay is solved/dodged Spurred by Wall needing to have its own on_hit function to do something when the player hits it, without having to change player code for all Walls, Defining on_hit on the Wall creation call for that specific Wall, and thus that specific Wall will have this behavior while other walls won't + https://i.imgur.com/asPdpnQ.png ? + Not sure if I should go all the way with event systems like this or only have it work for specific cases, need to think about it more release tool: Build a command line tool that creates projects and builds them up for release automatically on Windows, Web and Steam All the steps for this are listed on the readme and everything about it that can be automated should