Hardon Collider problem on restart
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Hardon Collider problem on restart
Hello, everyone !
I'm actually trying to create a simple platformer using HardonCollider.
Basically, I'd need to get the collision sides for the function I'm implementing. This said, I was thinking about doing some comparison between the mtv_x et mtv_y values that are passed in the collision callback. Unfortunately, this vector is not displayed properly at all. I was not expecting empty values, is this a bug or me doing something wrong ?
https://www.dropbox.com/s/glsd6xwzcag7u ... .love?dl=1
Thanks in advance for your answers, and have a nice evening.
I'm actually trying to create a simple platformer using HardonCollider.
Basically, I'd need to get the collision sides for the function I'm implementing. This said, I was thinking about doing some comparison between the mtv_x et mtv_y values that are passed in the collision callback. Unfortunately, this vector is not displayed properly at all. I was not expecting empty values, is this a bug or me doing something wrong ?
https://www.dropbox.com/s/glsd6xwzcag7u ... .love?dl=1
Thanks in advance for your answers, and have a nice evening.
Last edited by Ulydev on Tue Jul 14, 2015 12:44 pm, edited 1 time in total.
Re: Hardon Collider "resolve vector" behaving strangely
I found a simple temporary "fix", using Minkowski's algorithm.
Here's the Lua implementation
If someone got a cleaner workaround, though, please share it !
Here's the Lua implementation
Code: Select all
function getCollisionSide(A, B)
local side = 1 --1 down - 2 left - 3 up - 4 right
local x1, y1 = A:center()
local x2, y2 = B:center()
local w = 0.5 * (A.width + B.width);
local h = 0.5 * (A.height + B.height);
local dx = x1 - x2;
local dy = y1 - y2;
local wy = w * dy
local hx = h * dx
if (wy > hx) then
if (wy > -hx) then
side = 3
else
side = 2
end
else
if (wy > -hx) then
side = 4
else
side = 1
end
end
return side
end
Re: Hardon Collider "resolve vector" behaving strangely
Hi, it's me again ! I've got another problem / question that I prefer to ask here rather than opening a new thread.
I have two players (with their own collider) that can jump on each other's head. But there's always a "victim" which is not allowed to jump on the other's head and pushes it instead. Just like in this gif :
The "victim" always changes when I restart the game. Here's my collision manager :
I really don't understand what happens here... Thank you in advance for your help
I have two players (with their own collider) that can jump on each other's head. But there's always a "victim" which is not allowed to jump on the other's head and pushes it instead. Just like in this gif :
The "victim" always changes when I restart the game. Here's my collision manager :
Code: Select all
function touchGround(obj)
obj.ref.isGrounded = true
obj.ref.isJumping = false
end
function stopTouchingGround(obj)
obj.ref.isGrounded = false
end
function getCollisionSide(A, B, mtv_x, mtv_y)
local side = 1 --1 down - 2 left - 3 up - 4 right
local x1, y1 = A:center()
if mtv_x then x1, y1 = x1 + mtv_x, y1 + mtv_y end
local x2, y2 = B:center()
local w = 0.5 * (A.width + B.width);
local h = 0.5 * (A.height + B.height);
local dx = x1 - x2;
local dy = y1 - y2;
local wy = w * dy
local hx = h * dx
if (wy > hx) then
if (wy > -hx) then
side = 3
else
side = 2
end
else
if (wy > -hx) then
side = 4
else
side = 1
end
end
return side
end
function onCollide(dt, obj1, obj2, mtv_x, mtv_y)
if obj1.name == "player" or obj2.name == "player" then
--player is always refered as "obj1"
if obj2.name == "player" then local tObj = obj1; obj1 = obj2; obj2 = tObj; mtv_y = -mtv_y+0.001; mtv_x = -mtv_x end
local collisionSide = Gravity:convertCollisionSide(getCollisionSide(
obj1,
obj2,
mtv_x,
mtv_y), obj1.ref.gravity) --1 down - 2 left - 3 up - 4 right
mtv_x = mtv_x - math.sign(mtv_x)*0.005
mtv_y = mtv_y - math.sign(mtv_y)*0.005
local x1, y1 = obj1:center()
local x2, y2 = obj2:center()
print(collisionSide)
if collisionSide == 1 then
if obj2.name == "player" then
obj1.ref:jump("bump")
else
obj1:move(mtv_x, mtv_y)
touchGround(obj1)
end
elseif collisionSide == 2 or collisionSide == 4 then
obj1:move(mtv_x, mtv_y)
if Gravity:getAxis(obj1.ref.gravity) == "y" then obj1.ref.velocity.x = 0 else obj1.ref.velocity.y = 0 end
elseif collisionSide == 3 then
obj1:move(mtv_x, mtv_y)
if Gravity:getAxis(obj1.ref.gravity) == "y" then obj1.ref.velocity.y = 0 else obj1.ref.velocity.x = 0 end
end
end
end
function onStopCollide(dt, obj1, obj2)
if obj1.name == "player" or obj2.name == "player" then
if obj2.name == "player" then local tObj = obj1; obj1 = obj2; obj2 = tObj end
local collisionSide = Gravity:convertCollisionSide(getCollisionSide(obj1, obj2), obj1.ref.gravity) --1 down - 2 left - 3 up - 4 right
print("end collision side : "..collisionSide)
--if collisionSide == 1 then
stopTouchingGround(obj1)
--end
end
end
- DaedalusYoung
- Party member
- Posts: 407
- Joined: Sun Jul 14, 2013 8:04 pm
Re: Hardon Collider "resolve vector" behaving strangely
I didn't really look at your code, so I don't know what's causing your issue, but I just wanted to point out that this:
can be written easier like this:Ulydev wrote:Code: Select all
local tObj = obj1; obj1 = obj2; obj2 = tObj;
Code: Select all
obj1, obj2 = obj2, obj1 -- swaps obj1 and obj2
Re: Hardon Collider "resolve vector" behaving strangely
Thanks, that's appreciatedcan be written easier like this:Code: Select all
obj1, obj2 = obj2, obj1 -- swaps obj1 and obj2
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: Hardon Collider problem on restart
First: Can you upload a .love file? that would be appreciated since it will make the problem clearer, I cant know what obj1 and obj2 are if I cant take a look at other parts of the code
Any way I have some ideas of what could be happening my first option is that both obj1 and obj2 are "player" so obj2 is the only one that can handle the collisions, my second option is pretty similar, basically you are not handling what happens if what you suppose is the "victim" is actually the "perpetrator" (that is, the one jumping on top of the other is the "victim") so the perpetrator which is not suppose to suffer a collision from the top just slides to the other side like if it was being moved
NOTE: The "victim" changes every time you start up the game because the order in which pairs traverses a table is not defined)
Any way I have some ideas of what could be happening my first option is that both obj1 and obj2 are "player" so obj2 is the only one that can handle the collisions, my second option is pretty similar, basically you are not handling what happens if what you suppose is the "victim" is actually the "perpetrator" (that is, the one jumping on top of the other is the "victim") so the perpetrator which is not suppose to suffer a collision from the top just slides to the other side like if it was being moved
NOTE: The "victim" changes every time you start up the game because the order in which pairs traverses a table is not defined)
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Re: Hardon Collider problem on restart
Thanks for your answer, Positive07.
You were right, I was able to fix the problem by handling the collision twice for each player. It's pretty ugly, but it works for now
You were right, I was able to fix the problem by handling the collision twice for each player. It's pretty ugly, but it works for now
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: Hardon Collider problem on restart
Cool! Could you show us the fix? Would be nice for future users that may stumble with the same issue
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Re: Hardon Collider problem on restart
Indeed !
Basically, every time you check collision between, say, side A and side B, you also have to check collision between side B and side A.
Code: Select all
if obj2.name == "player" then --both objects are players
local collisionSide2 = Gravity:convertCollisionSide(getCollisionSide(
obj2, obj1,
-mtv_x,
-mtv_y), obj2.ref.gravity) --get object 2 side (we already got object 1 side earlier)
if collisionSide == 1 then
if collisionSide2 == 1 then
obj1:move(mtv_x*.5, mtv_y*.5)
obj2:move(-mtv_x*.5, -mtv_y*.5)
else
obj1.ref:jump("bump")
obj2.ref:kill()
obj1:move(0, mtv_y*.5)
if not obj2.ref.isGrounded then
obj2:move(0, -mtv_y*.5)
end
end
--obj1:move(0, mtv_y)
--obj2:move(0, -mtv_y)
elseif collisionSide == 2 or collisionSide == 4 then
if collisionSide2 == 1 then
obj2.ref:jump("bump")
obj1.ref:kill()
elseif collisionSide2 == 3 then
obj1:move(mtv_x*.5, mtv_y*.5)
obj2:move(-mtv_x*.5, -mtv_y*.5)
else
obj1:move(mtv_x*.5, mtv_y*.5)
obj2:move(-mtv_x*.5, -mtv_y*.5)
end
--obj1.ref:jump("bump")
--obj2.ref:kill()
--local tempDir = boolInt(collisionSide == 2)*2-1
--obj1:move(mtv_x, 0)--mtv_y)
--obj2:move(-mtv_x, 0)--mtv_y)
elseif collisionSide == 3 then
--obj1:move(0, mtv_y)
--obj2:move(0, -mtv_y)
if collisionSide2 == 1 then
obj2.ref:jump("bump")
obj1.ref:kill()
obj2:move(0, -mtv_y*.5)
if not obj1.ref.isGrounded then
obj1:move(0, mtv_y*.5)
end
else
obj1:move(mtv_x*.5, mtv_y*.5)
obj2:move(-mtv_x*.5, -mtv_y*.5)
end
end
else --handle normal collision between player and object
- Positive07
- Party member
- Posts: 1014
- Joined: Sun Aug 12, 2012 4:34 pm
- Location: Argentina
Re: Hardon Collider problem on restart
Does this work? It should be the same, just a little bit cleaner
Code: Select all
function kill (killer, victim, move)
killer.ref:jump("bump")
victim.ref:kill()
if move then
killer:move(0, move * mtv_y*.5)
if not victim.ref.isGrounded then
victim:move(0, move * -mtv_y*.5)
end
end
end
function move (obj1, obj2)
obj1:move(mtv_x*.5, mtv_y*.5)
obj2:move(-mtv_x*.5, -mtv_y*.5)
end
if obj2.name == "player" then --both objects are players
local collisionSide2 = Gravity:convertCollisionSide(getCollisionSide(
obj2, obj1,
-mtv_x,
-mtv_y), obj2.ref.gravity) --get object 2 side (we already got object 1 side earlier)
if collisionSide == 1 then
if collisionSide2 == 1 then
move(obj1, obj2)
else
kill(obj1, obj2, 1)
end
elseif collisionSide == 2 or collisionSide == 4 then
if collisionSide2 == 1 then
kill(obj2, obj1)
elseif collisionSide2 == 3 then
move(obj1, obj2)
end
elseif collisionSide == 3 then
if collisionSide2 == 1 then
kill(obj2, obj1, -1)
else
move(obj1, obj2)
end
end
else --handle normal collision between player and object
for i, person in ipairs(everybody) do
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
[tab]if not person.obey then person:setObey(true) end
end
love.system.openURL(github.com/pablomayobre)
Who is online
Users browsing this forum: Bing [Bot] and 134 guests