## Merging Physics Objects

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
egg651
Prole
Posts: 5
Joined: Sun Apr 22, 2012 4:09 pm

### Merging Physics Objects

This weekend's Ludum Dare inspired me to get back to making games (tried once before ages ago in XNA but eventually fizzled out after being too ambitious), and love2d seems perfect for what I'm looking to achieve. My idea is for a game about planets which move around by ejecting mass and gain mass by smashing in to other planets/rocks - And this is where we get to my problem. What's the best way to implement planet growth? (Taking in to account I'm using love.physics for all my objects, and that currently they are all circular)

Source code can be found here, and the .love file is attatched.

P.S: Apologies for any ugly code, hopefully I can still use the 'lol I'm a newbie idiot' excuse.
P.P.S: As a random side question: Why does it restart itself multiple times on launch?
Attachments
GravityWells.love

Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

### Re: Merging Physics Objects

It's "restarting" itself multiple times because you keep calling love.graphic.setMode. That function is for changing the window size or fullscreen dimensions, so only call it once, or supply a conf.lua file that sets the window size you want. See: https://love2d.org/wiki/conf.lua

As for merging two object, at the time of collision you'll basically want to calculate the area of the two objects, add the area of the smaller to the larger, and then recalculate the radius of the larger object from its new area. That formula is R=sqrt(A/pi)

iemfi
Citizen
Posts: 52
Joined: Fri Mar 30, 2012 11:03 am

### Re: Merging Physics Objects

It looks like it's reloading because you use setMode 4 times! Do you know how to handle collisions? Wiki has a good tutorial on that. https://love2d.org/wiki/Tutorial:Physic ... nCallbacks

After you have the 2 objects colliding, you just need a function which merges them. You could simply use getMass() to find the smaller one and add the 2 masses together then use setMass() on the larger body and and setRadius() on the larger shape and destroy() on the smaller body. The hard part would be making it look good and making the smashing together look correct. For that you can play around with the restitution and maybe add your own forces when a collision is detected.

egg651
Prole
Posts: 5
Joined: Sun Apr 22, 2012 4:09 pm

### Re: Merging Physics Objects

iemfi wrote:It looks like it's reloading because you use setMode 4 times! Do you know how to handle collisions? Wiki has a good tutorial on that. https://love2d.org/wiki/Tutorial:Physic ... nCallbacks
Inny wrote:It's "restarting" itself multiple times because you keep calling love.graphic.setMode.
Ah! It seems that I accidentally copied it when duplicating the code to create the walls.

As for the main problem - I've set up the world callbacks, and written a small function to merge two balls. The new problem is that if I destroy the smaller body, the program crashes as it tries to update the body that no longer exists, since it is still in dynamicobjects. Is there an easy way to remove it from that array or will I have to search through it looking for the right ball?

Ninja edit: Updated code here.

iemfi
Citizen
Posts: 52
Joined: Fri Mar 30, 2012 11:03 am

### Re: Merging Physics Objects

I think you have to search through it, this is what I use.

Code: Select all

function deleteObject(tab,obj)
for i,v in ipairs(tab) do
if v==obj then
table.remove(tab,i)
return
end
end
end
ninja edit: The other way would be to keep track of the position of each ball in the table but I wouldn't bother with that unless you had a gazillion balls.

egg651
Prole
Posts: 5
Joined: Sun Apr 22, 2012 4:09 pm

### Re: Merging Physics Objects

Yeah, I figured as much - Was just wondering if there was some magical lua/love2d feature I was unaware of.

Anyway, I've implemented a basic linear search as suggested to remove the items from the table and have been left with one last bug - The objects radii increase as they should, but the circle drawn to the screen remains the same size.

[Updated code]

Edit 2: Solved the problem by changing the following line in love.draw:

Code: Select all

love.graphics.circle("fill", ball.body:getX(), ball.body:getY(), ball.shape:getRadius())
To this:

Code: Select all

love.graphics.circle("fill", ball.body:getX(), ball.body:getY(), ball.fixture:getShape():getRadius())
I don't know why it works, but it does.
Attachments
GravityWells.love

tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

### Re: Merging Physics Objects

egg651 wrote: Edit 2: Solved the problem by changing the following line in love.draw:

Code: Select all

love.graphics.circle("fill", ball.body:getX(), ball.body:getY(), ball.shape:getRadius())
To this:

Code: Select all

love.graphics.circle("fill", ball.body:getX(), ball.body:getY(), ball.fixture:getShape():getRadius())
Wow, that is... not lovely. The new Box2d API makes me sad.
Kurosuke needs beta testers

slime
Solid Snayke
Posts: 2858
Joined: Mon Aug 23, 2010 6:45 am
Contact:

### Re: Merging Physics Objects

In box2d 2.2, shapes created by the user are prototypes. When you create a fixture and pass a shape in as an argument, box2d internally clones the shape and attaches the cloned shape to the fixture. I don't think that's unlovely, it's just.. different. It means that if your game uses a lot of the same shape with the same dimensions for different objects, you only need to create one and box2d will do the rest for you when you make fixtures.

egg651
Prole
Posts: 5
Joined: Sun Apr 22, 2012 4:09 pm

### Re: Merging Physics Objects

Ah, I see. Using that knowledge, I've changed the ball creation code to this:

Code: Select all

function GenerateBalls(count)
for i=0,count - 1 do
ball = {}
ball.body = love.physics.newBody(world, math.random(650), math.random(650), "dynamic")
ball.fixture = love.physics.newFixture(ball.body, love.physics.newCircleShape(math.random(5, 60)) , planetdensity)
ball.shape = ball.fixture:getShape()
ball.fixture:setRestitution(planetrestitution)
ball.r = math.random(255)
ball.g = math.random(255)
ball.b = math.random(255)
end