## Hardon Collider - getting stuck between tiles

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

Sorry about that, rar is faster for me, as I use WinRAR to zip files. This one should work correctly.

And no, I've tried it with 32x32 shape as well, it still didn't work. Also, both vertical and horizontal collisions don't work if the guy is colliding with more than one tile.
Attachments
game.love
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....
paritybit
Citizen
Posts: 53
Joined: Thu Sep 06, 2012 3:52 am

### Re: Hardon Collider - getting stuck between tiles

luaz wrote:Also, both vertical and horizontal collisions don't work if the guy is colliding with more than one tile.
I think that might answer your question about what's wrong. If you're colliding with multiple tiles, you're probably hitting the collision callback multiple times. The first time you hit it, the minimum translation vector will be right, but the second time you hit it you'll already be out of the collision -- if you translate by the vector for collision with the second tile then you'll be moving twice as far away as you need to be. That would account for the jumpiness. I'm not sure I have a solution though. Maybe you can keep track of movement that was a correction based on collision detection so that you don't re-do it. That is, somehow keep track of all the minimum translation vectors rather than acting on them in the callback, and then act on the maximum X and maximum Y values during the update?

If I'm completely off in my analysis, I think somebody will correct me. Seems like this is an awful lot of work.
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

paritybit wrote:
luaz wrote:Also, both vertical and horizontal collisions don't work if the guy is colliding with more than one tile.
I think that might answer your question about what's wrong. If you're colliding with multiple tiles, you're probably hitting the collision callback multiple times. The first time you hit it, the minimum translation vector will be right, but the second time you hit it you'll already be out of the collision -- if you translate by the vector for collision with the second tile then you'll be moving twice as far away as you need to be. That would account for the jumpiness. I'm not sure I have a solution though. Maybe you can keep track of movement that was a correction based on collision detection so that you don't re-do it. That is, somehow keep track of all the minimum translation vectors rather than acting on them in the callback, and then act on the maximum X and maximum Y values during the update?

If I'm completely off in my analysis, I think somebody will correct me. Seems like this is an awful lot of work.
I had a somewhat similar idea, but I couldn't think of the solution, I still can't, apparently.

One more thing (not the main question!): I can't figure out what's objB, as ctile doesn't seem to work...
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

### Re: Hardon Collider - getting stuck between tiles

I think I had the same problem as you. This is how I resolved it:

Code: Select all

function on_collide(dt, shape_a, shape_b, mtv_x, mtv_y) -- collision callback
local _, y1 = shape_a:center()
local _, y2 = shape_b:center()
local _, top1, _, bottom1 = shape_a:bbox()
local _, top2, _, bottom2 = shape_b:bbox()

if bottom1 - 3 <= top2 then
mtv_x = 0
end
local total = shape_a.lightness + shape_b.lightness
local afrac = shape_a.lightness / total
local bfrac = -shape_b.lightness / total
if shape_a == player then
if mtv_x > 0 then
if mtv_x * afrac > playermoved.xmax then
playermoved.xmax = mtv_x * afrac
end
else
if mtv_x * afrac < playermoved.xmin then
playermoved.xmin = mtv_x * afrac
end
end
if mtv_y > 0 then
if mtv_y * afrac > playermoved.ymax then
playermoved.ymax = mtv_y * afrac
end
else
if mtv_y * afrac < playermoved.ymin then
playermoved.ymin = mtv_y * afrac
end
end
else
shape_a:move(mtv_x * afrac, mtv_y * afrac)
end
shape_b:move(mtv_x * bfrac, mtv_y * bfrac)
end


Code: Select all

function love.update(dt)
playermoved = {xmax = 0, xmin = 0, ymax = 0, ymin = 0}
HC:update(dt)
player:move(playermoved.xmin + playermoved.xmax, playermoved.ymin + playermoved.ymax)
end
Please don't try to copy this exactly, that won't work for you.
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

Some comments would be nice: I'm unsure what the underscores are, what lightness is, what afrac and bfrac is, and the rest of the code, I think I probably can read.
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

### Re: Hardon Collider - getting stuck between tiles

The underscores are for values I ignore. It's not a feature of Lua, but a common convention (and an actual feature of some other languages, like Haskell(?) and Go).

lightness is a property I assigned to shapes to deal with different mass. Fixed platforms have a lightness of 0.

afrac and bfrac are the fraction of the displacement that should be given to shape_a and shape_b respectively: if a small rock bumps into the moon, the rock should move more than the moon as a consequence of the collision.
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

Well I've attempted to tinker with it a little, but I don't even know how to get the shape to move. I think you have a different movement code perhaps. I'm not sure, but I'm also not sure about the code given. I will continue tinkering with it, but I doubt I'll get it to work, as I'm still confused about the code provided.
Attachments
game.love
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....
paritybit
Citizen
Posts: 53
Joined: Thu Sep 06, 2012 3:52 am

### Re: Hardon Collider - getting stuck between tiles

@luaz

Attached is a working code solution for how to do it the way I suggested; this basically keeps track of all the translation vectors for collision and then using the maximum x and y values to form a 'comprehensive vector' (for lack of a real term, I made it up) that covers all of the collisions with one vector. It will work fine for a tile-based solution like you have.

There were to basic changes to your original code. The first was the collision callback function:

Code: Select all

function colTrue(dt, objA, objB, x, y)
if(objA == player.colRect) then
table.insert(player.translationVectors, {x = x, y = y})
end
end

Instead of applying a change, you can see it inserts the translation vector (as a table with an x and y value) into a table called player.translationVectors. The next step is to use this table in the update, so I added the following code after the collision detection update (col:update()):

Code: Select all

local x = 0
local y = 0
for _, vector in ipairs(player.translationVectors) do
if math.abs(x) < math.abs(vector.x) then x = vector.x end
if math.abs(y) < math.abs(vector.y) then y = vector.y end
end

player.x = player.x + x;
player.y = player.y + y;
player.colRect:moveTo(player.x + player.width / 2, player.y + player.height / 2)
player.translationVectors = { }

This is basically getting the largest x and y values that exist in any vector in the table and using them to 'correct' the player's position.

I also added a function to draw the collision detection boxes (because I was having some weird issues); this might come in handy sometime so I left it there.

Code: Select all

local function drawBoxes()
local r, g, b, a = love.graphics.getColor()
love.graphics.setColor(0, 255, 0, 255)
for _, shape in pairs(col:shapesInRange(0, 0, love.graphics.getWidth(), love.graphics.getHeight())) do
shape:draw('line')
end
player.colRect:draw('line')
love.graphics.setColor(r, g, b, a)
end

There's still a little bit of 'stickiness' if you hold the down and left or right while moving across the top of the wall tiles -- this is because you have multiple collision boxes instead of a single collision box for the whole wall. It's probably not an issue, but there are some solutions for this here. I'm sure I saw a thread about a minimum set of bounding boxes given a tiled map, but I can't find it now.
Attachments
solution.love
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

I appreciate the answer, it works now indeed! However, the stickiness problem that you've mentioned is a problem. Sometimes the player won't move when they key is being held down (for some reason, this happens more when the player's top is colliding rather than the bottom, maybe just pure chance).

I think there should be taken a completely different approach. I checked out the source of other games, but I couldn't remake the code for myself, as first of all I don't understand the whole code, and secondly I have trouble with learning from references or abstract references. Ironic, as I have abstract ideas.

The thing is, there are other projects who've made this work perfectly fine, even with the same tools. Which means the approach is likely not right.

---

I have been tinkering around with the code given previously, I couldn't make anything that works good from it. I'm gonna try to tinker with this code. Maybe something good will come out of it, but I doubt it for the very same reason mentioned in the previous post.
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....
luaz
Citizen
Posts: 83
Joined: Sun Sep 16, 2012 2:55 pm

### Re: Hardon Collider - getting stuck between tiles

Seems like this thread has been abandoned. I'm still unable to solve the problem. I've been only able to make it so that the character gets stuck, just like it does in the one made by parytibit. I cannot manage to make a smooth collision between the tiles and the player...
If you're going to reply to my post, consider posting an (preferably working) example - 99.7% of time time, I already know how to implement the feature theoretically! I don't learn very well from references, etc....

### Who is online

Users browsing this forum: Google [Bot] and 28 guests