Dr Burtons Corona SDK book example on GRAVITY

Hi guys,

Im writing to ask about Dr Brian Burtons code in his corona sdk book.

Its a simple gravity example test. Up down left right all affecting the gravity of a crate

Ive typed it exactly as it is in the book, and it seems very finiky, like Initially SetGravity(0,0) and adjusting the gravity buttons does nothing.

unless i set gravity to 0, 9.8, then im able to adjust the falling crates gravity using buttons. but even that works sometimes and sometimes theres no response. am i missing something? also the values in the text suddenly jump to additional numbers…

require “CiderDebugger”;-- Project: Ch8PlayingWithGravity

– Description:

– Version: 1.0

– Managed with http://CoronaProjectManager.com

– Copyright 2011 Brian Burton. All Rights Reserved.

---- cpmgen main.lua

local physics = require (“physics”)

physics.start()

–set initial

physics.setGravity(0, 9.8)

–initialise gx and gy

gx = 0

gy = 0

local ground = display.newRect(0, 768, 768, 10)

ground:setFillColor(255, 255, 255, 255)

local leftSide = display.newRect(1,1,10,768)

leftSide:setFillColor(255,255,255,255)

local rightSide = display.newRect(758,0,768,768)

rightSide:setFillColor(255,255,255,255)

local top = display.newRect(0,0,768, 10)

top:setFillColor(255,255,255,255)

– border to phyisics as a static

physics.addBody(ground, “static”)

physics.addBody(leftSide, “static”)

physics.addBody(rightSide, “static”)

physics.addBody(top, “static”)

–crate loading 

local crate = display.newImage(“crateB.png”)

crate.x = 389

crate.y = 389

physics.addBody(crate, {density=1.0, friction=0.2, bounce=0.3})

local gravityX = display.newText(“0.0”, 490, 875, native.systemFont, 36)

local gravityY = display.newText(“0.0”, 195, 875, native.systemFont, 36)

local upButton = display.newImage(“arrowButton.png”, 200, 800)

upButton.rotation = -90

local downButton = display.newImage(“arrowButton.png”, 200, 950)

downButton.rotation = 90

local leftButton = display.newImage(“arrowButton.png”, 400, 875)

leftButton.rotation = 180

local rightButton = display.newImage(“arrowButton.png”, 600, 875)

–update gravity function

local function updateGravity()

    gx, gy = physics.getGravity()

    gravityX.text = gx

    gravityX.text = (gravityX.text:sub(1,4))

    gravityY.text = gy

    gravityY.text = (gravityY.text:sub(1,4))

end

– adjust gravity of buttons

local function upButtonEvent (event)

    physics.setGravity(gx, gy + 0.1)

    updateGravity()

end

local function downButtonEvent (event)

    physics.setGravity(gx, gy - 0.1)

    updateGravity() 

end

local function leftButtonEvent (event)

    physics.setGravity(gx - 0.1, gy)

    updateGravity()

    

end

local function rightButtonEvent (event)

    physics.setGravity(gx + 0.1, gy)

    updateGravity()

end

–listeners

upButton:addEventListener(“tap”, upButtonEvent)

downButton:addEventListener(“tap”, downButtonEvent)

leftButton:addEventListener(“tap”, leftButtonEvent)

rightButton:addEventListener(“tap”, rightButtonEvent)

please could you guys help

Gary,

There was a minor change to gravity in the physics engine after the books was published.

If you give the box a little nudge (like you did with setting the gravity to 9.8), it will work fine.  I have updated the source code in the sample files to be -0.01 for the gy parameter.  

The next revision of the book will also include this change.

Dr. Burton

Well, I’ve just run that and it seems to work before the crate has landed properly. Once it lands and stops, though, the crate won’t move any more due to friction on the static object.

I have a standard behaviour when using fixed position objects which would normally be static: I create an anchor off-screen and weld the objects (such as ground and walls) to the anchor. This (usually) proves useful because the fixed objects behave more like real world objects rather than immovable objects exerting an irresistible force.

In your case, assuming you’ve assigned typical dynamic body properties to the welded walls and floor (just as to the crate) you should see the difference between using static bodies and dynamic bodies: Static objects exert and irresistible force against dynamic bodies. This means that, once a crate comes to rest, the maths governing its position relative to the static object keep it locked in place (unless another object comes into play and knocks it aside.)

Here’s my code:

local physics = require ("physics") physics.start() --set initial physics.setGravity(0, 9.8) --initialise gx and gy gx = 0 gy = 0 local ground = display.newRect(0, 768, 768, 10) ground:setFillColor(255, 255, 255, 255) local leftSide = display.newRect(1,1,10,768) leftSide:setFillColor(255,255,255,255) local rightSide = display.newRect(758,0,768,768) rightSide:setFillColor(255,255,255,255) local top = display.newRect(0,0,768, 10) top:setFillColor(255,255,255,255) -- anchor \*\*\*\* local anchor = display.newCircle( -100,-100,10 ) physics.addBody( anchor,"static" ) -- border to physics as a static -- made the ground, walls and top dynamic \*\*\*\* physics.addBody(ground, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(leftSide, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(rightSide, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(top, {density=1.0, friction=0.3, bounce=0.3}) -- anchored them \*\*\*\* physics.newJoint("weld",anchor,ground,anchor.x,anchor.y) physics.newJoint("weld",anchor,leftSide,anchor.x,anchor.y) physics.newJoint("weld",anchor,rightSide,anchor.x,anchor.y) physics.newJoint("weld",anchor,top,anchor.x,anchor.y) --crate loading  local crate = display.newImage("crate.png") crate.x = 389 crate.y = 389 physics.addBody(crate, {density=1.0, friction=0.3, bounce=0.3}) local gravityX = display.newText("0.0", 490, 875, native.systemFont, 36) local gravityY = display.newText("0.0", 195, 875, native.systemFont, 36) local upButton = display.newImage("button.png", 200, 800) upButton.rotation = -90 local downButton = display.newImage("button.png", 200, 950) downButton.rotation = 90 local leftButton = display.newImage("button.png", 400, 875) leftButton.rotation = 180 local rightButton = display.newImage("button.png", 600, 875) --update gravity function local function updateGravity()     gx, gy = physics.getGravity()     gravityX.text = gx     gravityX.text = (gravityX.text:sub(1,4))     gravityY.text = gy     gravityY.text = (gravityY.text:sub(1,4)) end -- adjust gravity of buttons local function upButtonEvent (event)     physics.setGravity(gx, gy + 0.1)     updateGravity() end local function downButtonEvent (event)     physics.setGravity(gx, gy - 0.1)     updateGravity()  end local function leftButtonEvent (event)     physics.setGravity(gx - 0.1, gy)     updateGravity()      end local function rightButtonEvent (event)     physics.setGravity(gx + 0.1, gy)     updateGravity() end --listeners upButton:addEventListener("tap", upButtonEvent) downButton:addEventListener("tap", downButtonEvent) leftButton:addEventListener("tap", leftButtonEvent) rightButton:addEventListener("tap", rightButtonEvent)

I’ve slightly adjusted it as I didn’t have your images.

Thanks Dr Burton for solving the initial problem, thanks Horacebury for solving the second one where it stops working once crate has landed.

Dr Burton, please include Horaceburys solution in your revision, as it seems very important in explaining the background to your chapter on physics. Could you also comment on the solution of welding to an anchor?

Horacebury, does anchoring the three objects just allow you to make them dynamic? can we not manipulate them as they are, or is anchoring the only way to make them stay in a fixed position?

sorry for the confusion

Anchoring the three objects does not rely on them being dynamic, but it does allow them to remain fixed in position, as if they were static objects.

Keeping them dynamic is Box2D’s answer to the age old question “What happens when an irresistible force meets an immovable object?”

Static objects  cannot be moved. It’s simply not possible. Therefore they are immovable objects.

Dynamic objects can be positioned absolutely and therefore can become  irresistible forces.

This is obviously not a good situation to be in, so we resolve it by making all objects dynamic. How does this apply to your problem? Answer: Only half of this applies to your problem - the static object half…

Basically, the friction value of the static object causes an almost irresistible force to be applied to the dynamic body, which keeps it in place, even when the gravity changes. This is possible because no other force is being applied to the dynamic body. This happens within the maths of the physics engine simply because all static objects exert effectively infinite force values against all other objects.

Please don’t take my explanation as cannon - I’m not a physics, Box2D, math or any other type of expert! But this is my understanding of the effect being applied within the Box2D physics engine. Funnily enough, I learned this on this very website, some time ago.

My final recommendation: Use an anchor object, placed well out of the way, and make every object dynamic and weld them to the anchor. You’ll end up with a much more realistic world.

Gary,

There was a minor change to gravity in the physics engine after the books was published.

If you give the box a little nudge (like you did with setting the gravity to 9.8), it will work fine.  I have updated the source code in the sample files to be -0.01 for the gy parameter.  

The next revision of the book will also include this change.

Dr. Burton

Well, I’ve just run that and it seems to work before the crate has landed properly. Once it lands and stops, though, the crate won’t move any more due to friction on the static object.

I have a standard behaviour when using fixed position objects which would normally be static: I create an anchor off-screen and weld the objects (such as ground and walls) to the anchor. This (usually) proves useful because the fixed objects behave more like real world objects rather than immovable objects exerting an irresistible force.

In your case, assuming you’ve assigned typical dynamic body properties to the welded walls and floor (just as to the crate) you should see the difference between using static bodies and dynamic bodies: Static objects exert and irresistible force against dynamic bodies. This means that, once a crate comes to rest, the maths governing its position relative to the static object keep it locked in place (unless another object comes into play and knocks it aside.)

Here’s my code:

local physics = require ("physics") physics.start() --set initial physics.setGravity(0, 9.8) --initialise gx and gy gx = 0 gy = 0 local ground = display.newRect(0, 768, 768, 10) ground:setFillColor(255, 255, 255, 255) local leftSide = display.newRect(1,1,10,768) leftSide:setFillColor(255,255,255,255) local rightSide = display.newRect(758,0,768,768) rightSide:setFillColor(255,255,255,255) local top = display.newRect(0,0,768, 10) top:setFillColor(255,255,255,255) -- anchor \*\*\*\* local anchor = display.newCircle( -100,-100,10 ) physics.addBody( anchor,"static" ) -- border to physics as a static -- made the ground, walls and top dynamic \*\*\*\* physics.addBody(ground, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(leftSide, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(rightSide, {density=1.0, friction=0.3, bounce=0.3}) physics.addBody(top, {density=1.0, friction=0.3, bounce=0.3}) -- anchored them \*\*\*\* physics.newJoint("weld",anchor,ground,anchor.x,anchor.y) physics.newJoint("weld",anchor,leftSide,anchor.x,anchor.y) physics.newJoint("weld",anchor,rightSide,anchor.x,anchor.y) physics.newJoint("weld",anchor,top,anchor.x,anchor.y) --crate loading  local crate = display.newImage("crate.png") crate.x = 389 crate.y = 389 physics.addBody(crate, {density=1.0, friction=0.3, bounce=0.3}) local gravityX = display.newText("0.0", 490, 875, native.systemFont, 36) local gravityY = display.newText("0.0", 195, 875, native.systemFont, 36) local upButton = display.newImage("button.png", 200, 800) upButton.rotation = -90 local downButton = display.newImage("button.png", 200, 950) downButton.rotation = 90 local leftButton = display.newImage("button.png", 400, 875) leftButton.rotation = 180 local rightButton = display.newImage("button.png", 600, 875) --update gravity function local function updateGravity()     gx, gy = physics.getGravity()     gravityX.text = gx     gravityX.text = (gravityX.text:sub(1,4))     gravityY.text = gy     gravityY.text = (gravityY.text:sub(1,4)) end -- adjust gravity of buttons local function upButtonEvent (event)     physics.setGravity(gx, gy + 0.1)     updateGravity() end local function downButtonEvent (event)     physics.setGravity(gx, gy - 0.1)     updateGravity()  end local function leftButtonEvent (event)     physics.setGravity(gx - 0.1, gy)     updateGravity()      end local function rightButtonEvent (event)     physics.setGravity(gx + 0.1, gy)     updateGravity() end --listeners upButton:addEventListener("tap", upButtonEvent) downButton:addEventListener("tap", downButtonEvent) leftButton:addEventListener("tap", leftButtonEvent) rightButton:addEventListener("tap", rightButtonEvent)

I’ve slightly adjusted it as I didn’t have your images.

Thanks Dr Burton for solving the initial problem, thanks Horacebury for solving the second one where it stops working once crate has landed.

Dr Burton, please include Horaceburys solution in your revision, as it seems very important in explaining the background to your chapter on physics. Could you also comment on the solution of welding to an anchor?

Horacebury, does anchoring the three objects just allow you to make them dynamic? can we not manipulate them as they are, or is anchoring the only way to make them stay in a fixed position?

sorry for the confusion

Anchoring the three objects does not rely on them being dynamic, but it does allow them to remain fixed in position, as if they were static objects.

Keeping them dynamic is Box2D’s answer to the age old question “What happens when an irresistible force meets an immovable object?”

Static objects  cannot be moved. It’s simply not possible. Therefore they are immovable objects.

Dynamic objects can be positioned absolutely and therefore can become  irresistible forces.

This is obviously not a good situation to be in, so we resolve it by making all objects dynamic. How does this apply to your problem? Answer: Only half of this applies to your problem - the static object half…

Basically, the friction value of the static object causes an almost irresistible force to be applied to the dynamic body, which keeps it in place, even when the gravity changes. This is possible because no other force is being applied to the dynamic body. This happens within the maths of the physics engine simply because all static objects exert effectively infinite force values against all other objects.

Please don’t take my explanation as cannon - I’m not a physics, Box2D, math or any other type of expert! But this is my understanding of the effect being applied within the Box2D physics engine. Funnily enough, I learned this on this very website, some time ago.

My final recommendation: Use an anchor object, placed well out of the way, and make every object dynamic and weld them to the anchor. You’ll end up with a much more realistic world.