Here's how I've made it. I've set the jumpable bodies' user data to "jumpable", to indicate which bodies can be jumped on. On second thought, maybe I could have used the fixtures, but it's OK like this if you have just one fixture per body.
Code: Select all
objects.ground.body:setUserData("jumpable")
I also got rid of objects.square which isn't very helpful. The loop for the platform shapes now looks like this:
Code: Select all
for y=1, #map do
for x=1, #map[y] do
if map[y][x] == 1 then
local body = love.physics.newBody(world,(x * 64) - 32 , (y * 64) - 32) --Creates the square body objects to create the map
body:setUserData("jumpable")
local shape = love.physics.newRectangleShape(64, 64) --Creates the square shape of size X=64, Y=64
love.physics.newFixture(body, shape, 1) --Fixes the square body and shape together
end
end
end
Note the body:setUserData("jumpable").
And this is how the jump key handler ended up looking like:
Code: Select all
if love.keyboard.isDown("w") then
local canJump = false
if objects.rectangle.body:isTouching(objects.ground.body) then
-- TODO: check normal
canJump = true
else
local contacts = objects.rectangle.body:getContacts()
for k,v in pairs(contacts) do
if v:isTouching() then
local f1, f2 = v:getFixtures()
local nx, ny = v:getNormal()
local groundCheck = ny < 0
local b = f1:getBody()
if b == objects.rectangle.body then
b = f2:getBody()
groundCheck = ny > 0
end
if b:getUserData() == "jumpable" then
if groundCheck and nx == 0 then
canJump = true
break
end
end
end
end
end
if canJump then
objects.rectangle.body:applyForce(0, -800)
end
end
Basically, go through all the contacts to see if one of the contacts is with a fixture whose body is marked as jumpable, and has a normal that makes sense for a ground jump. Note that this check disables the ability to jump on walls; if you want that, you'll have to change the normal check.
The getting stuck on borders is a common problem, even more with Box2D. I've tried making a capsule-shaped player, but then you get small bounces:
Code: Select all
objects.rectangle.shape1 = love.physics.newRectangleShape(14, 16) --Creates the rectangle shape of size X=20, Y=50
objects.rectangle.shape2 = love.physics.newCircleShape(0, -8, 8) --Creates the circle shape of radius 8
objects.rectangle.shape3 = love.physics.newCircleShape(0, 8, 8) --Creates the circle shape of radius 8
objects.rectangle.fixt1 = love.physics.newFixture(objects.rectangle.body, objects.rectangle.shape1, 1) --Fixes the rectangle body and shape together
objects.rectangle.fixt2 = love.physics.newFixture(objects.rectangle.body, objects.rectangle.shape2, 1) --Fixes the circle shape and body together
objects.rectangle.fixt3 = love.physics.newFixture(objects.rectangle.body, objects.rectangle.shape3, 1) --Fixes the circle shape and body together