Corona includes a robust
There are a few ways to detect collisions without using physics, including:
The first method can be complex if the rectangle has any rotation applied to it, and the separating axis theorem is fairly
Before considering
In some games, even objects that aren’t artistically circular can often have their collision boundaries represented by a circle, for instance a circle that encloses the entire image or alternatively spans a slightly smaller area around the “center” of the object. During fast gameplay, the player probably won’t notice exact

Some very simple calculations can determine if any two circles of arbitrary sizes are overlapping:
local function hasCollidedCircle( obj1, obj2 )
if ( obj1 == nil ) then -- Make sure the first object exists
return false
end
if ( obj2 == nil ) then -- Make sure the other object exists
return false
end
local dx = obj1.x - obj2.x
local dy = obj1.y - obj2.y
local distance = math.sqrt( dx*dx + dy*dy )
local objectSize = (obj2.contentWidth/2) + (obj1.contentWidth/2)
if ( distance < objectSize ) then
return true
end
return false
end
For this function, we simply pass in two display objects, obj1 and obj2. Using the contentWidth property to determine their width, we check if the two circles are closer than the distance of their centers and, if so, we know that they’re touching.
Overlapping rectangles are even easier to detect, using Corona’s contentBounds properties:
local function hasCollidedRect( obj1, obj2 )
if ( obj1 == nil ) then -- Make sure the first object exists
return false
end
if ( obj2 == nil ) then -- Make sure the other object exists
return false
end
local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin
local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax
local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin
local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax
return ( left or right ) and ( up or down )
end
This function works great for square or rectangular objects like tiles and cards. It uses a set of if statement checks to see if any corner of one rectangle is inside the bounds of the other rectangle.
For images that have some transparency around them, note that this will include the transparent areas since the function uses the content bounds of those images. If necessary, you can adjust the math in the comparisons, for instance add or subtract a pixel value to/from the various “min” and “max” properties to account for the width of the transparency.
Now that you have a couple different ways to determine if two items have collided, how can you use them? Unlike
Perhaps the most obvious method is to use an "enterFrame" Runtime listener as follows:
As a
As a listener method which you toggle on and off as needed, for example only when the player is
Consider this example function which assumes that you have a myPlayer object and multiple coin objects stored in a table named coinCache. Assuming the player can also use coinCache table on each frame and checks if the player has come into contact with any coins:
local function gameLoop( event )
for i = 1,#coinCache do
-- Check for collision between player and this coin instance
if ( coinCache[i] and hasCollidedCircle( myPlayer, coinCache[i] ) ) then
-- Remove the coin from the screen
display.remove( coinCache[i] )
-- Remove reference from table
coinCache[i] = nil
-- Handle other collision aspects like increasing score, etc.
end
end
return true
end
Runtime:addEventListener( "enterFrame", gameLoop )
That concludes our tutorial on
Character art in this tutorial is courtesy of Kenney. Kenney game studio supports other developers by creating free game assets and high quality learning material.