Collision help!

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.
Post Reply
User avatar
Miken1
Prole
Posts: 42
Joined: Tue Nov 05, 2013 8:35 am
Location: Sweden

Collision help!

Post by Miken1 »

Trying to make a game where you are suppose to jump on some boxes that are falling from the sky and try to get as far up as possible but I've ran into some problems with the whole collision bit.

Code: Select all

  function spawnObjects(x, y, width, height, yvel, gravity)
    local newObject = {x = x, y = y, width = width, height = height, yvel = yvel, gravity = gravity}
      
  table.insert(objects,newObject)
  objects.count = objects.count + 1
  return newObject
  
end


This is my function to create a box and I put everything in a table, but here is the problem, how can I make two objects in the table collide with each other?

Bonus question: how do I make the objects collide with the player?
bonus bonus question: How do I make the objects know if they are falling directly on the players head?


Thanks! :D
Attachments
Project.love
(21.16 KiB) Downloaded 86 times
User avatar
Miken1
Prole
Posts: 42
Joined: Tue Nov 05, 2013 8:35 am
Location: Sweden

Re: Collision help!

Post by Miken1 »

Maybe use an index?

Code: Select all

function spawnObjects(x, y, width, height, yvel, gravity)

    local newObject = {
        x = x,
        y = y,
        width = width,
        height = height,
        yvel = yvel,
        gravity = gravity,
        index = objects.count
        }
       
  table.insert(objects,newObject)
  objects.count = objects.count + 1
  return newObject
  
end
something like that?
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Collision help!

Post by ivan »

Code: Select all

  table.insert(objects,newObject)
  objects.count = objects.count + 1

for numerically indexed tables, objects.count == #objects
Miken1 wrote:This is my function to create a box and I put everything in a table, but here is the problem, how can I make two objects in the table collide with each other?

Code: Select all

for i = 1, #objects do
  local o1 = objects[i]
  for j = i + 1, #objects do
    local o2 = objects[j]
    -- test and resolve collisions between o1 and o2 (do not remove o1 or o2 from the list at this point)
  end
end
This iteration method is generally designed for moving objects. If you have static objects that do not move, you don't need to check for collisions between them.
If you have a callback during the collision step, you may want to iterate in reverse ("for i = #objects, 1, -1 do" and "for j = i - 1, 1, -1 do") so you can safely remove o1 or o2 from the list. Edit: Looking the code again: you have to break the inner loop right after destroying o1. Destroying o2, would shift the index of o1 so you generally want to avoid destroying either during the iteration.
Notice that the number of collision checks increases exponentially so if you have a lot of moving objects you may have to use some sort of space partitioning.
If you don't know how to resolve collisions, take a look at my humble tutorials: http://2dengine.com/doc_1_3_10/gs_collision.html and http://2dengine.com/doc_1_3_10/gs_intersection.html
Miken1 wrote:Bonus question: how do I make the objects collide with the player?
Generally, you want to treat the player just as another collision object so it shouldn't be a special case.
Miken1 wrote:bonus bonus question: How do I make the objects know if they are falling directly on the players head?
When resolving collisions you will have to find the "collision normal" or the "shortest separation vector".

Code: Select all

function oncollide(o1, o2, nx, ny)
  -- check for a player vs box collision
  if o1 == player then
    player_vs_box(o1, o2, nx, ny)
  elseif o2 == player then
    -- rotate the collision normal 180 degrees
    player_vs_box(o2, o1, -nx, -ny)
  end
end

function player_vs_box(player, box, nx, ny)
    -- check the y-axis of the collision normal
    if ny < 0 then
      -- player collided with an object that is pushing down
    end 
end
User avatar
Miken1
Prole
Posts: 42
Joined: Tue Nov 05, 2013 8:35 am
Location: Sweden

Re: Collision help!

Post by Miken1 »

ivan wrote:

Code: Select all

  table.insert(objects,newObject)
  objects.count = objects.count + 1

for numerically indexed tables, objects.count == #objects
Miken1 wrote:This is my function to create a box and I put everything in a table, but here is the problem, how can I make two objects in the table collide with each other?

Code: Select all

for i = 1, #objects do
  local o1 = objects[i]
  for j = i + 1, #objects do
    local o2 = objects[j]
    -- test and resolve collisions between o1 and o2 (do not remove o1 or o2 from the list at this point)
  end
end
This iteration method is generally designed for moving objects. If you have static objects that do not move, you don't need to check for collisions between them.
If you have a callback during the collision step, you may want to iterate in reverse ("for i = #objects, 1, -1 do" and "for j = i - 1, 1, -1 do") so you can safely remove o1 or o2 from the list. Edit: Looking the code again: you have to break the inner loop right after destroying o1. Destroying o2, would shift the index of o1 so you generally want to avoid destroying either during the iteration.
Notice that the number of collision checks increases exponentially so if you have a lot of moving objects you may have to use some sort of space partitioning.
If you don't know how to resolve collisions, take a look at my humble tutorials: http://2dengine.com/doc_1_3_10/gs_collision.html and http://2dengine.com/doc_1_3_10/gs_intersection.html
Miken1 wrote:Bonus question: how do I make the objects collide with the player?
Generally, you want to treat the player just as another collision object so it shouldn't be a special case.
Miken1 wrote:bonus bonus question: How do I make the objects know if they are falling directly on the players head?
When resolving collisions you will have to find the "collision normal" or the "shortest separation vector".

Code: Select all

function oncollide(o1, o2, nx, ny)
  -- check for a player vs box collision
  if o1 == player then
    player_vs_box(o1, o2, nx, ny)
  elseif o2 == player then
    -- rotate the collision normal 180 degrees
    player_vs_box(o2, o1, -nx, -ny)
  end
end

function player_vs_box(player, box, nx, ny)
    -- check the y-axis of the collision normal
    if ny < 0 then
      -- player collided with an object that is pushing down
    end 
end
Thanks alot!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 3 guests