I'm entirely new to lua and using a physics API, but have prior experience with a variety of languages. I thought I'd give writing a simple game a bash to get back into the swing of things after a long break.
I would like to fix the centre of gravity to the centre of a circle. After which, the plan is to attach a series of objects to the outside of the circle and rotate it to give the impression of a moving cityscape. If anyone can spare a few minutes to point me in the right direction it would be appreciated!
Cheers
Gravity (quick noob question)
Re: Gravity (quick noob question)
Gravity in Box2d (Love2d's physics module) is just a vector. If you want to have non-uniform gravity you have to apply forces to all dynamic bodies in your simulation. Basically you have to iterate all bodies and apply a force to each one in direction of your circle center.
If you have A LOT of objects you may want to create them dynamically, rather than creating the entire "cityscape" and then rotating it.
If you have A LOT of objects you may want to create them dynamically, rather than creating the entire "cityscape" and then rotating it.
-
- Prole
- Posts: 3
- Joined: Sat Dec 06, 2014 3:14 pm
Re: Gravity (quick noob question)
Thanks, that makes sense.
Before looking at the dynamic option, I'd still like to resolve the physics method. I've taken one of the tutorial scripts as a start and edited it to attempt to apply force to some blocks, however they all fly away. Can you spot where I'm going wrong, or what I've missed?
Before looking at the dynamic option, I'd still like to resolve the physics method. I've taken one of the tutorial scripts as a start and edited it to attempt to apply force to some blocks, however they all fly away. Can you spot where I'm going wrong, or what I've missed?
Code: Select all
function love.load()
love.physics.setMeter(64) --the height of a meter our worlds will be 64px
world = love.physics.newWorld(0, 4*love.physics.getMeter(), true)
width, height = love.graphics.getDimensions()
objects = {} -- table to hold all our physical objects
-- create ground sphere
objects.ground = {}
objects.ground.body = love.physics.newBody(world, width/2, height/2)
objects.ground.shape = love.physics.newCircleShape(width/4) --make globe
objects.ground.fixture = love.physics.newFixture(objects.ground.body, objects.ground.shape) --attach shape to body
-- create some buildings
num_buildings = 7
objects.building = {}
for i=1, num_buildings do
gX, gY = objects.ground.body:getX(), objects.ground.body:getY()
gX = gX - (50 * num_buildings) + (100*i) - 50
gY = gY /2
objects.building[i] = {}
objects.building[i].body = love.physics.newBody(world, gX, gY, "dynamic")
objects.building[i].shape = love.physics.newRectangleShape(0,0,width*0.02,width*0.05)
objects.building[i].fixture = love.physics.newFixture(objects.building[i].body, objects.building[i].shape,10)
end
--initial graphics setup
love.graphics.setBackgroundColor(0, 0, 0)
love.window.setMode(width, height)
end
function love.update(dt)
world:update(dt) --this puts the world into motion
--apply force
gX, gY = objects.ground.body:getX(), objects.ground.body:getY()
for i=1, num_buildings do
objects.building[i].body:applyForce(gX, gY)
end
end
function love.draw()
-- draw the centre sphere
love.graphics.setColor(77, 0, 75, 255)
love.graphics.circle("fill", objects.ground.body:getX(), objects.ground.body:getY(), objects.ground.shape:getRadius())
-- draw buildings
love.graphics.setColor(50, 50, 50)
for i=1, num_buildings do
love.graphics.polygon("fill", objects.building[i].body:getWorldPoints(objects.building[i].shape:getPoints()))
end
-- add fps to corner
love.graphics.setColor(255,255,100,200)
love.graphics.print(love.timer.getFPS(), 10, 10)
-- add marker for values used in applying force
love.graphics.print("X",objects.ground.body:getX(),objects.ground.body:getY())
end
Re: Gravity (quick noob question)
I would suggest something like:
Code: Select all
local building_width = math.pi*2*ground_radius/num_buildings -- circumference/num_buildings
for i=1, num_buildings do
local i2 = i/num_buldings -- i in range 0 to 1
local a = i2*math.pi*2 -- angle in radians
local building_height = math.random(5, 20) -- random value
local x = math.cos(a)*(ground_radius + building_height/2)
local y = math.sin(a)*(ground_radius + building_height/2)
-- create a body at position "x", "y" with a rotation of "a" radians
-- create a box fixture with size "building_width" by "building_height"
-
- Prole
- Posts: 3
- Joined: Sat Dec 06, 2014 3:14 pm
Re: Gravity (quick noob question)
I've adapted that for building placement:
All of the blocks still slip off of the sphere unless I change them from 'dynamic' to 'static' or 'kinematic'. Applying force to the dynamic objects towards the centre of the sphere, or any other [x,y] position, does not counter the gravity.
*EDIT
I've solved this using a static sphere and dynamic blocks by using distance joints and rotations instead of applying force:
If there is a better way please keep me posted!
Code: Select all
local building_width = (( math.pi*2*objects.ground.shape:getRadius() ) / num_buildings)-- circumference/num_buildings
for i=1, num_buildings do
local i2 = i/num_buildings -- i in range 0 to 1
local a = i2*math.pi*2 -- angle in radians
local building_height = math.random(10, 50) -- random value
local x = objects.ground.body:getX() + math.cos(a)*(objects.ground.shape:getRadius() + building_height/2)
local y = objects.ground.body:getY() + math.sin(a)*(objects.ground.shape:getRadius() + building_height/2)
objects.building[i] = {}
objects.building[i].body = love.physics.newBody(world, x, y, "dynamic")
objects.building[i].body:setAngle(a)
objects.building[i].shape = love.physics.newRectangleShape(0,0,building_width,building_height)
objects.building[i].fixture = love.physics.newFixture(objects.building[i].body, objects.building[i].shape,10)
end
*EDIT
I've solved this using a static sphere and dynamic blocks by using distance joints and rotations instead of applying force:
Code: Select all
local building_width = (( math.pi*2*objects.ground.shape:getRadius() ) / num_buildings)-- circumference/num_buildings
for i=1, num_buildings do
local i2 = i/num_buildings -- i in range 0 to 1
local a = i2*math.pi*2 -- angle in radians
local building_height = math.random(50, 100) -- random value
local x = objects.ground.body:getX() + math.cos(a)*(objects.ground.shape:getRadius() + building_height/2)
local y = objects.ground.body:getY() + math.sin(a)*(objects.ground.shape:getRadius() + building_height/2)
objects.building[i] = {}
objects.building[i].body = love.physics.newBody(world, x, y, "dynamic")
objects.building[i].body:setAngle(a)
objects.building[i].shape = love.physics.newRectangleShape(0,0,building_width,building_height)
objects.building[i].fixture = love.physics.newFixture(objects.building[i].body, objects.building[i].shape,10)
objects.building[i].joint = love.physics.newDistanceJoint( objects.ground.body, objects.building[i].body, x, y, x, y )
end
Code: Select all
rot = -0.0001
objects.ground.body:setAngle(objects.ground.body:getAngle()+rot)
for i=1, num_buildings do
objects.building[i].body:setAngle(objects.building[i].body:getAngle()+rot)
end
Re: Gravity (quick noob question)
Make sure your global gravity is zero: "world:setGravity(0, 0)"gibberwocky wrote:All of the blocks still slip off of the sphere unless I change them from 'dynamic' to 'static' or 'kinematic'. Applying force to the dynamic objects towards the centre of the sphere, or any other [x,y] position, does not counter the gravity.
Static objects are basically immovable which is one way to go, in that case you can have 1 static body with the "buildings" represented as fixtures on it.
If you want your buildings to be dynamic (so you can knock them over) then it gets a little more complicated.
In particular the base of the buildings (in your case) is flat while the "ground" object is circular: imagine balancing a rectangle top of a circle.
I suppose it might work better if each building is represented as two triangle fixtures so that they look like 'chairs':
Code: Select all
_____
| / \ |
|/ \|
Who is online
Users browsing this forum: No registered users and 6 guests