Page 1 of 1

Love.physics hit detection question

Posted: Mon Sep 01, 2014 12:31 pm
by PartyCow
Hey!

I'm trying to make a 'bullet' (body) disappear when it hits anything, but nothing seems to happen.

Bullet is created in the mouseclick event, hit detection in the beginConctact event.
The bullet name is object.block9.

main.love attached.

Re: Love.physics hit detection question

Posted: Mon Sep 01, 2014 1:51 pm
by bdjnk
PartyCow wrote:I'm trying to make a 'bullet' (body) disappear when it hits anything, but nothing seems to happen.
Here's the essential reason: In beginCollision you are comparing fixtures (a and b) to a table you created (objects.block9), which will always be false. Even correcting for that, you still have an issue because you are attempting to destroy the fixtures, not the bodies. See Body:destroy. This is less wrong:

Code: Select all

if objects.block9 then
  if a == objects.block9.fixture then
    a:getBody():destroy()
  end
  if b == objects.block9.fixture then
    b:getBody():destroy()
  end
end
Unfortunately, these are the least of your issues. This still won't work, but try and see if you can fix the additional problems on your own.

Re: Love.physics hit detection question

Posted: Mon Sep 01, 2014 5:53 pm
by PartyCow
Thanks, the above works.

Although running into 2 problems now:
The problem now is that is crashes whenever it hits something because the draw is trying to use something that doesn't exsist.
Now the way to fix this sounds simple, remove it from the table when you remove it. Although I don't know how I would do this without clearing the objects.block9 table...

Secondly, only the last object created is processed in the beginContact. I assume this can be fixed by making sub-tables in object9 containing the objects, but wouldn't that complicate the above issue?

Would appreciate some input on the best way to fix this!

Re: Love.physics hit detection question

Posted: Tue Sep 02, 2014 4:51 am
by bdjnk
PartyCow wrote:Running into two problems now:
  • The game crashes whenever a bullet hits something because the draw is trying to access a table that doesn't exist.
  • Only the last bullet created is processed in the beginContact.
These are actually one problem. Consider this: What is truly necessary to make sure beginContact handles all bullets? Solve that and you'll be just about done with the crashing problem as well.

I apologize for my oblique assistance. I'm trying to steer you away from being a help vampire and toward intellectual engagement.

Re: Love.physics hit detection question

Posted: Tue Sep 02, 2014 11:23 pm
by bdjnk
Okay, I feel bad I left you hanging. Hopefully you've already figured it all out, but just in case you're stuck, here are the alterations I made to get everything working as you'd expect.

Code: Select all

function love.mousepressed(button)
  local ballx, bally = objects.ball.body:getPosition()
  local mx, my = love.mouse.getPosition()
  local angle = math.atan2(my - bally, mx - ballx)
        
  local bullet = {}
  table.insert(bullets, bullet)
        
  bullet.shape = love.physics.newCircleShape(1.5)
        
  bullet.body = love.physics.newBody(world, ballx+(math.cos(angle)*12), bally+(math.sin(angle)*12), "dynamic")
  local shotx, shoty = bullet.body:getPosition()
  bullet.body:applyLinearImpulse((shotx-ballx)/50,(shoty-bally)/50)
        
  bullet.fixture = love.physics.newFixture(bullet.body, bullet.shape, 2)
  bullet.fixture:setRestitution(1)
end

function beginContact(a, b, coll)
  for i = #bullets, 1, -1 do
    local bullet = bullets[i]
    if not bullet then break end
    if a == bullet.fixture then
      a:getBody():destroy()
      table.remove(bullets, i)
    end
    if b == bullet.fixture then
      b:getBody():destroy()
      table.remove(bullets, i)
    end
  end
end
A few words of explanation. In beginContact I need to check all bullets for collision. We start at the end of our bullets array so we can table.remove in peace (without having to jigger the indexes). In love.mousepressed we create a bullet table, add it to our bullets array, and initialize it with box2d nonsense.

Sometimes the problem with code is the way functionality gets added ad hoc. You become convinced you need something you added for some reason days or weeks ago, when in fact it's just gumming up the works.