GBC Object Pool – Pooling Complex Physics Objects

GBC Object Pool is a CoronaSDK plugin that simplifies the management of Object Pooling. In this article, I describe the method to pool complex physics objects.

A complex physics object consists of several display objects connected together by a physics joint. I recently added another example to the GBC Object Pool sample app that demonstrates how to pool complex physics objects. This article will go through some of the code in that example.

Using the traditional way of object creation, you would need to create multiple objects and joints in order to display a complex physics object. Depending on the complexity of this object, there may be visible performance issues (screen stutter or delay) when creating these types of objects. Utilizing object pooling will reduce or eliminate this delay.

The general solution is to create as many pools that are needed in order to create the object, and then join them via joints after you extract them from the pool. For example, connecting similar items may only require one pool. In the example, though, we connect three circles to a square, so I created two pools… every time we wish to display this type of complex object (when we tap on the screen), we grab one square from the square pool and three circles from the circle pool, and join them together.

squarePool = GBCObjectPool.init(createMainObject, returnMainObject)
GBCObjectPool.create(squarePool, 10, 0, true) 
        
circlePool = GBCObjectPool.init(createSatellite, returnSatellite)
GBCObjectPool.create(circlePool, 100, 0, true)

-- This creates a complex object using multiple pools when the screen is touched.
-- We grab 1 object from the square pool, and 3 objects from the 
-- circle pool.
-- Notice, we then create the proper joints, and event listeners.
-- We also have to save a reference to the joints and the circles so that
-- they can be returned to the pool later.
function onScreenTap(event)
    local Circles = {}
    local Joints = {}
    
    local square = GBCObjectPool.get(squarePool)
    
    for i = 1, 3 do
        Circles[i] = GBCObjectPool.get(circlePool)
    end
    
    square.x = event.x
    square.y = event.y
    Circles[1].x = square.x - 70
    Circles[1].y = square.y
    Circles[2].x = square.x + 70
    Circles[2].y = square.y
    Circles[3].x = square.x + 5
    Circles[3].y = square.y + 70
    
    Joints[1] = physics.newJoint("rope", square, Circles[1], 0, 0, 0, 0)
    Joints[2] = physics.newJoint("rope", square, Circles[2], 0, 0, 0, 0)
    Joints[3] = physics.newJoint("rope", square, Circles[3], 0, 0, 0, 0)
    
    -- Save a reference to all the joints and circles in the square object
    -- We will need this later when placeing back into the pool
    square.satellites = Circles
    square.joints = Joints    
    
    square:addEventListener("tap", onSquareTap)
    
    return true
end

We need a way to track all the objects used, so we can return them to the pool later. Notice above, we save a reference to the joints and circles in the square object itself. Since the square object will contain a listener that will start removing everything when tapped, it’s a great place to store it.

The code below is the listener that is called when you tap the square. This function will dismantle the complex object and return the parts to their appropriate pool.

-- When you tap on the square object, the entire complex object
-- is returned to the proper pools.
-- Note that since we are not destroying objects (we are pooling them)
-- we have to manually remove and nil all physics joints, since we created them
-- when we created this complex object.
function onSquareTap(event)
    local object = event.target
    
    -- remove the physics joints
    for i = #object.joints, 1, -1 do
        display.remove(object.joints[i])
        object.joints[i] = nil
    end
    
    -- put the circles back into the pool
    for i = #object.satellites, 1, -1 do
        GBCObjectPool.put(circlePool, object.satellites[i])
    end
    
    -- nil out the joint and circle variables
    object.satellites = nil
    object.joints = nil
    
    -- remove listener from square
    object:removeEventListener("tap", onSquareTap)
    
    -- place square into pool
    GBCObjectPool.put(squarePool, object) 
    
    return true
end

That’s really all there is to it. In summary, just remember:

  • When creating a complex object
    • Grab the objects from the pools
    • Create your physics joints
    • Store a reference to all the objects and joints used
  • To remove a complex object
    • Remove the joints using display:remove(joint) or joint:removeSelf()
    • Return all items to the appropriate pools

[divider]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: