SoFunction
Updated on 2025-03-03

How to use CocosCreator object pool

Preface:

Creating ( ) and destroying ( ) nodes at runtime is very performance-consuming. Therefore, in relatively complex scenarios, we usually only create nodes in the scene initialization logic (onLoad), and only destroy nodes when switching scenes. If we create action games that have a large number of enemies or bullets that need to be repeatedly generated and destroyed, how do we create and destroy nodes at any time during the game? This requires the help of object pools.

An object pool is a set of recyclable node objects. We initialize a node's object pool through the instances we create. Usually when we have multiple prefabs that need to be instantiated, we should create an instance for each prefab.

When we need to create a node, we apply for a node from the object pool. If there are free nodes in the object pool, we will return the node to the user. The user adds this new node to the scene node tree.
When we need to destroy a node, we call the put(node) method of the object pool instance and pass in the node instance that needs to be destroyed. The object pool will automatically complete the operation of removing the node from the scene node tree and then return it to the object pool.

This enables the recycling of a few nodes.

Specific operations

Step 1: Prefab ready

Set up the nodes you want to create in advance and make them into Prefab resources. Some friends may not be able to create prefabs?
(Just pull the resource in the resource manager into the hierarchical manager and then pull the node back to the resource manager)
This completes the creation of the prefabricated body!

Step 2: Initialize the object pool

In the initialization script for scene loading, we can create the number of nodes that need to be created and put into the object pool:

properties: {
    enemyPrefab:   // The required prefabricated body},
onLoad: function () {
    // Create an object pool     = new ();
    
    let initCount = 5;
    for (let i = 0; i < initCount; ++i) {
        let enemy = (); // Create node        (enemy); // Put into the object pool through the put interface    }
}

The number of initial nodes required in the object pool can be controlled according to the needs of the game. It doesn't matter if our estimate of the number of initial nodes is inaccurate, and we will process it later.

Step 3: Request an object from the object pool

Next, in our runtime code, we can obtain the objects stored in the object pool in the following way:

createEnemy: function (parentNode) {
    let enemy = null;
    if (() > 0) { // Use the size interface to determine whether there are free objects in the object pool        // get() get object        enemy = ();
        
    } else { // If there are no free objects, that is, if there are not enough spare objects in the object pool, we will use        enemy = ();
    }
     = parentNode; // Add the generated enemies to the node tree    ('Enemy').init(); //The next step is to call the script on enemy for initialization}

The key point of safely using object pool is that before getting the object, you must always use size to determine whether there are available objects. If not, use the normal method of creating nodes. Although it will consume some runtime performance, it is better than a game crash! Another option is to call get directly. If there are no available nodes in the object pool, null will be returned, and it is also OK to make judgments at this step.

Step 4: Return the object to the object pool

When we kill the enemy, we need to return the enemy node to the object pool in case we continue to recycle it later. We use this method:

onEnemyKilled: function (enemy) {
    // enemy should be a    (enemy); // Like the initialization method, put the node into the object pool. This method will call the node's removeFromParent at the same time.}

In this way, we complete a complete loop, and it will be no problem how many monsters the protagonist needs to brush! The operation of putting nodes into and taking out the object pool will not bring additional memory management overhead, so you should try to make use of them as much as possible.

Step 5: Use components to handle recycling and reuse events

When creating an object pool using the constructor, you can specify a component type or name as a component mounted on a node to handle node recycling and reuse events.

You can use:

 let menuItemPool = new ('MenuItem');  // Specify a component type

In this way, when using () to obtain the node, the reuse method in MenuItem will be called to complete the registration of the click event.
When the node is recycled using (menuItemNode), the unuse method in MenuItem will be called to complete the anti-registration of the click event.

({
    extends: ,
    onLoad: function () {
         = false;
        (.TOUCH_END, , );
    },
    // put() will be called when retrieving the object pool    unuse: function () {
        (.TOUCH_END, , );
    },
    // Get() will be called when getting the object in the object pool    reuse: function () {
        (.TOUCH_END, , );
    }
});

In addition () You can pass in any number of parameters of type, and these parameters will be passed to the reuse method as is:

// 
let myBulletPool = new ('Bullet'); //Create a bullet object poollet newBullet = (this); // Pass in an instance of the manager, which is used to recover bullets in the bullet script later
// 
reuse (bulletManager) {
     = bulletManager; // The management class instance passed in get}
hit () {
    (); //Recycle bullets through the previously passed management instance}

Step 6: Clear the Object Pool

If the nodes in the object pool are no longer needed, we can manually clear the object pool and destroy all nodes cached in it:

(); // Call this method to clear the object pool

When the object pool instance is no longer referenced anywhere, the engine's garbage collection system will automatically destroy and recycle nodes in the object pool. However, the time point of this process is uncontrollable. In addition, if the nodes in it are referenced by other places, it may also lead to memory leakage. Therefore, it is best to manually call the clear method when switching scenes or when other objects are no longer needed to clear the cache nodes.

The above is the detailed content of how to use the CocosCreator object pool. For more information about the CocosCreator object pool, please follow my other related articles!