feat(world): add multiple hitbox support on actor2D

This commit is contained in:
Kazhnuz 2019-06-22 22:11:22 +02:00
parent c553dfafa3
commit f88c7f49e4
4 changed files with 101 additions and 7 deletions

View file

@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **actor2D:** Make hitbox modifiable.
- **actor2D:** Add multiple hitbox support.
### Changed
- **world2D:** Use a list for bodies (hitboxes, etc) and one other for actors

View file

@ -6,6 +6,9 @@ function Player:new(world, x, y, id)
self:setSprite("player", 8, 12)
self:cloneSprite()
self:setYGravity(480)
self.isPunching = false
self.direction = 1
end
function Player:updateStart(dt)
@ -19,13 +22,29 @@ function Player:updateStart(dt)
else
self.mainHitbox:modify(0, 0, 16, 24)
end
if self.keys["left"].isDown then
if self.keys["left"].isDown and (not self.isPunching) then
self.xsp = -120
end
if self.keys["right"].isDown then
if self.keys["right"].isDown and (not self.isPunching) then
self.xsp = 120
end
if self.keys["A"].isDown then
self.isPunching = true
if (self.direction == 1) then
self:addHitbox("punch", "punch", 16, 6, 12, 12, false)
else
self:addHitbox("punch", "punch", -12, 6, 12, 12, false)
end
else
self.isPunching = false
self:removeHitbox("punch")
end
if (self.isPunching) then
self:checkHitboxCollisions("punch")
end
if self.keys["start"].isPressed then
--self.world:switchActivity()
--self.assets:switchActivity()
@ -43,6 +62,9 @@ end
function Player:setAnimation()
self:setCustomSpeed(math.abs(self.xsp) / 12)
if (self.isPunching) then
self:changeAnimation("punch", false)
else
if (self.onGround) then
if math.abs(self.xsp) > 0 then
self:changeAnimation("walk", false)
@ -53,11 +75,13 @@ function Player:setAnimation()
self:changeAnimation("jump", true)
end
end
end
function Player:setDirection(direction)
direction = direction or 0
if direction ~= 0 then
direction = utils.math.sign(direction)
self.direction = direction
self:setSpriteScallingX(direction)
end
end
@ -68,9 +92,15 @@ function Player:collisionResponse(collision)
end
end
function Player:hitboxResponse(name, type, collision)
if (collision.other.type == "coin") and (type == "punch") then
collision.other.owner:takeCoin(self)
end
end
function Player:draw()
Player.super.draw(self)
self:drawMainHitbox()
self:drawHitboxes()
utils.graphics.resetColor()
end

View file

@ -43,8 +43,8 @@ return {
pauseAtEnd = false,
},
["punch"] = {
startAt = 10,
endAt = 10,
startAt = 11,
endAt = 11,
loop = 1,
speed = 0,
pauseAtEnd = false,

View file

@ -34,7 +34,7 @@ local Hitbox = require(cwd .. "utils.hitbox2D")
function Actor2D:new(world, type, x, y, w, h, isSolid)
self:setCoordinate(x, y)
Actor2D.super.new(self, world, type, isSolid)
self:initMainHitbox(w, h)
self:initHitboxes(w, h)
end
function BaseActor:destroy()
@ -178,14 +178,76 @@ end
-- HITBOXES FUNCTIONS
-- Functions related to actor hitboxes
function Actor2D:initMainHitbox(w, h)
function Actor2D:initHitboxes(w, h)
self.w = w or 0
self.h = h or 0
self:initMainHitbox()
self.hitboxes = {}
end
function Actor2D:initMainHitbox()
self.mainHitbox = Hitbox(self, self.type, 0, 0, self.w, self.h, self.isSolid)
self.world:registerBody(self.mainHitbox)
end
function Actor2D:addHitbox(name, type, ox, oy, w, h, isSolid)
if (self.hitboxes[name] ~= nil) then
print("ERROR:", "The hitbox " .. name .. " already exists")
else
local hitbox = Hitbox(self, type, ox, oy, w, h, isSolid)
self.hitboxes[name] = hitbox
self.world:registerBody(self.hitboxes[name])
return hitbox
end
end
function Actor2D:checkHitboxCollisions(name, filter)
self:checkHitboxCollisionsAtPoint(name, self.x, self.y, filter)
end
function Actor2D:checkHitboxCollisionsAtPoint(name, dx, dy, filter)
local x, y, cols, colNumber = dx, dy, {}, 0
local filter = filter or self.filter
if (self.isDestroyed == false) and (self.hitboxes[name] ~= nil) then
x, y, cols, colNumber = self.hitboxes[name]:checkCollision(dx, dy, filter)
local type = self.hitboxes[name].type
for i, col in ipairs(cols) do
self:hitboxResponse(name, type, col)
end
end
return x, y, cols, colNumber
end
function Actor2D:hitboxResponse(name, type, collision)
-- just a blank placeholder function
end
function Actor2D:removeHitbox(name)
if (self.hitboxes[name] ~= nil) then
self.world:removeBody(self.hitboxes[name])
self.hitboxes[name] = nil
end
end
function Actor2D:purgeHitbox()
for k,v in pairs(self.hitboxes) do
self.world:removeBody(v)
end
self.hitboxes = {}
end
function Actor2D:drawHitboxes()
for k,v in pairs(self.hitboxes) do
v:draw()
end
self.mainHitbox:draw()
end
function Actor2D:drawMainHitbox()
self.mainHitbox:draw()
end