From 16c1140ead99064799113eb3d8ddcf47929bba70 Mon Sep 17 00:00:00 2001 From: Elizabeth Alexander Hunt Date: Thu, 28 May 2026 21:01:02 -0700 Subject: Adding debug collision boxes, making bullets hurt you, and be able to kill bullets upon consumption --- ai.lua | 6 ++++-- camera.lua | 6 ++++++ collisions.lua | 26 ++++++++++++++++++++++---- dyl.lua | 6 ++++++ entity.lua | 15 +++++++++++---- math.lua | 2 +- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/ai.lua b/ai.lua index af1a807..3900af9 100644 --- a/ai.lua +++ b/ai.lua @@ -26,16 +26,17 @@ function AiController:update(dt) end function gliding_gun() - _glider_damage = { amount = 2, knockback = { magnitude = 300, time = 0.080 } } + _glider_damage = { amount = 2, knockback = { magnitude = 300, time = 0.070 } } GlidingGunBuilder = EntityBuilder:new(World) function GlidingGunBuilder:transition_state() end return GlidingGunBuilder:b_type(Entities.Bullet) :b_line_of_sight(vec2(1, 0)) :b_position(vec2(100, 100)) + :b_health() :b_render_order(0) :b_collidable() - :b_live_for(25) + :b_live_for(2) :b_velocity(vec2(-40, 0)) :b_collision_bounds(vec2(3, 4), vec2(5, 6)) :b_add_state( @@ -48,6 +49,7 @@ function gliding_gun() } } ) + :b_damage(_glider_damage) :b_state(States.Active) :build() end diff --git a/camera.lua b/camera.lua index 6062ee7..bb69183 100644 --- a/camera.lua +++ b/camera.lua @@ -42,6 +42,12 @@ end _cull_factor = 1/4 function Camera:render(entity) screen_position = (entity.sprite_position or entity.position) - self.position + if DEBUG and entity.collision then + entity_collision_box = { top_left = screen_position + entity.collision_bounds.top_left, bottom_right = screen_position + entity.collision_bounds.bottom_right } + -- entity_collision_box = { top_left = screen_position, bottom_right = screen_position + vec2(8, 8)} + -- entity_collision_box = entity_collision_bounds + rect(entity_collision_box.top_left.x, entity_collision_box.top_left.y, entity_collision_box.bottom_right.x, entity_collision_box.bottom_right.y, 5) + end if screen_position:in_bounds(SCREEN * -_cull_factor, SCREEN * (1 + _cull_factor)) then entity:render(screen_position) end diff --git a/collisions.lua b/collisions.lua index 3d3ba46..093d57c 100644 --- a/collisions.lua +++ b/collisions.lua @@ -5,9 +5,24 @@ function is_colliding(a, b) ) end +_kills = { + vec2(Entities.Sword, Entities.Bullet) +} +function kills(a, b) + return some(_kills, function (v) return a.entity_type == v.x and b.entity_type == v.y end) +end +_consume = { + -- Consume the bullet as soon as it hits a target + vec2(Entities.Player, Entities.Bullet), + vec2(Entities.Wife, Entities.Bullet) +} +function consume(a, b) + return some(_consume, function (v) return a.entity_type == v.x and b.entity_type == v.y end) +end _hurts = { vec2(Entities.Bullet, Entities.Player), vec2(Entities.Sword, Entities.Enemy), + vec2(Entities.Enemy, Entities.Player) } function hurts(a, b) if b:is_in_iframe() then @@ -26,6 +41,12 @@ function handle_collision(a, b) end if hurts(a, b) then b:take_damage(a.line_of_sight, a.damage) + if consume(b, a) then + a:kill() + end + end + if kills(a, b) then + b:kill() end end @@ -36,10 +57,7 @@ function run_collisions() if a.id == b.id then goto continue end - if is_colliding( - {top_left = (a.collision_bounds.top_left + a.position), bottom_right = (a.collision_bounds.bottom_right + a.position) }, - {top_left = (b.collision_bounds.top_left + b.position), bottom_right = (b.collision_bounds.bottom_right + b.position) } - ) then + if is_colliding(a:collision_box(), b:collision_box()) then handle_collision(a, b) end ::continue:: diff --git a/dyl.lua b/dyl.lua index 116315b..9e60dd3 100644 --- a/dyl.lua +++ b/dyl.lua @@ -1,3 +1,5 @@ +DEBUG = true + _slashing_timer_sec = .12 _slash_animation_distance = 3 function slashing_particle(following) @@ -53,6 +55,7 @@ function fire() end function enemy() + _enemy_damage_spec = { amount = 2, knockback = { magnitude = 200, time = 0.120 } } EnemyBuilder = EntityBuilder:new(World) function EnemyBuilder:transition_state() end @@ -61,6 +64,7 @@ function enemy() :b_position(vec2(30, -40)) :b_sprite_position(vec2(30, 40)) :b_line_of_sight(vec2(1, 0)) + :b_damage(_enemy_damage_spec) :b_render_order(1) :b_collidable() :b_add_state( @@ -263,7 +267,9 @@ function player() :b_render_order(2) :b_collidable() :b_position(vec2(30, 30)) + :b_health(10) :b_sprite_position(vec2(30, 30)) + :b_collision_bounds(vec2(2, 2), vec2(5, 6)) :b_add_state( States.Idle, { animation = { diff --git a/entity.lua b/entity.lua index 5698c77..12d4862 100644 --- a/entity.lua +++ b/entity.lua @@ -68,6 +68,7 @@ function Entity:update(dt) if self.life_time ~= nil then self.life_time -= dt + if self.life_time <= 0 then self:kill() return end end if self.health ~= nil and self.health <= 0 then self:kill() @@ -186,6 +187,10 @@ function _get_animation_key(line_of_sight) return _animation_keys[n_line_of_sight.x + 2] .. "_x" end +function Entity:collision_box() + return {top_left = (self.collision_bounds.top_left + self.position), bottom_right = (self.collision_bounds.bottom_right + self.position) } +end + function Entity:render(screen_position) animation = self.states[self.state].animation if (animation == nil) then return end @@ -263,6 +268,12 @@ function EntityBuilder:b_equipped(equipped) end function EntityBuilder:b_collidable() self.collision = true + if (self.collision_bounds == nil) then + self.collision_bounds = { + top_left = vec2(0, 0), + bottom_right = vec2(SPRITE_DIMS) + } + end return self end function EntityBuilder:b_live_for(t) @@ -286,10 +297,6 @@ function EntityBuilder:b_collision_bounds(top_left, bottom_right) end function EntityBuilder:build() self.equipped = {} - self.collision_bounds = { - top_left = vec2(0, 0), - bottom_right = vec2(SPRITE_DIMS) - } return self.build_context.world.add(setmetatable(self, Entity)) end \ No newline at end of file diff --git a/math.lua b/math.lua index ddc6644..4ebd38f 100644 --- a/math.lua +++ b/math.lua @@ -9,7 +9,7 @@ Vec2.__mul = function(a, b) return vec2(a.x * b.x, a.y * b.y) end Vec2.__div = function(a, b) - if (type(b) == "number") then return vec2(a.x / b, a.y / b) end -- scalar mult + if (type(b) == "number") then return vec2(a.x / b, a.y / b) end -- scalar div return vec2(a.x / b.x, a.y / b.y) end Vec2.__tostring = function(a) return "(" .. fmt(a.x) .. "," .. fmt(a.y) .. ")" end -- cgit v1.3