Although Corona's Box2D-powered physics engine can easily simulate x and y directional gravity, radial gravity isn't built-in functionality. Fortunately, it can be accomplished relatively easily using standard physics collision events and a touch joint.

For those who don't know what radial gravity is, it's essentially like the simulated gravitational pull of a planet, or a magnet pulling outlying metal objects toward it. This tutorial will outline how to build a basic radial gravity simulation with properties that can be easily altered, including the size and strength of the gravitational field.

## Test Project Setup

For purposes of this tutorial, let's quickly create a test project:

1. Open the Corona Simulator.

2. Click New Project from the welcome window or select New Project... from the File menu.

3. For the project/application name, type `RadialGravity` and ensure that the Blank template option is selected. Leave the screen size settings at default but set Default Orientation to Sideways, then click OK (Windows) or Next (Mac). This will create the basic files for the test project in the location (folder) that you specified.

4. Locate the project folder, open the `main.lua` file in your chosen text editor, then insert these lines of code:

```local physics = require( "physics" )
physics.start()  -- Start the physics engine
physics.setGravity( 0, 0 )  -- Set "space" gravity
math.randomseed( os.time() )  -- Seed the pseudo-random number generator

-- Set radial gravity simulation values
local fieldPower = 0.4```

The first step is to create the gravitational field that will exert a pull force on objects that enter it. In Corona, we can create this field as a simple radial body set as a sensor. In your project, add the following lines:

```local field = display.newCircle( display.contentCenterX, display.contentCenterY, fieldRadius )
field.alpha = 0.2

-- Add physical body (sensor) to field

## Objects Colliding With Field

The common method behind other objects being affected by radial gravity is their collision with this field. Essentially, when an object enters the field — collision phase of `"began"` — we'll create a physics touch joint between the object and the center of the field. Similarly, if an object exits the field (collision phase of `"ended"`), we'll break (remove) the touch joint and let the object go about its normal physical behavior.

### Objects Entering Field

First, let's add the following code to the project to handle objects which enter the gravitational field:

```local function collideWithField( self, event )

local objectToPull = event.other

if ( event.phase == "began" and objectToPull.touchJoint == nil ) then

-- Create touch joint after short delay (10 milliseconds)
timer.performWithDelay( 10,
function()
-- Create touch joint
objectToPull.touchJoint = physics.newJoint( "touch", objectToPull, objectToPull.x, objectToPull.y )
-- Set physical properties of touch joint
objectToPull.touchJoint.frequency = fieldPower
objectToPull.touchJoint.dampingRatio = 0.0
-- Set touch joint "target" to center of field
objectToPull.touchJoint:setTarget( self.x, self.y )
end
)
end
end
field.collision = collideWithField

Inspecting this in more detail, we do the following:

1. First, with `local objectToPull = event.other`, we create a local reference to the object which collided with the field.

2. With the first conditional check, we confirm that the `"began"` phase has occurred and that the object doesn't already have a touch joint applied (this second condition is simply an additional fail-safe).

3. After a short timer delay (see notes below), we add a touch joint to the object, set the basic joint properties, and then set its target to the center of the gravitational field (`self.x`/`self.y`).

Notes
• Because certain physical actions like creating joints can't be done in the exact same time step as a collision, we must do so following a short timer (here, 10 milliseconds). For simplicity, we use an anonymous function inside the `timer.performWithDelay()` call to create the touch joint.

• In the case of a touch joint, you don't actually join the object to another object as you would with most physical joints. For this joint type, the "target" is simply a point in world coordinates.

### Objects Exiting Field

So that the gravitational field doesn't maintain permanent control over objects which exit its radius, we need to add some code to break (remove) the object's touch joint.

In your project, add the following code inside the existing `collideWithField()` function:

```local function collideWithField( self, event )

local objectToPull = event.other

if ( event.phase == "began" and objectToPull.touchJoint == nil ) then

-- Create touch joint after short delay (10 milliseconds)
timer.performWithDelay( 10,
function()
-- Create touch joint
objectToPull.touchJoint = physics.newJoint( "touch", objectToPull, objectToPull.x, objectToPull.y )
-- Set physical properties of touch joint
objectToPull.touchJoint.frequency = fieldPower
objectToPull.touchJoint.dampingRatio = 0.0
-- Set touch joint "target" to center of field
objectToPull.touchJoint:setTarget( self.x, self.y )
end
)

elseif ( event.phase == "ended" and objectToPull.touchJoint ~= nil ) then

objectToPull.touchJoint:removeSelf()
objectToPull.touchJoint = nil
end
end```

This addition is simple: in the `"ended"` collision phase, we remove the touch joint, effectively allowing the object to continue on with its normal physical behavior.

## Generating Objects

Let's complete our project by generating 5 objects which approach the gravitational field at random speeds. Add the following code to your project following the previous lines:

```for i = 1,5 do

local object = display.newCircle( 0, (i*50)+10, 10 )
To test behavior variations, change the `fieldPower` variable value near the beginning of the project to something higher or lower. A lower value like `0.2` will make the field's pull more gentle, while a higher value like `0.8` will pull objects very strongly toward the center.