Corona Reference: Physics


Setting Up the Physics World

Include the following line at the beginning of your code to enable the physics library:
local physics = require( "physics" )
Next, include the following line to begin all physics simulations:
physics.start()

Gravity

    By default, the physics engine will simulate gravity on Earth, with no horizontal gravity and 9.8 m/secĀ² vertical gravity, so objects will fall from the top of the scene to the bottom. You can adjust the gravity however you like by changing the x and y components of the setGravity function:
    physics.setGravity( x, y )
    For instance, to make objects fall towards the lower right corner of the screen, you would set both values to a positive number:
    physics.setGravity( 4, 8 )
    and to pull objects toward the upper right corner, you would have a positive x value and a negative y value:
    physics.setGravity( 6, -5 )
    To remove all effects of gravity, set both values to 0.

Pausing and Restarting Physics

    To temporarily suspend physics simulations, use the pause method:
    physics.pause()
    This line would typically be included in a function. To stop all physics simulations and "destroy" the physics world, use
    physics.stop()

Other Properties

    If your physics enabled app does not seem to behave properly, there are some other settings you may try to adjust. These are all best left at the default option, unless your app specifically requires a change.

    setScale
    By default, the pixel-per-meter ratio used between display objects and physics simulations is set to 30, meaning that a 90 pixel object would be considered 3 meters wide. This is the best setting for display objects less than 300 pixels wide. If you're using a lot of larger physics objects, you might notice the objects appearing too "heavy" or reacting slowly in a collision. In this case, try changing the scale value to a larger value:
    physics.setScale( 60 )
    Note that this is not necessary or suggested if the majority of your physics objects are less than 300 pixels wide or high.

    setContinuous
    By default, the physics engine will continuously check for collisions to ensure proper behavior. This helps prevent objects from "tunneling" through small static objects, but may cause unwanted effects with certain physics joints. To turn off continual collision detection, set
    physics.setContinuous( false )
    Note that collisions may appear sluggish and static bodies will need to be larger than usual to prevent tunneling in this case.

    setPositionIterations
    During animations, the physics engine will compute the position of physics objects 8 times per frame, per object. Occasionally, you might notice two physics bodies momentarily overlapping during a collision in between these calculations. To increase the number of position approximations per frame, adjust the number to a higher value
    physics.setPositionIterations( 16 )
    Note that this may greatly decrease performance, and is rarely necessary.

Draw Modes

The physics engine allows three draw modes that can be used to understand how your physics bodies are interacting. By default, the rendering mode is "normal", meaning that the simulator will display exactly what the device would display. For debugging purposes, it is useful to change this mode to either "hybrid" or "debug".

In hybrid mode, physics bodies will be displayed along with an overlay of collision outlines. Include the following line at the beginning of your code (but after you've included the physics library) to view hybrid mode:
	physics.setDrawMode( "hybrid" )
To view only the collision outlines, set the draw mode to "debug":
	physics.setDrawMode( "debug" )
The color of the outline depends on the type of physics body and its current state:
  • Dynamic bodies will be outlined in orange
  • Kinematic bodies will be outlined in dark blue
  • Static bodies will be outlined in green
  • Sleeping bodies will be outlined in grey
  • Physics joints will be outlined in light blue
In addition to displaying the collision outlines and states, the hybrid and debug modes also show a small marker at the physics body's center of mass if the body is dynamic or kinematic.

The images below show a physics-enabled scene rendered with normal, hybrid, and debug modes, respectively:
normalmode hybridmode debugmode

Physics Bodies

Display Objects to Physics Bodies

    Any display object (simple shape, imported image, or sprite) can be turned into a physics body. After enabling physics and defining your display object, use the addBody function to make your object react to gravity and collisions. A complete but simple example would be
    local physics = require( "physics" )
    physics.start()
    
    local myCircle = display.newCircle( 100, 100, 50 )
    physics.addBody( myCircle )
    If you run the code above in the simulator, you'll see the circle immediately fall to the bottom of the screen, and continue falling until it is no longer visible. This is because the body is reacting to the default gravity setting, and there is no object at the bottom of the screen (acting as the ground) to stop its motion.

    All display properties are still available to physics bodies, like fill color. Physics bodies can still be repositioned by changing their x and y properties and rotated as usual, but they will have many other properties that will control their motion and reaction to various forces in a physics simulation.

    Note: While it is possible to scale a physics body to change its size on the screen, this is not recommended. For imported images, physics simulations will perform much better if the size of the object is changed PRIOR to importing it, using an external editor.

Body Types

    There are three major types of physics bodies, all of which react differently to collisions and other events:
    • Dynamic Bodies This is the default type for a physics body; all bodies are dynamic unless changed to another type. These bodies react to gravity and collisions with all other body types.
    • Kinematic Bodies Kinematic bodies do not react to gravity. They will react to collisions with dynamic bodies, but not other kinematic bodies or static bodies.
    • Static Bodies Static bodies do not react to gravity and are not moved by collisions. Examples would include the ground, a wall, a tree, or any other object that your dynamic or kinematic objects should "lose" a collision with.
    The body type of an object can be specified when adding it:
    local myCircle = display.newCircle( 100, 100, 50 )
    physics.addBody( myCircle, "kinematic" )
    or after the object is defined, by changing the bodyType property (note, this property cannot be changed during a collision):
    local myCircle = display.newCircle( 100, 100, 50 )
    physics.addBody( myCircle )
    myCircle.bodyType = "kinematic"

Body Properties

    Any physics body, regardless of type, has three properties that determine how it reacts with other objects. These are similar to properties you're used to, but note that an app is a two dimensional world. This means that "volume" is replaced by "area".
    • Density This property controls the mass of an object (density x area = mass). The default density is 1.0, the density of water. Values greater than 1 will result in "heavier" objects, while lower density values will result in "lighter" objects. The overall appearance of mass will also depend on the gravity of your scene and the physics scale.
    • Friction This property controls how "slippery" the objects are. The default value is 0.3. Smaller values (must be at least 0) result in an object with a lower coefficient of friction, while higher values will seem to have a rougher texture. A value of 1 would be a strong coefficient of friction, while a value of 0.1 would be appropriate for a texture such as ice.
    • Bounce This value decides how much of the object's velocity is returned after a collision. A value of 0 will result in no "bounce" - the object will simply stop when it collides with a static object. A value of 1 will cause the object to return to its original position, while any value greater than 1 will cause the object to gain velocity after a collision (in the opposite direction). The default value is 0.2.
    If you'd like to change any of the body properties to something other than their default value, you can do so when adding the body:
    local myCircle = display.newCircle( 100, 100, 50 )
    physics.addBody( myCircle, { density = 0.6, friction = 0.6, bounce = 0.3 } )

Waking and Sleeping

    The start function takes an optional argument. By default, all physics bodies are set to "sleep" after a few seconds of not being involved in a collision. This is meant to improve performance, and works well for most apps. Sleeping bodies will automatically "wake" when a collision is detected. However, sleeping bodies do not wake in response to a change in gravity. For instance, if you're creating an app where the gravity changes in response to the accelerometer (if the user tilts the device), you'll need to force all bodies to stay awake. To do so, pass the argument true to the start function:
    	physics.start( true )
    To keep only certain bodies awake, set the isSleepingAllowed property of the body itself to false:
    	myBody.isSleepingAllowed = false
    The read-only isAwake property returns true if the body is awake, and false otherwise.

Additional Body Properties

    There are several properties available to control how (or if) a physics body interacts with other objects:
    • Sensor A sensor object is used to detect another object passing over it. They trigger a collision, but are not moved by it. For instance, a rectangular body could be placed over the goal area in a hockey game to detect that a puck. The puck will not bounce off the object, but a collision function would still fire and change the score. To create a sensor, draw a static physics body over the area and set its isSensor property to true:
      myBody.isSensor = true
      A collision event triggered by sensor objects has two phases, "began" (when the colliding object enters the sensor) and "ended" (when the colliding object leaves the sensor). For invisible sensor areas, create a sensor object, and set its alpha value very close to 0, such as 0.01.
    • Active Setting the isActive property to false will prevent the body from interacting with other physics bodies. The body will not be removed. To set a body called "myBody" to inactive, include the line
      myBody.isBodyActive = false
      This cannot be done during a collision. If you'd like to render a physics body inactive after it has been in a collision, you'll need to use a timer to call a function that will inactivate the body after the collision has completed.
    • Bullets Setting the isBullet property to true will cause collision detection to be run continuously, instead of the default detection. This is generally not necessary, unless the object is moving at a very high speed. In these cases, the object may appear to have already passed through its target before a collision is detected. To create a bullet object, set
      myBody.isBullet = true
      Use this only when needed, as too many bullet objects will result in slow performance.
    • Gravity To force a particular body to override the effects of gravity, change its gravityScale property. Setting this value to 0 will make the body float, regardless of the gravity setting in the scene. Setting the value to 1 makes the object respond to the scene's gravity, as usual. Values greater than 1 will increase the effects of gravity on that object.
      myBody.gravityScale = 0.5
      Note that objects with a gravityScale greater than 1 may act a bit erratically in collisions; use this property carefully.

Collision Outlines

Rectangular

    By default, a physics body will be given a rectangular collision outline. This is fine for objects that actually are rectangular, and for static objects that can be closely approximated by a rectangle, like the ground or a wall. The rectangular outline will surround the entire object, and include any transparent pixels around the image if it is not actually rectangular.

    The penguin and tree in the scene below both have a default rectangular outline, as shown in hybrid draw mode.
    This isn't a bad approximation for the penguin, but the tree is much more problematic. Any object that comes near the tree will collide with the rectangle, which will look like the object collides with empty space near the tree, instead of the tree itself.

Circular

    For objects that are closer to circular, you can apply a circular collision outline with a specified radius. This is done by providing the radius, in pixels, in the option table when defining the object:
    physics.addBody( myObject, { radius = 80, bounce = 0.5 } )

    The penguin and tree in the scene below both have a circular outline, as shown in hybrid draw mode. On the left, the outline around the penguin includes his wings, but will make the penguin appear to hover above the ground. On the right, the radius is set smaller so he'll sit on the ground, but his wings will not be included in a collision event. Again, there is a lot of room around the tree that we probably don't want to include in a collision.
      
    This isn't a bad approximation for the penguin, but the tree is much more problematic. Any object that comes near the tree will collide with the rectangle, which will look like the object collides with empty space near the tree, instead of the tree itself.

Polygonal

    To get a more accurate collision outline for shapes that cannot be approximated by a rectangle or a circle, you can provide a table of coordinates for a polygon that better matches the body's shape. This can be labor intensive, but the results are worth it.

    The tree has now been surrounded with a polygonal outline. It's still not perfect, but most collisions with the tree will seem relatively realistic.
    Creating a polygonal outline is similar to creating a polygonal display object. Just as with these objects, a polygonal outline cannot be convex. This means we can't add additional points under the tree to better fit against the trunk, or additional points to fit around the branches.

    To create a polygonal outline, you'll first need to define a table of vertices of the outline itself.
    local myVertices = { x_1, y_1, x_2, y_2, ... , x_n, y_n }
    You might want to open your image in an image editor to help determine the best points to choose. The location of the object on screen doesn't need to be taken into account; the outline will automatically be centered over the physics body. The name of this table is then specified as the shape when defining the object.
    physics.addBody( myObject, { shape = myVertices, bounce = 0.5 } )

    The code to create the tree outline and add it to the tree object is as follows:
    local tree = display.newImage( "tree.png" )
       tree.x = 430
       tree.y = 830
    
    local treeShape = { -140,150,-50,200,50,200,140,150,0,-200 }
    physics.addBody( tree, "kinematic", { shape = treeShape } )
    Note that the vertices do not correspond to the actual location of the outline on the screen. They just specify the shape of the tree if it were centered at the origin, though even this isn't necessary - it's only important that the points are located in the correct place, relative to each other, and that they match the size of the object. The position of the tree is set by its x and y coordinates, and tree and the outline are centered at this location.

Automatic

    The best solution for irregular objects is to let Corona draw the outline for you. This will result in an outline that closely surrounds the object, without having to figure out vertices for a polygonal outline, and even if the shape is convex. There is one down side - this method uses the Graphics 2.0 library, which is only available to paid subscribers (as of October 2014). However, as a starter subscriber you can still use this method, you just won't be able to build for devices without upgrading your subscription. You'll also get a message asking you to upgrade each time you open your app in the simulator.

    To use the automatic outline method, use the newOutline function of the graphics library. This function takes two arguments. One is a numeric value that essentially specifies how close of an outline you'd like to use. This value represents the coarseness of the outline, so higher values result in poorer outlines but better performance. Lower values give a better outline, but if you have a lot of objects or action in your scene, you may notice some lag. The second argument is the name of the file you'd like outlined. You'll need to name this outline so you can pass it to the physics body you'll create next:
    local treeOutline = graphics.newOutline( 3, "tree.png" )
    Now, create the physics body as usual, and pass the name of your outline to the outline option when defining it. Note we still need to import the image itself.
    local treeOutline = graphics.newOutline( 3, "tree.png" )
    
    local tree = display.newImage( "tree.png" )
    physics.addBody( tree, "kinematic", { outline = treeOutline } )
    The result of adding outlines to the penguin and the tree, in hybrid mode shows how closely the both shapes are represented by their collision outlines:

Complex Bodies

    It is also possible to create bodies that are divided into several regions, each with different physical properties. Each of these regions is defined by a polygon table, and must be convex. The body is then created with multiple option tables in its definition.

    The bicycle horn below is made from two materials - a metal piece and a rubber piece - that will have distinct physical properties.
    We'll create two polygons around the distinct parts of the bicycle horn - one around the metal horn, and one around the rubber ball.
    local hornTable = { -93,-40,34,-16,34,4,24,28,17,36,-45,39,-93,36,-100,-2 }    
    local ballTable = { 34,-16,71,-34,89,-28,99,-13,99,6,89,17,71,23,34,4 }
    Next, to create the physics object, we import the image and use it to define the physics body. We'll give different physical properties to each section of the horn:
    local bikehorn = display.newImage("bikehorn.png")
    physics.addBody( bikehorn, "dynamic", 
       { shape = ballTable, density = 0.9, friction = 2, bounce = 0.8 },   
       { shape = hornTable, density = 6, friction = 0.5, bounce = 0.1 }    
       )

Motion and Forces

Linear Motion

    Linear motion refers to an objects change in position, as opposed to angular motion, which refers to the object's spin around its center of mass. Without any additional forces on the object, linear motion would be along a straight line. However, the trajectory of an object may seem curved if it is pulled by gravity or pushed by other forces.
    • Linear Damping To adjust how quickly an object appears to slow to a full stop (or return to its usual linear velocity) after a collision, adjust its linearDamping property:
      myBody.linearDamping = 1
      A higher value results is greater damping, and the default is 0.
    • Linear Velocity To force an object to move in a particular direction, specify the x and y components of its linear velocity as follows:
      myBody:setLinearVelocity( 1, 5 )
      The line above would case the object called "myBody" to move 1 pixel per second to the right, and 5 pixels per second down, resulting in a diagonal motion towards the lower right area of the screen. Either component can be positive or negative, so objects can be made to travel in any direction.
    • Constant Linear Force A consistent linear force can be applied to an object by specifying a target point (of the object) that will receive the force, and the x and y components of the force itself. Typically, the target point would be the object's center of mass. The first two arguments of the applyForce method are the directional components of the force (horizontal followed by vertical), and the second two are the target point.
      myBody:applyForce( 60, 300, myObject.x, myObject.y )
    • Brief Linear Force A momentary push can also be given, as opposed to the consistent push defined above. A single linear impulse can be applied with the applyLinearImpulse method, which also takes four arguments, defined in the same was as the linear force above.
      myBody:applyLinearImpulse( 60, 300, myObject.x, myObject.y )

Angular Motion

    Angular motion refers to how an object moves or spins around its center of mass.
    • Angular Damping To adjust how quickly an object stops spinning about its center of mass after a collision, adjust the angularDamping property.
      myBody.angularDamping = 3
      A higher value results is greater damping, and the default is 0.
    • Prevent Rotation To completely prevent an object from rotating during a collision or due to other forces, set the isFixedRotation property to true.
      myBody.isFixedRotation = true
      This property is also useful to prevent unwanted behavior when objects are connected by joints.
    • Angular Velocity To force an object to spin about its center of mass, even in the absence of a collision, change the angularVelocity property to any nonzero value.
      myBody.angularVelocity = 1
      Note that the object's spin will still react to collisions, but after recovering from a collision it will return to the set velocity.
    • Constant Rotational Force To apply a consistent rotational force to an object, supply a nonzero value to the applyTorque method. Positive values will cause the object to spin in a clockwise direction, and negative will result in a counterclockwise rotation.
      myBody:applyTorque( 2 )
      The resulting rotation will be about the object's center of mass.
    • Brief Rotational Force To apply a brief rotational force to an object, supply a nonzero value to the applyAngularImpulse method. Positive values will cause the object to spin in a clockwise direction, and negative will result in a counterclockwise rotation.
      myBody:applyAngularImpulse( 10 )
      The resulting rotation will be about the object's center of mass.

Joints


Joint Troubleshooting

Collisions

One of the most useful features of the physics engine is its ability to detect collisions. Many of these are handled without any effort on your part: if a dynamic ball hits a static wall, it will bounce off by itself. If you want some other events to occur when two physics bodies come into contact with each other, you can listen for a collision event and have a specific function run when one is detected.

To make it easier to see the difference between these functions, we'll use the following setup throughout all examples. The code below will create a scene with four static "walls" surrounding the display area, and four "balls" that will move randomly around the screen. We'll use a runtime enterFrame function to make sure the balls keep floating. The remaining examples will all use modifications of this code.
local physics = require( "physics" )
physics.start()
physics:setGravity(0,0)

local w = display.contentWidth
local h = display.contentHeight

local leftWall = display.newRect( 0, h/2, 2, h )
   physics.addBody( leftWall, "static" )
   leftWall.name = "wall"
   leftWall.id = "left wall"
local rightWall = display.newRect( w, h/2, 2, h )
   physics.addBody( rightWall, "static" )
   rightWall.name = "wall"
   rightWall.id = "right wall"
local ceiling = display.newRect( w/2, 0, w, 2 )
   physics.addBody( ceiling, "static" )
   ceiling.name = "wall"
   ceiling.id = "ceiling"
local floor = display.newRect( w/2, h, w, 2 )
   physics.addBody( floor, "static" )
   floor.name = "wall"
   floor.id = "floor"

local ball1 = display.newCircle( 50, 50, 60 )
   ball1:setFillColor( 1, 0, 0 )
   ball1.name = "ball"
   ball1.id = "red ball"
   ball1.alpha = 0.2
   physics.addBody( ball1 )

local ball2 = display.newCircle( 50, 50, 60 )
   ball2:setFillColor( 0, 1, 0 )
   ball2.name = "ball"
   ball2.id = "green ball"
   ball2.alpha = 0.2
   physics.addBody( ball2 )

local ball3 = display.newCircle( 50, 50, 60 )
   ball3:setFillColor( 0, 0, 1 )
   ball3.name = "ball"
   ball3.id = "blue ball"
   ball3.alpha = 0.2
   physics.addBody( ball3 )
    
local function moveBalls( event )
   ball1:applyForce( math.random(-20,20), math.random(-20,20), ball1.x, ball1.y )
   ball2:applyForce( math.random(-20,20), math.random(-20,20), ball2.x, ball2.y )
   ball3:applyForce( math.random(-20,20), math.random(-20,20), ball3.x, ball3.y )
end

Runtime:addEventListener( "enterFrame", moveBalls )
Notice that we've given a "name" property to all physics bodies - we'll use these in our collision handlers. The balls will be difficult to see at first due to the low alpha values.

Global Collisions

    If you'd like an event handler to fire whenever ANY two objects on screen collide, you can use a global collision listener. Assuming you want a function called "onCollision" to run whenever two physics bodies collide, your code will include
    local function onCollision( event )
       if (event.phase == "began") then
          -- code to run when objects first make contact
       elseif (event.phase == "ended") then
          -- code to run when objects break contact
       end
    end
    
    Runtime:addEventListener( "collision", onCollision )
    The handler can have two phases: "began" and "ended". You are not required to include actions for both phases, but you should specify a phase for anything you would like to happen. Not specifying a phase can result in actions firing twice: once when objects first touch, and again when they break contact.

    Unlike the touch event handlers we saw earlier, there is no "event.target" with global collision listeners. Instead, the two objects that are involved in the collision are calle event.object1 and event.object2. Assigning id's to your objects is recommended, because they allow you to identify which objects are actually touching.

    To continue the floating ball example from earlier, we'll create a listener that detects ALL collisions on screen; that is, the handler will be fired anytime two balls collide, or if a ball hits a wall, or even if two walls are colliding with each other (even though they're static, if they're overlapping, they're colliding). So in the handler, we'll use if-then statements to check which objects are actually colliding. In the example here, we'll make the balls temporarily 'glow' when they come into contact with another ball. We'll also print a message to the terminal with the id of the objects that were involved in the collision.
    local function onCollision( event )
       if (event.phase == "began") then
          if event.object1.name == "ball" and event.object2.name == "ball" then
             transition.to( event.object1, {alpha = 1, time = 300})
             transition.to( event.object1, {alpha = 0.2, time = 300, delay = 300})
             transition.to( event.object2, {alpha = 1, time = 300})
             transition.to( event.object2, {alpha = 0.2, time = 300, delay = 300})
          end
       elseif (event.phase == "ended") then
          print( event.object1.id.." and "..event.object2.id.." are done colliding!" )
       end
    end
    
    Runtime:addEventListener( "collision", onCollision )
    Paste the code above at the end of the code at the top of this section to see the result.

Local Collisions

    Rather than listen for every collision happening within a scene, you can use a local collision listener to check if a particular object has come into contact with another physics body. Assuming you want a function called "onCollision" to run whenever an object called "myObject" collides with another object, your code will include
    local function onCollision( self, event )
       if (event.phase == "began") then
          -- code to run when objects first make contact
       elseif (event.phase == "ended") then
          -- code to run when objects break contact
       end
    end
    
    myObject.collision = onCollision
    myObject:addEventListener( "collision", myObject )
    The handler still has two phases, "began" and "ended", just as for a global collision. The object with the listener attached to it can be referred to as self within the handler. The other object is referred to as event.other. Also note the pair of arguments taken by the handler.

    To continue the floating ball example from earlier, we'll create a listener on the red ball. If it collides with a wall, it will temporarily glow. If it collides with another ball, there will be a message printed to the terminal. All of these will occur as soon as the ball makes contact with another object; the event "ended" phase is left empty here.
    local function onCollision( self, event )
       if (event.phase == "began") then
          if event.other.name == "wall" then
             transition.to( self, {alpha = 1, time = 300})
             transition.to( self, {alpha = 0.2, time = 300, delay = 300})
          elseif event.other.name == "ball" then
             print( "The red ball just hit the "..event.other.id.."!" )
          end
       elseif (event.phase == "ended") then
       end
    end
    
    ball1.collision = onCollision
    ball1:addEventListener( "collision", ball1 )
    Paste the code above at the end of the code at the top of this section to see the result (remove the previous global collision listener and handler before doing so!).

Sensor Collisions

    As we've seen, we can create physics bodies that are defined to be sensors. These objects can listen for a collision with other objects, but there is no visual effect of the collision. That is, a dynamic ball colliding with a sensor rectangle will simply pass over the rectangle, instead of bouncing off.

    To demonstrate, we'll create a rectangle to add to our floating ball code, which we'll define to be a sensor object. If one of the floating balls enters the sensor area, it will glow, and fade again when the ball leaves the sensor. Add the code below to the floating ball example to see the effect.
    local sensorArea = display.newRect( w/2, h/2, w/2, h/2 )
       sensorArea.isVisible = false
       physics.addBody( sensorArea )
       sensorArea.isSensor = true
        
    local function onCollision( self, event )
       if (event.phase == "began") then
          transition.to( event.other, {alpha = 1, time = 300})
       elseif (event.phase == "ended") then
          transition.to( event.other, {alpha = 0.2, time = 300})
       end
    end
    
    sensorArea.collision = onCollision
    sensorArea:addEventListener( "collision", sensorArea )	

Example: Flick Hockey

The code below creates a hockey game. Tap the "ice" to create a puck. Then, grab the puck and flick it toward the goal. If the puck moves into the goal sensor, you'll score a point. Otherwise, the score will not change.
local physics = require("physics")
	physics.start()
	physics.setGravity( 0, 0 )

local bg, goal, goalLine, goalText, score, post1, post2

local w, h = display.contentWidth, display.contentHeight

bg = display.newRect( w/2, h/2, w, h )

goal = display.newRect( w/2, 100, 400, 200 )
	goal:setFillColor( 0.9, 0.9, 0.9 )
physics.addBody( goal, { isSensor = true } )
	
goalLine = display.newLine( 0, 200, w, 200 )
	goalLine.width = 6
	goalLine:setStrokeColor( 1, 0, 0 )
	
post1 = display.newRoundedRect( w/2 - 206, 100, 10, 230, 5)
	post1:setFillColor( 0, 0, 0 )
physics.addBody( post1, "static" )

post2 = display.newRoundedRect( w/2 + 206, 100, 10, 230, 5)
	post2:setFillColor( 0, 0, 0 )
physics.addBody( post2, "static" )
	
score = 0

goalText = display.newText( "Goals: 0", w/2, h - 50, Arial, 40 )
	goalText:setFillColor( 0, 0, 0 )
	
	
local function dragBody( event )
    local body = event.target
    local phase = event.phase
    local stage = display.getCurrentStage()

    if "began" == phase then
        stage:setFocus( body, event.id )
        body.isFocus = true
        body.tempJoint = physics.newJoint( "touch", body, event.x, event.y )
    elseif body.isFocus then
        if "moved" == phase then
			body.tempJoint:setTarget( event.x, event.y )
        elseif "ended" == phase or "cancelled" == phase then
            stage:setFocus( body, nil )
            body.isFocus = false
            
            body.tempJoint:removeSelf()    
        end
    end

    return true
end		
	
function makePuck( event )
	newPuck = display.newCircle( event.x, event.y, 35 )
		newPuck:setFillColor( 0, 0, 0 )
		newPuck.strokeWidth = 6
		newPuck:setStrokeColor( 0.2, 0.2, 0.2 )
	physics.addBody( newPuck, { density = 0.5, friction = 0.1, bounce = 0.2, radius = 35 })
	newPuck:addEventListener( "touch", dragBody )
	
	return true
end

bg:addEventListener( "tap", makePuck )

local function onCollision( event )
	if event.phase == "began" then
		if event.object1 == goal or event.object2 == goal then score = score + 1 end
		goalText.text = "Goals: "..score
	end 
	return true
end
 
Runtime:addEventListener( "collision", onCollision )