Top down physics explosions, zero gravity

Hey all! I’m not super into the physics side of Corona, but I get the basics.

First off, it’s not ‘zero G outer space’ explosion.

I have the overhead view of a Ye Olde Tavern, so you see straight down on to some tables and chairs. The tables and chairs are physics objects, with varying densities and frictions.

OK cool.

I wanted to be able to place explosions (for testing, by just tapping on the screen) and have the explosions affect the furniture and blow it away from the explosions. That’s why I have the gravity set as 0, too.

How would I best achieve this? My first thought is to take the location of the tap, check a radius around it to see if any furniture is in range of an arbitrary distance I choose, and then calculate the angle from each affected object to the origin of the explosion, and then apply a linear impulse to each of the affected pieces of furniture in the OPPOSITE direction of my explosion.

Any thoughts? I am famous for over-complicating things, which is why I come to you all first. :slight_smile:

Appreciate any help!

BTW to my US compatriots, happy 4th of July!! [import]uid: 11636 topic_id: 12005 reply_id: 312005[/import]

Your approach is correct.
Just make magnitude of your linear impulse is proportional to the distance of object from the center of explosion. [import]uid: 48521 topic_id: 12005 reply_id: 43834[/import]

Um…how the hell do I get rise over run to use for applyLinearImpulse from degrees?? John Beebe’s ‘getAngle’ is what I’m using and it returns degrees. :slight_smile: Wasn’t it math.tan? And using the whole number as the rise and the modulo remainder as the run? Too tired, crashing out now. I’ll see what Google says, but if anyone’s done this before I’d appreciate the help. [import]uid: 11636 topic_id: 12005 reply_id: 43846[/import]

what u said made no sense to me… [import]uid: 48521 topic_id: 12005 reply_id: 43847[/import]

[edited for horrible spelling on my part] Rise over run (y = mx + b) algebraic solution to get the linearImpulse needed.Also, known as slope.

As far as ‘beebegames.lua’ it’s the framework I’m using from the code exchange that has a built in 'object:getAngleTo(x,y) that returns the degree heading of a set of x,y coordinates

For future reference if anyone needs to get the rise over run from coordinates, you can check:

http://www.mathopenref.com/coordslope.html

I’ll post the finished example later! [import]uid: 11636 topic_id: 12005 reply_id: 43891[/import]

Hey I just made an example on (what I believe) you were trying to do. Here it is: http://www.mediafire.com/?4zm0wib0olhuhlb

Its based off a tutorial by Mobile Tuts Plus. The tutorial:
http://mobile.tutsplus.com/tutorials/corona/corona-sdk_physics_explosions/

Well anyways hope it helps. and if you still have questions ask away…

-Nick Homme [import]uid: 11769 topic_id: 12005 reply_id: 43961[/import]

you don’t need to resolve angle here…
suppose your explosion is at (x0,y0) and the object is at (x1,y1)
then the force you will apply will be inversely proportional to (x1-x0,y1-y0)

something like,
[lua]local F = 1000 – Force magnitude
object:applyLinearImpulse( F/(x1-x0), F/(y1-y0), object.x, object.y)[/lua]

Edit: I realized this will lead to huge force when objects are very near the explosion… so intead of dividing it by (x1-x0) and (y1-y0), you can just subtract by quantity proportional to them.
[import]uid: 48521 topic_id: 12005 reply_id: 43960[/import]

@Nick & @Chinmay!!

I was JUST at the point where you guys were at. Thanks for all the help so far.

Now like Chinmay mentioned however, we have an issue with the further away an object is from our tap event, the GREATER the force that is applied to it.

My question is now, how do we apply an inversely proportional amount of force the further away we are from the explosion origin? I’ve tried dividing the force, multiplying it…but I’m missing something like the inverse of the distance and then dividing that against the force on the axes?

Here’s the sample code with primitives and no graphics so anyone can jump in.

Also, I’ve become convinced that ‘friction’ does not a damned thing, and the only way you can get the objects to behave properly is to apply linear damping. :expressionless:

Here we go:

[code]

physics = require “physics”
physics.start()
physics.setDrawMode( “hybrid” )
physics.setGravity( 0, 0 )

furniture = {}

gameBoard = display.newGroup()
background = display.newRect(0,0,1024,1024)
background:setFillColor(0,175,50)
background:setReferencePoint(display.TopLeftReferencePoint)
background.x = 0
background.y = 0

function getDistanceTo( sourceX, sourceY, x, y )
– Returns distance (in pixels) from object’s location to given coordinates.
local theDistance = math.ceil(math.sqrt( ((y - sourceY) * (y - sourceY)) + ((x - sourceX) * (x - sourceX)) ))
return theDistance
end

function handleTouch(event) – still actually local
print(“touch:”…event.phase)
if “ended” == event.phase then
– Set an effect range that will check against
– all other pieces of furniture. If the furniture’s
– x and y location are within this range, then affect
– them with our 'splosion!
local range = 200
for i=1,#furniture do
local tempDistance = getDistanceTo(event.x,event.y,furniture[i].x,furniture[i].y)
if(tempDistance local tempX
local tempY
tempX = event.x - furniture[i].x
tempY = event.y - furniture[i].y
– Vary ‘force’ if you want to increase or decrease
– the force at which the pieces of furniture go flying
– local force = 1
local force = 1
– We put a negative sign in front of our tempX and tempY
– so the objects move AWAY from the event.x and y…
– If for some reason you wanted to ‘suck’ the objects
– TOWARDS the event.x and y, you’d take the negative sign
– off.
– Away…
furniture[i]:applyLinearImpulse( -tempXforce,-tempYforce,furniture[i].x,furniture[i].y)
– Towards…
--furniture[i]:applyLinearImpulse( tempXforce,tempYforce,furniture[i].x,furniture[i].y)
end
end
end
end

– Add the background event handler to our background
– displayRect…
background:addEventListener ( “touch”, handleTouch )
chairMaterial = { density = 1.0, bounce = 0.5 }
tableMaterial = { density = 1.0, bounce = 0.1 }

for i=1,10 do
furniture[i] = {}
local tempNumber = math.random(1,3)
tempSize = 64
local tempValue = math.random(1,2)
if(tempValue==1)then
– Make a table!
furniture[i] = display.newCircle(0,0,30,30)
furniture[i]:setFillColor(255,255,0)
physics.addBody( furniture[i], tableMaterial )
furniture[i].linearDamping = 10
furniture[i].angularDamping = 2
else
– Make a chair!
furniture[i] = display.newRect(0,0,30,30)
furniture[i]:setFillColor(175,50,110)
physics.addBody( furniture[i], chairMaterial )
furniture[i].linearDamping = 1
furniture[i].angularDamping = 2
end

furniture[i].x = math.random(200,250)
furniture[i].y = math.random(200,250)
furniture[i].linearDamping = 4
furniture[i].angularDamping = 2
furniture[i].name=“furniture”…i
end

[/code]

The chairs are the squares and they’re lighter and more likely to move fast, whereas the tables I’ve increased the damping on them. We’re so close, I’m DYIN over here!! :slight_smile: Thanks for the help and effort! [import]uid: 11636 topic_id: 12005 reply_id: 43970[/import]