Playing with physics joints today. A common physics effect is to create chain. A chain in Corona SDK is a group of physics objects joined together with a Pivot joint. Create a chain by creating a series of display objects, use physics.addBody() to turn them into physics bodies, and last create a joint between each object connecting them in series.
A chain will often contain many links. This means that you will end up creating many physics bodies, and a joint a between pair. This is a lot of objects. Best to use a Loop here.
Create a joint between two physics objects with physics.newJoint(). The method takes 5 parameters:
physics.newJoint( "pivot", object1, object2, anchorX, anchorY )
- “pivot” – Sets the type of joint to pivot.
- object1 – first object in the joint.
- object2 – second object in the joint.
- anchorX – X position of of the joint between the two objects.
- anchorY – Y position of the joint between the to objects.
The anchorX and anchorY set a common point where object1 and object2 are connected.
Here’s a simple function that makes a chain made of any number of rectangular links.
local function make_chain( x, y, w, h, c )
local prev_link
for i = 1, c do
local link = display.newRect( x, y+(i*(h+1)), w, h )
if i == 1 then
physics.addBody( link, "static" )
else
physics.addBody( link, "dynamic" )
link.linearDamping = 1
link.angularDamping = 11
end
if i > 1 then
print( i )
physics.newJoint( "pivot", prev_link, link, x, prev_link.y + (h*0.5) )
end
prev_link = link
end
end
This function takes 5 parameters
- x – The x position of the first link.
- y – The y position of the first link.
- w – Width of each link.
- h – Height of each link.
- c – (Count) the number of links in the chain.
The first chain link is a static and so supports the chain.
For testing try the code below. Make a new default project in Corona and paste the following into main.lua. This example creates a chain, and a circle. Swipe to shoot the ball. The ball helps give you an idea how the chain reacts.
local physics = require( "physics" ) physics.start() physics.setDrawMode("hybrid") -- physics.setContinuous( false ) physics.setVelocityIterations( 16 ) local function make_chain( x, y, w, h, c ) local prev_link for i = 1, c do local link = display.newRect( x, y+(i*(h+1)), w, h ) if i == 1 then physics.addBody( link, "static" ) else physics.addBody( link, "dynamic" ) link.linearDamping = 1 link.angularDamping = 11 end if i > 1 then print( i ) physics.newJoint( "pivot", prev_link, link, x, prev_link.y + (h*0.5) ) end prev_link = link end end make_chain( 160, 10, 20, 20, 10 ) -- make_chain( 160, 10, 20, 100, 3 ) -- make_chain( 160, 10, 10, 30, 5 ) -- make_chain( 160, 10, 5, 10, 20 ) -- make_chain( 80, 10, 5, 10, 20 ) -- make_chain( 240, 10, 5, 10, 20 ) local floor = display.newRect( 160, 480, 320, 10 ) physics.addBody( floor, "static" ) local left = display.newRect( 0, 240, 10, 480 ) physics.addBody( left, "static" ) local right = display.newRect( 320, 240, 10, 480 ) physics.addBody( right, "static" ) local top = display.newRect( 160, 0, 320, 10 ) physics.addBody( top, "static" ) local ball = display.newCircle( 160, 300, 30 ) physics.addBody( ball, "dynamic", {radius=30} ) local function shoot( event ) if event.phase == "ended" then local dx = event.x - event.xStart local dy = event.y - event.yStart ball:applyLinearImpulse( -dx * 0.01, -dy * 0.01, ball.x, ball.y ) end end Runtime:addEventListener( "touch", shoot )