From a856739a36efba96e9fdae86bfbabfbed12bf04e Mon Sep 17 00:00:00 2001 From: Kazhnuz Date: Fri, 7 May 2021 18:27:13 +0200 Subject: [PATCH] improvement: refactor hitbox management --- .../birb/modules/world/actors/actor2D.lua | 36 ++---------------- .../birb/modules/world/actors/actor3D.lua | 36 ++---------------- .../modules/world/actors/mixins/physics.lua | 37 +++++++++++++++++-- 3 files changed, 40 insertions(+), 69 deletions(-) diff --git a/sonic-radiance.love/birb/modules/world/actors/actor2D.lua b/sonic-radiance.love/birb/modules/world/actors/actor2D.lua index 7a86b74..b3885d2 100644 --- a/sonic-radiance.love/birb/modules/world/actors/actor2D.lua +++ b/sonic-radiance.love/birb/modules/world/actors/actor2D.lua @@ -42,8 +42,7 @@ local Hitbox = require "birb.modules.world.actors.utils.hitbox2D" function Actor2D:new(world, type, x, y, w, h, isSolid) self:init(world, type) - self:initPhysics(x, y, 0, w, h, 0, isSolid) - self:initHitboxes() + self:initPhysics(Hitbox, x, y, 0, w, h, 0, isSolid) self:initTimers() self:initSprite() self:initKeys() @@ -142,37 +141,8 @@ end -- HITBOXES FUNCTIONS -- Functions related to actor hitboxes -function Actor2D:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID) - local sx, sy = self:getSpriteScalling() - local type = framedata[1] - local data = framedata[2] - local isSolid = framedata[3] or false - local anim = animationID or "null" - local frame = frameID or 0 - local id = hitboxID or 0 - - if (type == "main") then - self.mainHitbox:setFromData(data, sx, sy) - else - local hitboxName = anim .. frame .. type .. id - self:addHitbox(hitboxName, type, data, sx, sy, isSolid) - return hitboxName - end -end - -function Actor2D:initMainHitbox() - self.mainHitbox = Hitbox(self, self.type, {0, 0, self.w, self.h}, 0, 0, self.isSolid) - self.mainHitbox:advertiseAsMainHitbox() -end - -function Actor2D:addHitbox(name, type, data, sx, sy, isSolid) - if (self.hitboxes[name] ~= nil) then - core.debug:warning("actor2D", "the hitbox " .. name .. " already exists") - else - local hitbox = Hitbox(self, type, data, sx, sy, isSolid) - self.hitboxes[name] = hitbox - return hitbox - end +function Actor2D:packForHitbox() + return {0, 0, self.w, self.h} end function Actor2D:checkHitboxCollisions(name, filter) diff --git a/sonic-radiance.love/birb/modules/world/actors/actor3D.lua b/sonic-radiance.love/birb/modules/world/actors/actor3D.lua index 670b255..1f83f19 100644 --- a/sonic-radiance.love/birb/modules/world/actors/actor3D.lua +++ b/sonic-radiance.love/birb/modules/world/actors/actor3D.lua @@ -43,8 +43,7 @@ Actor3D:implement(PhysicalActor) function Actor3D:new(world, type, x, y, z, w, h, d, isSolid) self:init(world, type) - self:initPhysics(x, y, z, w, h, d, isSolid) - self:initHitboxes() + self:initPhysics(Hitbox, x, y, z, w, h, d, isSolid) self:initTimers() self:initSprite() self:initKeys() @@ -165,37 +164,8 @@ end -- HITBOXES FUNCTIONS -- Functions related to actor hitboxes -function Actor3D:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID) - local sx, sy = self:getSpriteScalling() - local type = framedata[1] - local data = framedata[2] - local isSolid = framedata[3] or false - local anim = animationID or "null" - local frame = frameID or 0 - local id = hitboxID or 0 - - if (type == "main") then - self.mainHitbox:setFromData(data, sx, sy) - else - local hitboxName = anim .. frame .. type .. id - self:addHitbox(hitboxName, type, data, sx, sy, isSolid) - return hitboxName - end -end - -function Actor3D:initMainHitbox() - self.mainHitbox = Hitbox(self, self.type, {0, 0, 0, self.w, self.h, self.d}, 1, 1, self.isSolid) - self.mainHitbox:advertiseAsMainHitbox() -end - -function Actor3D:addHitbox(name, type, data, sx, sy, isSolid) - if (self.hitboxes[name] ~= nil) then - core.debug:warning("actor3D", "the hitbox " .. name .. " already exists") - else - local hitbox = Hitbox(self, type, data, sx, sy, isSolid) - self.hitboxes[name] = hitbox - return hitbox - end +function Actor3D:packForHitbox() + return {0, 0, 0, self.w, self.h, self.d} end function Actor3D:checkHitboxCollisions(name, filter) diff --git a/sonic-radiance.love/birb/modules/world/actors/mixins/physics.lua b/sonic-radiance.love/birb/modules/world/actors/mixins/physics.lua index 86c21c6..513ba0b 100644 --- a/sonic-radiance.love/birb/modules/world/actors/mixins/physics.lua +++ b/sonic-radiance.love/birb/modules/world/actors/mixins/physics.lua @@ -3,7 +3,7 @@ PhysicalActor = Object:extend() -- PHYSICS FUNCTIONS -- Raw implementation of everything common in physics -function PhysicalActor:initPhysics(x, y, z, w, h, d, isSolid) +function PhysicalActor:initPhysics(hitboxObj, x, y, z, w, h, d, isSolid) self:setCoordinate(x, y, z) self.isSolid = isSolid or false @@ -21,6 +21,7 @@ function PhysicalActor:initPhysics(x, y, z, w, h, d, isSolid) self.zfrc = 0 self:initGravity() + self:initHitboxes(hitboxObj) self:setBounceFactor() self:setFilter() @@ -134,7 +135,8 @@ end -- HITBOX FUNCTIONS -- All functions to handle hitboxes -function PhysicalActor:initHitboxes() +function PhysicalActor:initHitboxes(hitboxObj) + self.Hitbox = hitboxObj self:initMainHitbox() self.hitboxes = {} @@ -143,7 +145,8 @@ function PhysicalActor:initHitboxes() end function PhysicalActor:initMainHitbox() - -- Empty function : don't load ANY real hitbox function into PhysicalActor + self.mainHitbox = self.Hitbox(self, self.type, self:packForHitbox(), 0, 0, self.isSolid) + self.mainHitbox:advertiseAsMainHitbox() end function PhysicalActor:setHitboxFile(file) @@ -173,6 +176,34 @@ function PhysicalActor:getHitboxList(animation, frame) end end +function PhysicalActor:addHitboxFromFrameData(framedata, animationID, frameID, hitboxID) + local sx, sy = self.sprite:getScalling() + local type = framedata[1] + local box = framedata[2] + local isSolid = framedata[3] or false + local anim = animationID or "null" + local frame = frameID or 0 + local id = hitboxID or 0 + + if (type == "main") then + self.mainHitbox:setFromData(box, sx, sy) + else + local hitboxName = anim .. frame .. type .. id + self:addHitbox(hitboxName, type, box, sx, sy, isSolid) + return hitboxName + end +end + +function PhysicalActor:addHitbox(name, type, data, sx, sy, isSolid) + if (self.hitboxes[name] ~= nil) then + core.debug:logWarn("PhysicalActor", "the hitbox " .. name .. " already exists") + else + local hitbox = self.Hitbox(self, type, data, sx, sy, isSolid) + self.hitboxes[name] = hitbox + return hitbox + end +end + function PhysicalActor:updateHitboxes() if (self.hitboxList ~= nil) then self:purgeHitbox()