您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關怎么使用CocosCreator對象池,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
把你想要創建的節點事先設置好并做成 Prefab 資源,有些朋友可能不會制作預制體?
(只需要將資源管理器里的資源 拉拽到 層級管理器中 然后 將節點在拉拽回 資源管理器)
這樣就完成預制體的創建了!
在場景加載的初始化腳本中,我們可以將需要數量的節點創建出來,并放進對象池:
properties: { enemyPrefab: cc.Prefab // 所需要的預制體 }, onLoad: function () { // 創建對象池 this.enemyPool = new cc.NodePool(); let initCount = 5; for (let i = 0; i < initCount; ++i) { let enemy = cc.instantiate(this.enemyPrefab); // 創建節點 this.enemyPool.put(enemy); // 通過 put 接口放入對象池 } }
對象池里需要的初始節點數量可以根據游戲的需要來控制,即使我們對初始節點數量的預估不準確也不要緊,后面我們會進行處理。
接下來在我們的運行時代碼中就可以用下面的方式來獲得對象池中儲存的對象了:
createEnemy: function (parentNode) { let enemy = null; if (this.enemyPool.size() > 0) { // 通過 size 接口判斷對象池中是否有空閑的對象 // get()獲取對象 enemy = this.enemyPool.get(); } else { // 如果沒有空閑對象,也就是對象池中備用對象不夠時,我們就用 cc.instantiate 重新創建 enemy = cc.instantiate(this.enemyPrefab); } enemy.parent = parentNode; // 將生成的敵人加入節點樹 enemy.getComponent('Enemy').init(); //接下來就可以調用 enemy 身上的腳本進行初始化 }
安全使用對象池的要點就是在 get 獲取對象之前,永遠都要先用 size 來判斷是否有可用的對象,如果沒有就使用正常創建節點的方法,雖然會消耗一些運行時性能,但總比游戲崩潰要好!另一個選擇是直接調用 get ,如果對象池里沒有可用的節點,會返回 null ,在這一步進行判斷也可以。
當我們殺死敵人時,需要將敵人節點退還給對象池,以備之后繼續循環利用,我們用這樣的方法:
onEnemyKilled: function (enemy) { // enemy 應該是一個 cc.Node this.enemyPool.put(enemy); // 和初始化時的方法一樣,將節點放進對象池,這個方法會同時調用節點的 removeFromParent }
這樣我們就完成了一個完整的循環,主角需要刷多少怪都不成問題了!將節點放入和從對象池取出的操作不會帶來額外的內存管理開銷,因此只要是可能,應該盡量去利用。
使用構造函數創建對象池時,可以指定一個組件類型或名稱,作為掛載在節點上用于處理節點回收和復用事件的組件。
在創建對象池時可以用:
let menuItemPool = new cc.NodePool('MenuItem'); // 指定一個組件類型
這樣當使用 menuItemPool.get() 獲取節點后,就會調用 MenuItem 里的 reuse方法,完成點擊事件的注冊。
當使用menuItemPool.put(menuItemNode)回收節點后,會調用 MenuItem 里的 unuse方法,完成點擊事件的反注冊。
cc.Class({ extends: cc.Component, onLoad: function () { this.node.selected = false; this.node.on(cc.Node.EventType.TOUCH_END, this.onSelect, this.node); }, // put() 收回對象池時會調用 unuse: function () { this.node.off(cc.Node.EventType.TOUCH_END, this.onSelect, this.node); }, // get()獲取對象池內對象時會調用 reuse: function () { this.node.on(cc.Node.EventType.TOUCH_END, this.onSelect, this.node); } });
另外 cc.NodePool.get() 可以傳入任意數量類型的參數,這些參數會被原樣傳遞給 reuse 方法:
// BulletManager.js let myBulletPool = new cc.NodePool('Bullet'); //創建子彈對象池 let newBullet = myBulletPool.get(this); // 傳入 manager 的實例,用于之后在子彈腳本中回收子彈 // Bullet.js reuse (bulletManager) { this.bulletManager = bulletManager; // get 中傳入的管理類實例 } hit () { this.bulletManager.put(this.node); // 通過之前傳入的管理類實例回收子彈 }
如果對象池中的節點不再被需要,我們可以手動清空對象池,銷毀其中緩存的所有節點:
myPool.clear(); // 調用這個方法就可以清空對象池
當對象池實例不再被任何地方引用時,引擎的垃圾回收系統會自動對對象池中的節點進行銷毀和回收。但這個過程的時間點不可控,另外如果其中的節點有被其他地方所引用,也可能會導致內存泄露,所以最好在切換場景或其他不再需要對象池的時候手動調用 clear 方法來清空緩存節點。
以上就是怎么使用CocosCreator對象池,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。