cocoscreator 對象池管理多個節點使用

  1. 上次介紹對象池簡單使用,只限以單個節點的對象池管理,但我們在開發遊戲時;往往有多個預製體 創建與刪除;那麼上篇介紹對象池管理就有很大侷限性。因此我們要想辦法對象池管理多個節點
  2. 首先我們目要知道: 對象可以幫助提高遊戲性能,優化對象的反覆創建和銷燬。
  3. 運用知識點:Pool 類型使用 文檔地址: https://docs.cocos.com/creator/api/zh/classes/Pool.html#constructor

屬性: count Number 當前可用對象數量,一開始默認是 0,隨著對象的回收會逐漸增大,最大不會超過調用構造函數時指定的 size。

方法: constructor 使用構造函數來創建一個指定對象類型的對象池,您可以傳遞一個回調函數,用於處理對象回收時的清理邏輯。

get 獲取並初始化對象池中的對象。

_get 獲取對象池中的對象,如果對象池沒有可用對象,則返回空。

put 向對象池返還一個不再需要的對象。

resize 設置對象池容量。

運用上面知識點做了一個例子:

cocoscreator 對象池管理多個節點使用

例子介紹:add1 和 add2 分別 控制兩個 藍色預製體 和 紅色預製體;當點擊其中一個按鈕, 屏幕上 就會顯示 藍和紅方塊,方塊會向左移動,移動屏幕時就會回收節點;並把節點回收到對象池中,下次創建時如果對象池中有藍節點就會取出藍色節點,沒有就會 cc.instantiate創建;實現如下:

<code>//Global.js  為了測試效果 增加一個全局js文件
window.Global = {
// 對象池管理
poolObj:null,
// 對象池中的節點 增加
pool2:null,

}/<code>
<code>//  but1.js  藍色預製體 每一個預製體 綁定個 js 腳本
cc.Class({
extends: cc.Component,
onLoad () {
this.speedX = 100;
},
update (dt) {
this.node.x += -this.speedX * dt
// 當前節點轉換成世界座標
var xMax = this.node.getBoundingBoxToWorld().xMax;
if( xMax < 0 ){
// 回收腳本組件
Global.poolObj.desObj(this);
// 更新 藍色數量 和對象池中數量
Global.pool2.showLableText();
}
},
});/<code>
<code>// but2.js   紅色預製體 每一個預製體 綁定個 js 腳本
cc.Class({
extends: cc.Component,
onLoad () {
this.speedX = 100;
},
update (dt) {
this.node.x += -this.speedX * dt
// 當前節點轉換成世界座標
var xMax = this.node.getBoundingBoxToWorld().xMax;
if( xMax < 0 ){
// 回收腳本組件
Global.poolObj.desObj(this)
// 更新 藍色數量 和對象池中數量
Global.pool2.showLableText();
}
},
});/<code>
<code>
cc.Class({
extends: cc.Component,
onLoad () {
// 保存到 全局
window.Global.poolObj = this

/**
* https://docs.cocos.com/creator/api/zh/classes/Pool.html#constructo
* 1. 創建 對象池 實例
*/
this.pool = new cc.js.Pool(function(){
// 節點有回收則觸發回調,開始設定對象池內容有 10 個
cc.log("clear node。。。")
},10);
// 獲取並初始化對象池中的對象。這個方法默認為空,需要用戶自己實現
this.pool.get = this.getInitObj;
},

// 獲取並初始化 對象池

getInitObj:function( jsTypeObj ){
// 設置一個標識 對象池是否找到 腳本組件
let isTrue = false;
// 臨時數給 ,用於存放從 池中取出的腳本組件
let arr = new Array;
let obj = null;
for(let i=1; i<=this.count;i++){
\t\t\t// 從節點池中取出一個腳本組件對象
\t\t\t obj = this._get()
\t\t\tif( obj instanceof jsTypeObj ){
isTrue = true;
break;
}else{
arr.push(obj);
}

\t\t\t
}
// 遍歷臨時數組,將數組中的腳本對象返還給對象池
arr.forEach(o => {
this.put(o)
});

if( isTrue ){
return obj;
}
\t return null;
},

// 三個參數:prefab 預製體 jsTypeObj js腳本對象 parentNode 父節點
\tgetObj:function( prefab,jsTypeObj,parentNode){
\t\t// 對象池中獲取腳本對象 調用 get 方法;則調用 getInitObj 方法
\t\tvar jsObj = this.pool.get( jsTypeObj )
// 判斷對象池是否有腳本對象,沒有則創建
\t\tif( !jsObj ){
jsObj = cc.instantiate(prefab).getComponent(jsTypeObj)\t
console.log(" instantiate.... ")
}


// 掛在父節點上
\t\tif( parentNode ){
jsObj.node.x = 200;
jsObj.node.parent = parentNode
}
\t\treturn jsObj;
},

// 刪除節點池中腳本對象
\tdesObj:function( jsObj ){
jsObj.node.removeFromParent();
// 放入對象池中
this.putInPool( jsObj );
},

// 放入對象池中
putInPool : function( jsObj ){
this.pool.put(jsObj);
},

// 獲取 對象池中 籃色腳本組件數
getJsNum:function( jsTypeObj ){

let num = 0;
let arr = new Array;

let count = this.pool.count;

for(let i=1; i<=count;i++){
\t\t\t// 從節點池中取出一個腳本組件對象
\t\t\tlet obj = this.pool._get()
\t\t\tif( obj instanceof jsTypeObj ){
num = num + 1;
}

if( obj != null ){
arr.push(obj);
}
}
// 遍歷臨時數組,將數組中的腳本對象返還給對象池
arr.forEach(o => {
this.pool.put(o)

});

return num+"|對象池數:"+this.pool.count;
}
// update (dt) {},
});
/<code>
<code>// pool2.js 全局都可以調用
var But1 = require("but1");
var But2 = require("but2");
cc.Class({
extends: cc.Component,
properties: {
but1Prefab : cc.Prefab,
but2Prefab :cc.Prefab,

but1Lable :cc.Label,
but2Lable :cc.Label,
},

onLoad () {
window.Global.pool2 = this
},
onClickBut:function( target,val ){

switch(val){
case 'but1' :
// 創建
Global.poolObj.getObj(this.but1Prefab,But1,this.node);
this.showLableText();
break;
case 'but2' :
Global.poolObj.getObj(this.but2Prefab,But2,this.node);
this.showLableText();
break;

}
},

showLableText:function(){
this.but1Lable.string = " 籃色對象池數:"+ Global.poolObj.getJsNum(But1);
this.but2Lable.string = " 紅色對象池數:"+ Global.poolObj.getJsNum(But2);
}
});/<code>


cocoscreator 對象池管理多個節點使用


分享到:


相關文章: