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:** Make hitbox modifiable.
- **actor2D:** Add multiple hitbox support.
### Changed ### Changed
- **world2D:** Use a list for bodies (hitboxes, etc) and one other for actors - **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:setSprite("player", 8, 12)
self:cloneSprite() self:cloneSprite()
self:setYGravity(480) self:setYGravity(480)
self.isPunching = false
self.direction = 1
end end
function Player:updateStart(dt) function Player:updateStart(dt)
@ -19,13 +22,29 @@ function Player:updateStart(dt)
else else
self.mainHitbox:modify(0, 0, 16, 24) self.mainHitbox:modify(0, 0, 16, 24)
end end
if self.keys["left"].isDown then if self.keys["left"].isDown and (not self.isPunching) then
self.xsp = -120 self.xsp = -120
end end
if self.keys["right"].isDown then if self.keys["right"].isDown and (not self.isPunching) then
self.xsp = 120 self.xsp = 120
end 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 if self.keys["start"].isPressed then
--self.world:switchActivity() --self.world:switchActivity()
--self.assets:switchActivity() --self.assets:switchActivity()
@ -43,6 +62,9 @@ end
function Player:setAnimation() function Player:setAnimation()
self:setCustomSpeed(math.abs(self.xsp) / 12) self:setCustomSpeed(math.abs(self.xsp) / 12)
if (self.isPunching) then
self:changeAnimation("punch", false)
else
if (self.onGround) then if (self.onGround) then
if math.abs(self.xsp) > 0 then if math.abs(self.xsp) > 0 then
self:changeAnimation("walk", false) self:changeAnimation("walk", false)
@ -52,12 +74,14 @@ function Player:setAnimation()
else else
self:changeAnimation("jump", true) self:changeAnimation("jump", true)
end end
end
end end
function Player:setDirection(direction) function Player:setDirection(direction)
direction = direction or 0 direction = direction or 0
if direction ~= 0 then if direction ~= 0 then
direction = utils.math.sign(direction) direction = utils.math.sign(direction)
self.direction = direction
self:setSpriteScallingX(direction) self:setSpriteScallingX(direction)
end end
end end
@ -68,9 +92,15 @@ function Player:collisionResponse(collision)
end end
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() function Player:draw()
Player.super.draw(self) Player.super.draw(self)
self:drawMainHitbox() self:drawHitboxes()
utils.graphics.resetColor() utils.graphics.resetColor()
end end

View file

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

View file

@ -34,7 +34,7 @@ local Hitbox = require(cwd .. "utils.hitbox2D")
function Actor2D:new(world, type, x, y, w, h, isSolid) function Actor2D:new(world, type, x, y, w, h, isSolid)
self:setCoordinate(x, y) self:setCoordinate(x, y)
Actor2D.super.new(self, world, type, isSolid) Actor2D.super.new(self, world, type, isSolid)
self:initMainHitbox(w, h) self:initHitboxes(w, h)
end end
function BaseActor:destroy() function BaseActor:destroy()
@ -178,14 +178,76 @@ end
-- HITBOXES FUNCTIONS -- HITBOXES FUNCTIONS
-- Functions related to actor hitboxes -- Functions related to actor hitboxes
function Actor2D:initMainHitbox(w, h) function Actor2D:initHitboxes(w, h)
self.w = w or 0 self.w = w or 0
self.h = h 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.mainHitbox = Hitbox(self, self.type, 0, 0, self.w, self.h, self.isSolid)
self.world:registerBody(self.mainHitbox) self.world:registerBody(self.mainHitbox)
end 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() function Actor2D:drawMainHitbox()
self.mainHitbox:draw() self.mainHitbox:draw()
end end