Love.physics hit detection question

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
PartyCow
Prole
Posts: 18
Joined: Sat Nov 17, 2012 3:12 pm

Love.physics hit detection question

Post by PartyCow » Mon Sep 01, 2014 12:31 pm

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.
Attachments
main.love
(3.22 KiB) Downloaded 49 times

User avatar
bdjnk
Citizen
Posts: 81
Joined: Wed Jul 03, 2013 11:44 pm

Re: Love.physics hit detection question

Post by bdjnk » Mon Sep 01, 2014 1:51 pm

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.

PartyCow
Prole
Posts: 18
Joined: Sat Nov 17, 2012 3:12 pm

Re: Love.physics hit detection question

Post by PartyCow » Mon Sep 01, 2014 5:53 pm

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!

User avatar
bdjnk
Citizen
Posts: 81
Joined: Wed Jul 03, 2013 11:44 pm

Re: Love.physics hit detection question

Post by bdjnk » Tue Sep 02, 2014 4:51 am

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.

User avatar
bdjnk
Citizen
Posts: 81
Joined: Wed Jul 03, 2013 11:44 pm

Re: Love.physics hit detection question

Post by bdjnk » Tue Sep 02, 2014 11:23 pm

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.

Post Reply

Who is online

Users browsing this forum: No registered users and 42 guests