Like any good platformer, our character will bounce off of enemies when he/she lands on top of them, but not when he/she hits them from the side. We'll accomplish this by checking the position of the collision on the main character.
We've already created the basic behavior for when the character collides with an enemy, by taking damage and flinching back.
Although there are a number of tests to determine whether a body has landed on top of another body, such as checking direction or comparing positions for horizontal overlap and vertical separation, we're going to create another sensor fixture. This one is intended to detect collisions with walls, rather than other sprites. Open character/init.lua
and calculate the width of the new body in the main function:
local spirit = setmetatable({isSensor = true, filter = kind.Group}, {__index = kind.Form}) local width, height = calculateBaseWidth(body) width, height = width or (sprite.width / 2 - 2), height or (sprite.height / 2) return function(world)
Use this base width to create an outline along the bottom of the sprite:
width, height = width or (sprite.width / 2 - 2), height or (sprite.height / 2)
local feet = {isSensor = true, filter = categories.body; shape = {width, height; width, height + 2; -width, height + 2; -width, height} }
return function(world)
Include this fixture as the third component of each character body:
local feet = {isSensor = true, filter = categories.body; shape = {width, height; width, height + 2; -width, height + 2; -width, height} }
physics.addBody(sprite, 'dynamic', body, spirit, feet)
Modify the contact
function so that its collision recognition checks for this specific overlap. This can be used to distinguish between landing on the ground or running into a wall:
if other.Name == 'Ground' then if event.selfElement == 3 then self:dispatchEvent{name = 'Land'} self.Standing = other elseif self.Standing and self.Standing ~= other then self:dispatchEvent{name = 'Bump'} end elseif self.Allegiance == categories.player then
It can be used to distinguish whether the player character has landed on top of an enemy or bumped into it from the side:
elseif self.Allegiance == categories.player then if other.Allegiance == categories.enemy and event.selfElement ~= 3 then self:dispatchEvent{name = 'Hurt'} end elseif self.Allegiance == categories.enemy then
It can also be used by the enemy to act more bouncy when the layer jumps on them. The player bouncing off the tops of enemies is part of their physics, not their control.
elseif self.Allegiance == categories.enemy then if other.Allegiance == categories.player and event.otherElement == 3 then local dX, dY = other:getLinearVelocity() other:setLinearVelocity(dX, -dY) self:dispatchEvent{name = 'Stomp'} timer.performWithDelay(350, function() self:removeSelf() end) end end
We distinguished between two different sorts of collision between the same pair of bodies, by using multiple sensors within a single body.
Collision events also include x and y fields, which specify the point where the colliding bodies made contact. These also offer a way to check the particulars of a collision; however, at the time of this writing, there was a Corona bug affecting the coordinates reported in this event. If this seems like a simpler way to process your collision events, check the Corona update logs to see if this is now reporting reliably.
3.144.230.82