diff --git a/CHANGELOG.md b/CHANGELOG.md index 680fef8..ebec843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **world2D:** Use a list for bodies (hitboxes, etc) and one other for actors +- **world2D:** Make the hitbox an object, owned by the actor + ### Fixed - **world:** Remove a forgotten camera debug function diff --git a/gamecore/modules/world/actors/actor2D.lua b/gamecore/modules/world/actors/actor2D.lua index d67df15..669f697 100644 --- a/gamecore/modules/world/actors/actor2D.lua +++ b/gamecore/modules/world/actors/actor2D.lua @@ -26,13 +26,21 @@ local cwd = (...):gsub('%.actor2D$', '') .. "." local BaseActor = require(cwd .. "baseactor") local Actor2D = BaseActor:extend() +local Hitbox = require(cwd .. "utils.hitbox2D") + -- INIT FUNCTIONS -- Initialise the actor and its base functions function Actor2D:new(world, type, x, y, w, h, isSolid) self:setCoordinate(x, y) - self:initMainHitbox(w, h) Actor2D.super.new(self, world, type, isSolid) + self:initMainHitbox(w, h) +end + +function BaseActor:destroy() + self.world:removeActor(self) + self.world:removeBody(self.mainHitbox) + self.isDestroyed = true end -- MOVEMENT FUNCTIONS @@ -118,7 +126,8 @@ end function Actor2D:move(dx, dy) local cols, colNumber = {}, 0 if (self.isDestroyed == false) then - self.x, self.y, cols, colNumber = self.world:moveActor(self, dx, dy, self.filter) + self.x, self.y, cols, colNumber = self.mainHitbox:checkCollision(dx, dy, self.filter) + self.mainHitbox:updatePosition() end return self.x, self.y, cols, colNumber end @@ -126,7 +135,7 @@ end function Actor2D:checkCollision(dx, dy) local x, y, cols, colNumber = dx, dy, {}, 0 if (self.isDestroyed == false) then - x, y, cols, colNumber = self.world:moveActor(self, dx, dy, self.filter) + x, y, cols, colNumber = self.mainHitbox:checkCollision(dx, dy, self.filter) end return self.x, self.y, cols, colNumber end @@ -172,12 +181,13 @@ end function Actor2D:initMainHitbox(w, h) self.w = w or 0 self.h = h or 0 + + self.mainHitbox = Hitbox(self, self.type, 0, 0, self.w, self.h, self.isSolid) + self.world:registerBody(self.mainHitbox) end function Actor2D:drawMainHitbox() - local x, y = math.floor(self.x), math.floor(self.y) - love.graphics.setColor(self.debug.r, self.debug.g, self.debug.b, 1) - utils.graphics.box(x, y, self.w, self.h) + self.mainHitbox:draw() end -- COORDINATE FUNCTION diff --git a/gamecore/modules/world/actors/utils/hitbox2D.lua b/gamecore/modules/world/actors/utils/hitbox2D.lua new file mode 100644 index 0000000..4f4953d --- /dev/null +++ b/gamecore/modules/world/actors/utils/hitbox2D.lua @@ -0,0 +1,107 @@ +-- hitbox2D.lua :: a basic 2D hitbox object. It's used by the actors to check +-- collisions and to handle different type of responses. + +--[[ + Copyright © 2019 Kazhnuz + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] + +local Hitbox2D = Object:extend() + +-- INIT FUNCTIONS +-- Initialise the actor and its base functions + +function Hitbox2D:new(owner, type, ox, oy, w, h, isSolid) + self.owner = owner + self.world = owner.world + + self.type = type + self.ox = ox + self.oy = oy + self.x, self.y = self:getPosition() + self.w = w + self.h = h + self.isSolid = isSolid + + self:setDebugColor(0,0,0) +end + +function Hitbox2D:modify(ox, oy, w, h) + self.ox = ox + self.oy = oy + self.x, self.y = self:getPosition() + self.w = w + self.h = h +end + +function Hitbox2D:setDebugColor(r,g,b) + self.debug = {} + self.debug.r = r + self.debug.g = g + self.debug.b = b +end + +-- COORDINATE FUNCTIONS +-- Handle Hitbox position + +function Hitbox2D:updatePosition() + self.x, self.y = self:getPosition() + self.world:updateBody(self) + return self.x, self.y +end + +function Hitbox2D:getPosition() + return self.ox + self.owner.x, self.oy + self.owner.y +end + +function Hitbox2D:getOwnerPosition() + return self.x - self.ox, self.y - self.oy +end + +function Hitbox2D:getNewOwnerPosition(x, y) + return x - self.ox, y - self.oy +end + +function Hitbox2D:getCenter() + return self.x + (self.w/2), self.y + (self.h/2) +end + +-- COLLISION FUNCTIONS +-- Handle Hitbox position + +function Hitbox2D:checkCollision(dx, dy, filter) + self:updatePosition() + + local dx, dy = self.ox + dx, self.oy + dy + local x, y, cols, colNumber = self.world:checkCollision(self, dx, dy, filter) + local newx, newy = self:getNewOwnerPosition(x, y) + + return newx, newy, cols, colNumber +end + +-- DRAW FUNCTIONS +-- Just some debug function to draw hitbox + +function Hitbox2D:draw() + local x, y = self:getPosition() + love.graphics.setColor(self.debug.r, self.debug.g, self.debug.b, 1) + utils.graphics.box(x, y, self.w, self.h) +end + +return Hitbox2D diff --git a/gamecore/modules/world/baseworld.lua b/gamecore/modules/world/baseworld.lua index db3fbf0..375b2dc 100644 --- a/gamecore/modules/world/baseworld.lua +++ b/gamecore/modules/world/baseworld.lua @@ -163,7 +163,15 @@ function BaseWorld:getVisibleActors(id) local y = camy - paddingh local w = camw + paddingw * 2 local h = camh + paddingh * 2 - return self:queryRect(x, y, w, h) + + local query = self:queryRect(x, y, w, h) + local returnquery = {} + + for i,v in ipairs(query) do + table.insert(returnquery, v.owner) + end + + return returnquery end -- INFO FUNCTIONS diff --git a/gamecore/modules/world/world2D.lua b/gamecore/modules/world/world2D.lua index cba3b17..98ce64e 100644 --- a/gamecore/modules/world/world2D.lua +++ b/gamecore/modules/world/world2D.lua @@ -35,7 +35,7 @@ function World2D:new(scene, actorlist, mapfile) end -- ACTORS FUNCTIONS --- Wrappers around Bump2D functions +-- Add support for bodies in Actor functions function World2D:initActors() self.currentCreationID = 0 @@ -45,12 +45,21 @@ end function World2D:registerActor(actor) World2D.super.registerActor(self, actor) - return self.bodies:add(actor, actor.x, actor.y, actor.w, actor.h) end -function World2D:removeActor(actor) - World2D.super.removeActor(self, actor) - return self.bodies:remove(actor) +function World2D:registerBody(body) + return self.bodies:add(body, body.x, body.y, body.w, body.h) +end + +-- ACTORS FUNCTIONS +-- Wrappers around Bump2D functions + +function World2D:updateBody(body) + return self.bodies:update(body, body.x, body.y, body.w, body.h) +end + +function World2D:removeBody(body) + return self.bodies:remove(body) end function World2D:moveActor(actor, x, y, filter)