This tutorial is a brief discussion of how to handle collisions between LiquidFun particles and Box2D rigid bodies. Handling these collisions is essential to implementing a more comprehensive and responsive scenario using LiquidFun physics.

If you missed the previous Introduction to LiquidFun tutorial, please read it carefully so that you fully understand LiquidFun and the basis of the system.

Basic Setup

For this tutorial, we’ll need to create, at the minimum, a particleSystem and another object with which the particles can collide:

local physics = require( "physics" )

-- Create a platform
local platform = display.newRect( 0, 0, 160, 60 )
platform.myName = "Platform"
platform.x, platform.y = display.contentCenterX, 350
platform.rotation = 10
platform:setFillColor( 1 )
physics.addBody( platform, "static" )

-- Create the particle system
local particleSystem = physics.newParticleSystem{
   filename = "particle.png",
   radius = 3,
   imageRadius = 6
particleSystem.myName = "myParticleSystem"

-- Paramaters for particle faucet
local particleParams =
   flags = { "water", "fixtureContactListener" },
   velocityX = 40,
   velocityY = -200,
   color = { 0, 0.3, 1, 1 },
   x = display.contentCenterX-80,
   y = 200

-- Timer to generate particles
local function onTimer()
   particleSystem:createParticle( particleParams )
timer.performWithDelay( 20, onTimer, 5 )

This is fairly basic code. First, we create a static platform for the particles to collide with and rotate it to 10 degrees so we can watch the liquid particles flow off it. Then we create the particleSystem and assign it a .myName parameter which will help us identify the system when detecting collisions.

Next we create the particleParams table with some basic properties. This doesn’t vary too much from the examples in the previous tutorial except for the inclusion of one very important flag: "fixtureContactListener". If you don’t include this flag, you will not receive collision responses.

Finally we queue a timer to generate 5 particles at an increment of 20 milliseconds.

Particle System Collision Handling

Now let’s set up a function to listen for collision events on the actual particleSystem. This is similar to the method of local collision handling between traditional physical objects described here — in this case, we just need to set up the function, set its name as the .particleCollision property of the particleSystem, and then add an event listener of the "particleCollision" type to the system:

local function particleSystemCollision( self, event )

   --print( "Collision with particleSystem." )
   if ( event.phase == "began" ) then


particleSystem.particleCollision = particleSystemCollision
particleSystem:addEventListener( "particleCollision" )

This provides you with a very basic collision framework, but in most cases you’ll need more information to properly react to particle collisions. Fortunately, Corona provides a considerable amount of information as properties of the event table of the listener function. These include:

  • event.phase — One of the typical collision phases of "began" or "ended".
  • event.object — Reference to the object that the particle collided with.
  • event.element — The fixture index of the other object, relevant for multi-element bodies.
  • event.particleSystem — Reference to the parent ParticleSystem of the colliding particle.
  • event.x — The x position (screen content coordinates) of the particle that’s involved in the collision.
  • event.y — The y position (screen content coordinates) of the particle that’s involved in the collision.
  • event.normalX — The collision normal’s x direction.
  • event.normalY — The collision normal’s y direction.
  • event.r — The red color value of the particle.
  • event.g — The green color value of the particle.
  • event.b — The blue color value of the particle.
  • event.a — The alpha color value of the particle.

For future reference, a list of these properties are documented here, so please bookmark the link if you intend to utilize LiquidFun in depth.

Object Collision Handling

Alternatively, you can detect collisions on other objects instead of directly on the particle system. This may be more logical if you’re designing an app with multiple particle systems and you prefer to detect collisions with one core object like a player character.

In our existing example, we can achieve this by adding a collision listener to the platform object instead of the particle system. Inspect the difference:

function platform:particleCollision( event )

   --print( "Collision with object." )
   if ( event.phase == "began" ) then
      print( "phase: " .. event.phase )
      print( "body: " .. event.object.myName )
      print( "particleSystem: " .. event.particleSystem.myName )

platform:addEventListener( "particleCollision" )

Conveniently, this model also provides the same event table properties listed above, so you can gather info about the specific particle involved in the collision, including the particle system which generated it.

Global Collision Handling

Yet another option to handle collisions is a global Runtime listener. This will detect collisions between particles and other physical objects at the global level.

local function onGlobalCollision( event )

   --print( "Global collision." )
   if ( event.phase == "began" ) then
      print( "phase: " .. event.phase )
      print( "body: " .. event.object.myName )
      print( "particleSystem: " .. event.particleSystem.myName )

Runtime:addEventListener( "particleCollision", onGlobalCollision )

In Summary

Hopefully this tutorial has illustrated how simple it is to detect collisions between LiquidFun particles and other physical objects. This feature should help take your liquidFun-based apps to the next level of interactivity.

    • Hi,

      since 2359 the LiquidFun particles are now fully integrated into the display groups, I already experimented with this and I love it!


Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>