Corona SDK – Physics – chains

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 )

 

Leave a Reply

Your email address will not be published. Required fields are marked *