Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Planet physics (Gravity)

edited August 2013 in Examples Posts: 437

Hey all, this is a very simple example of my suggestion to use a set of planets with gravity , movers and attractors:

``````--# Main
-- PlanetGravity

-- Use this function to perform your initial setup
function setup()
physics.gravity(0,0)
mainPlanet = Planet({
x       = WIDTH/2,
y       = HEIGHT/2,
mass    = 10,
type    = ATTRACTOR,
img     = "SpaceCute:Planet"
})

redPlanet = Planet({
x       = WIDTH - 100,
y       = HEIGHT/3,
mass    = 8,
type    = ATTRACTOR,
img     = "Space Art:UFO"
})

asteroid = Planet({
x       = WIDTH/4,
y       = 100,
sizex   = 66,
sizey   = 55,
mass    = 2,
type    = MOVER,
img     = "Space Art:Asteroid Large"
})

small_asteroid = Planet({
x       = WIDTH/1.2,
y       = HEIGHT - 100,
sizex   = 50,
sizey   = 50,
mass    = 1,
type    = MOVER,
img     = "Space Art:Asteroid Small"
})

rockPlanet = Planet({
x       = 100,
y       = HEIGHT - 100,
mass    = 18,
type    = ATTRACTOR,
img     = "Tyrian Remastered:Rock 3"
})

-- set the attractors

-- controls of the masses
parameter.number("Red Planet Mass", 8, 150, 8, function(newMass)
redPlanet.mass = newMass
end
)
parameter.number("Green Planet Mass",10,200,10,function(newMass)
mainPlanet.mass= newMass
end
)
parameter.number("Rock Planet Mass",8,200,18,function(newMass)
rockPlanet.mass= newMass
end
)
createUniverseLimit()
end

function createUniverseLimit()
top   = physics.body(EDGE, vec2(0,HEIGHT), vec2(WIDTH,HEIGHT))
left  = physics.body(EDGE, vec2(0,HEIGHT), vec2(0,0))
right = physics.body(EDGE, vec2(WIDTH,HEIGHT), vec2(WIDTH,0))
bottom= physics.body(EDGE, vec2(0,0) , vec2(WIDTH,0))
end

function draw()
background(0)
strokeWidth(2)

mainPlanet:draw()
rockPlanet:draw()
redPlanet:draw()
asteroid:draw()
small_asteroid:draw()
end

function touched(touch)
if asteroid:touched(touch) then return end
if small_asteroid:touched(touch) then return end
end

--# Planet
Planet = class()
ATTRACTOR = 1
MOVER     = 2
GRAVITY   = 1000
function Planet:init(args)
-- create the planet body
self.body.x    = args.x
self.body.y    = args.y
self.type      = args.type
self.body.mass = args.mass
self.mass      = args.mass -- when static, body.mass is 0
self.dragOffset= vec2(0,0)
self.body.restitution = .05
self.body.friction = .6
self.touchId   = 0
if args.type == ATTRACTOR then
self.attracted = {}
self.body.type = STATIC
elseif args.type == MOVER then
self.attractors= {}
end

end

if self.type == ATTRACTOR then
table.insert(self.attracted, attractor)
table.insert(attractor.attractors, self)
elseif self.type == MOVER then
table.insert(self.attractors, attractor)
table.insert(attractor.attracted, self)
end
end

function Planet:attract(m)
-- Direction of the force
local force = self.body.position - m.body.position
local d     = force:len() -- = m.body.position:dist(self.body.position)
force = force:normalize()
local dir   = vec2(self.mass/m.body.mass, self.mass/m.body.mass)

-- Magnitude of the force
local strength = (GRAVITY * self.mass * m.body.mass)/(d*d)
force = force * strength
m.body:applyForce(force)

stroke((1+math.floor(force.y))*110, (1+math.floor(force.x))*110, 10, 255)

-- draw line between attractor/mover
line(m.body.x+force.x, m.body.y+force.y, (self.body.x), (self.body.y))
end

function Planet:updateForces()
if self.type == ATTRACTOR then
self.body.angle = self.body.angle - 0.1
for i,a in ipairs(self.attracted) do
self:attract(a)
end
elseif self.type == MOVER then
-- check for planets?
-- TODO
end
end

function Planet:draw()
self:updateForces()
pushMatrix()
translate(self.body.x, self.body.y)
rotate(self.body.angle)
sprite(self.img, 0, 0, self.sizex, self.sizey)
popMatrix()
end

function Planet:touched(touch)
if touch.state == BEGAN then
if self.touchId == 0 then
if self.body:testPoint(vec2(touch.x,touch.y)) then
self.touchId = touch.id
else
-- not touching this body
return false
end
else
-- this body has another touch
return false
end
else
if self.touchId ~= touch.id then
return false
end
end

self.body.x = touch.x
self.body.y = touch.y
if touch.state == ENDED then
self.touchId = 0
end
return true
end

``````
Tagged: