Solving Collisions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
Refpeuk
Citizen
Posts: 91
Joined: Wed Dec 14, 2011 6:16 pm

Solving Collisions

Post by Refpeuk » Mon Feb 27, 2012 1:44 am

Hi Guys,

This just as much a lua question as it is a love one; I'm trying to solve my hardon collider collision callbacks (and by this I don't mean it as in solving a problem, but knowing what to do with it)

I'm making a platformer and originally had it so that it would simply set player y velocity and acceleration to 0, but this resulted in some pretty nasty tunneling. I'm guessing the best way would be to set my playerY to the origin y of the rectangle it's collided with, but I'm not quite sure how. Hardoncollider returns the shapes that have been collided, and I keep all my values in tables where the same number in each refers to the same shape. So for example it returns playershape and objects.shape[4], then I want to be able to put the 4 into a variable like "i" so I can do something like:

playerY = objects.Y

How can I do this in lua, or is there a better way to solve my collisions without tunneling.

Thanks!
It was the best of times, it was the worst of times . . .

User avatar
thelinx
The Strongest
Posts: 847
Joined: Fri Sep 26, 2008 3:56 pm
Location: Sweden

Re: Solving Collisions

Post by thelinx » Mon Feb 27, 2012 1:53 am

HardonCollider also returns the "minimum translation vector", which will help you solve collisions. Search this forum, and you're sure to find more info on it.

User avatar
Refpeuk
Citizen
Posts: 91
Joined: Wed Dec 14, 2011 6:16 pm

Re: Solving Collisions

Post by Refpeuk » Mon Feb 27, 2012 1:57 am

Awesome, thanks: way better than what I wanted to do!
It was the best of times, it was the worst of times . . .

User avatar
molul
Party member
Posts: 264
Joined: Sun Feb 05, 2012 6:51 pm
Location: Valencia, Spain
Contact:

Re: Solving Collisions

Post by molul » Mon Feb 27, 2012 9:30 am

Hmmm I'm curious about this. I've programmed my own collisions detection functions, only between the player and the ground. I planned to use it for all the enemies as well, and then use hardoncollider for collisions between the player and the enemies, but I wonder if my approach is wrong. Should I use hardoncollider for the collisions between the player and enemies withthe map too?

User avatar
Refpeuk
Citizen
Posts: 91
Joined: Wed Dec 14, 2011 6:16 pm

Re: Solving Collisions

Post by Refpeuk » Mon Feb 27, 2012 6:18 pm

Hmm, now I've got another problem, though . . .

This is what my on_col callback looks like:

Code: Select all

function on_collide(dt, shape_a, shape_b, mtvx, mtvy)
  if shape_a == player.col.feet or shape_b == player.col.feet then
    player.velocity.y = 0
    playerY = playerY - mtvy

    jumpallowed = jumpallowed + 1
  end
end
But for some reason it's being called every frame instead of just when the collision begins, causing my jumpallowed variable to keep counting up. I checked to be sure that the off collision callback was working properly, and it is only being called when the collision ends like it's supposed to. What am I doing wrong?
It was the best of times, it was the worst of times . . .

Zeliarden
Party member
Posts: 139
Joined: Tue Feb 28, 2012 4:40 pm

Re: Solving Collisions

Post by Zeliarden » Tue Feb 28, 2012 4:46 pm

Should probably be
jumpallowed = 1
instead of
jumpallowed = jumpallowed + 1

User avatar
Refpeuk
Citizen
Posts: 91
Joined: Wed Dec 14, 2011 6:16 pm

Re: Solving Collisions

Post by Refpeuk » Wed Feb 29, 2012 12:03 am

That's what I used to do. Unfortunately that caused several issues when moving from one block to another (eg: walking) where you would start colliding with the second block before stopping with the first. I think I've worked out a better way now.

I would still love to know how to determine the index of a returned variable, though. I keep all my collision objects in a table, so I'd like to be able to take "shape_a" which would be something like objects.col[9] and extract the 9 to an int variable so that I could use it to keep track of exactly which object has collided when working with a large number of them.

I don't know if I'm making sense . . . should I rephrase this? Does anyone understand what I mean?
It was the best of times, it was the worst of times . . .

User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Solving Collisions

Post by kikito » Wed Feb 29, 2012 12:25 am

Refpeuk wrote:I don't know if I'm making sense . . . should I rephrase this? Does anyone understand what I mean?
I think I understand - you are using integers to index object in a table, and suddenly you need the integer given the object.

One option is to parse the table with a for - when you find the object, you have found the index. It's a bit slow, but if you don't need the index very often, it might be just enough.

Another option is to use the object themselves as keys, instead of integers!

Instead of doing this:

Code: Select all

objects[#objects + 1] = newObject -- insertion
...
for i=1,#objects do -- treatment
  treatObject(objects[i])
end
...
-- deletion
table.remove(objects, 5) -- how do I get the 5?
Consider doing this:

Code: Select all

objects[newObject] = true -- insertion
...
for object,_ in pairs(objects) do -- treatment
  treatObject(object)
end
...
objects[object] = nil -- deletion
This will make every parse of objecs a bit slower, but you will not have that "what key is this object" problem ... each object will be its own key.
When I write def I mean function.

User avatar
Refpeuk
Citizen
Posts: 91
Joined: Wed Dec 14, 2011 6:16 pm

Re: Solving Collisions

Post by Refpeuk » Wed Feb 29, 2012 12:31 am

If I understand you correctly you mean I don't need to use an integer to index a table; I could use my collision shape themselves as indexes for other tables.

Eg :

Code: Select all

objects.shape[i] = collider:addRectangle(objects.x[i], objects.y[i], objects.width[objects.type[i]], objects.height[objects.type[i]])
bool.collided[objects.shape[i]] = 1
Does this mean there's no way to actually find the index other than looping through it? There must be a simpler way, considering I would need to do it every frame for each object that is colliding.
It was the best of times, it was the worst of times . . .

User avatar
MarekkPie
Inner party member
Posts: 587
Joined: Wed Dec 28, 2011 4:48 pm
Contact:

Re: Solving Collisions

Post by MarekkPie » Wed Feb 29, 2012 1:58 am

Run a few tests through Lua's interpreter to fully understand how tables and function on tables work:

Code: Select all

t = {"a", "b", "c"}
for key, value in ipairs(t) do -- loop iteratively
    print(key, value)
end
-- result
-- 1    a
-- 2    b
-- 3    c
If you don't specify any indexes, it gives them numeric indexes starting from 1. So, from your example, yes, you could add an item to a table like that, but the index wouldn't be the object reference, rather #table + 1. So essentially

Code: Select all

t = {"a", "b", "c"}

-- and

t = {}
t[#t + 1] = "a"
t[#t + 1] = "b"
t[#t + 1] = "c"

-- and

t = {1 = "a", 2 = "b", 3 = "c"}
are equivalent to the code in the first block. You can, however, use any of the primitive Lua types as an index (numbers, booleans, functions, strings, tables...maybe even userdata, but that requires using the C API, which I haven't ever touched.):

Code: Select all

t = {}
t[#t + 1] = "a"
t[true] = "b"
t["index"] = "c"
t[function() end] = "d"
t[{}] = "e"
for key, value in pairs(t) do -- ipairs only works if all the indexes are numerical
    print(type(key), value)
end

-- result (in some order):
number   a
boolean  b
string   c
function d
table    e

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], MrFariator and 14 guests