一、項目結構
ProjectName(新建項目)
├──assets
├──library
├──local
├──packages
├──settings
├──temp
└──project.json
子結構 | 功能 |
---|---|
assets | 與資源管理器的內容同步,游戲的核心目錄(每個文件都有相應.meta文件) |
library | 這里文件的結構和資源的格式將被處理成最終游戲發布時需要的形式 |
local | 編輯器使用習慣記錄(如:窗體布局) |
settings | 項目設置 |
project.json | 版本控制,必須與assets共同存在 |
build | 打包導出目錄,構建項目時,自動生成 |
PS:.meta文件——記錄某資源在項目中的唯一標識,以及其配置信息,只有在編輯器中對資源做修改,.meta文件才會實時變化。因此,不要在編輯器外,對資源的內容進行操作。
二、資源分類
1、場景(scene)
自動釋放資源:切換場景后,上一個場景中的資源,從內存中釋放。
延遲加載資源:意味着不用等待所有資源加載完畢,才顯示場景。(快速切換場景,資源陸續在畫面顯示)
2、貼圖(texture)
普通圖,子層為一張spriteFrame。
3、預制(prefab)
創建方式:拖拽場景節點,到資源管理器。
4、圖集(atlas)
精靈圖,子層為多張spriteFrame。(精靈圖合成軟件:TexturePacker、Zwoptex)
5、自動圖集(auto-atlas)
打包時,將所在目錄中的所有碎圖,合成為圖集。
6、藝術數字(label-atlas)
數字為內容的圖集。
7、字體(font)
動態字體:.ttf
位圖字體:.fnt + .png(存在於同一目錄)
8、粒子(particle)
小型動畫
9、聲音(audio)
模式:web audio、dom audio
10、骨骼動畫(spine / dragonBones)
文件格式 | 功能 |
---|---|
.json | 骨骼數據 |
.png | 圖集紋理 |
.txt / .atlas | 圖集數據 |
11、瓦片圖(tiledMap)
文件格式 | 功能 |
---|---|
.tmx | 地圖數據 |
.png | 圖集紋理 |
.tsx tileset | 數據配置文件 |
12、文本(text)
13、腳本(script)
14、json
三、資源小知識點
1、跨項目導入導出資源
操作流程:
(1)導出:文件 => 資源導出,選擇 .fire場景文件,輸出assets目錄的 .zip壓縮包。
(2)導入:文件 => 資源導入,選擇壓縮包源路徑、解壓路徑,輸出assets目錄內容。
2、圖像資源自動剪裁
基於size mode,盡量去除spriteFrame無像素的部分,減小圖片尺寸。
四、場景小知識點
1、場景中的元素,即是節點,可內嵌組件。
2、坐標系
類別 | 坐標軸方向 |
---|---|
cocos坐標系(世界、本地坐標系) | x右、y上、z外 |
設備屏幕坐標系 | x右、y下 |
3、錨點
作用:用於變換、子節點定位基准。
五、子系統重點
1、渲染系統
對攝像機、渲染組件的了解。
2、UI系統
對widget、layout等UI組件的了解。
3、動畫系統
(1)創建動畫的基本流程
(2)時間曲線(雙擊動畫線,進入編輯窗口)
(3)事件管理(雙擊游標、加減按鈕控制參數個數)
(4)腳本控制
4、物理系統
碰撞組件(普通碰撞)
(1)editing——是否為編輯模式
(2)regenerate points——計算圖形邊界,自定生成控制點,數值為控制點的生成密度 / 准確度
(3)ctrl + 點擊——刪除控制點
(4)組件類型:矩形、圓形、多邊形
(5)設置碰撞組(項目 => 項目設置 => 分組設置):
制定分組 => 匹配分組 => 碰撞組件所在節點上,設置所屬分組
(6)腳本控制
Box2D物理引擎(高級碰撞)
5、音頻系統
(1)audioSource組件
(2)腳本控制
六、腳本開發
1、使用 cc.Class 聲明類型
(1)定義 CCClass
var Sprite = cc.Class({
//...
});
(2)實例化
var obj = new Sprite();
(3)判斷類型
cc.log(obj instanceof Sprite); //使用原生JS的instanceof
(4)構造函數(ctor)
var Sprite = cc.Class({
//使用ctor聲明構造函數
ctor: function () {
cc.log(this instanceof Sprite);
}
});
(5)實例方法
var Sprite = cc.Class({
// 聲明一個名叫 "print" 的實例方法
print: function () { }
});
(6)繼承(extends)
// 父類
var Shape = cc.Class();
// 子類
var Rect = cc.Class({
//使用 extends 實現繼承
extends: Shape
});
(7)父構造函數
var Shape = cc.Class({
ctor: function () {
cc.log("Shape"); // 實例化時,父構造函數會自動調用,
}
});
var Rect = cc.Class({
extends: Shape
});
var Square = cc.Class({
extends: Rect,
ctor: function () {
cc.log("Square"); // 再調用子構造函數
}
});
var square = new Square();
(8)完整聲明屬性
//簡單類型聲明
properties: {
score: {
//這幾個參數分別指定了 score 的默認值為 0,在 屬性檢查器 里,其屬性名將顯示為:“Score (player)”,並且當鼠標移到參數上時,顯示對應的 Tooltip。
default: 0,
displayName: "Score (player)",
tooltip: "The score of player",
}
}
//數組聲明
properties: {
names: {
default: [],
type: [cc.String] // 用 type 指定數組的每個元素都是字符串類型
},
enemies: {
default: [],
type: [cc.Node] // type 同樣寫成數組,提高代碼可讀性
},
}
//get/set 聲明
properties: {
width: {
get: function () {
return this._width;
},
set: function (value) {
this._width = value;
}
}
}
properties常用參數
參數 | 作用 |
---|---|
default | 默認值 |
type | 限定屬性的數據類型 |
visible | 若為false,則不在屬性檢查器面板中顯示該屬性 |
serializable | 若為false,則不序列化(保存)該屬性 |
displayName | 在屬性檢查器面板中,顯示成指定名字 |
tooltip | 在屬性檢查器面板中,添加屬性的Tooltip |
2、訪問節點和組件
(1)獲得組件所在的節點
this.node
(2)獲得其它組件
this.getComponent(組件名)
(3)獲得其它節點及其組件
// Player.js
cc.Class({
extends: cc.Component,
properties: {
player: {
default: null,
type: cc.Node
}
}
});
//如果你將屬性的 type 聲明為 Player 組件,當你拖動節點 "Player Node" 到 屬性檢查器,player 屬性就會被設置為這個節點里面的 Player 組件
// Cannon.js
var Player = require("Player");
cc.Class({
extends: cc.Component,
properties: {
// 聲明 player 屬性,這次直接是組件類型
player: {
default: null,
type: Player
}
}
});
//查找子節點
//返回子節點數組
this.node.children
//返回對應的子節點
this.node.getChildByName(子節點名);
//查找后代節點
cc.find(子節點/.../后代節點, this.node);
//全局查找節點
cc.find(場景/節點/節點/...);
(4)訪問已有變量里的值(通過模塊訪問
//專門開設一個中介模塊,導出接口;在其他模塊進行節點、組件、屬性的操作
// Global.js
module.exports = {
backNode: null,
backLabel: null,
};
// Back.js
var Global = require("Global");
cc.Class({
extends: cc.Component,
onLoad: function () {
Global.backNode = this.node;
Global.backLabel = this.getComponent(cc.Label);
}
});
// AnyScript.js
var Global = require("Global");
cc.Class({
extends: cc.Component,
start: function () {
var text = "Back";
Global.backLabel.string = text;
}
});
3、常用節點和組件接口
(1)節點狀態和層級操作
//激活/關閉節點
this.node.active = true;
this.node.active = false;
//更改節點的父節點
this.node.parent = parentNode;
//索引節點的子節點
//返回子節點數組
this.node.children
//返回子節點數量
this.node.childrenCount
(2)更改節點的變換(位置、旋轉、縮放、尺寸)
//更改節點位置
//分別對 x 軸和 y 軸坐標賦值
this.node.x = 100;
this.node.y = 50;
//使用setPosition方法
this.node.setPosition(100, 50);
this.node.setPosition(cc.v2(100, 50));
//設置position變量
this.node.position = cc.v2(100, 50);
//更改節點旋轉
this.node.rotation = 90;
this.node.setRotation(90);
//更改節點縮放
this.node.scaleX = 2;
this.node.scaleY = 2;
this.node.setScale(2);
this.node.setScale(2, 2);
//更改節點尺寸
this.node.setContentSize(100, 100);
this.node.setContentSize(cc.size(100, 100));
this.node.width = 100;
this.node.height = 100;
//更改節點錨點位置
this.node.anchorX = 1;
this.node.anchorY = 0;
this.node.setAnchorPoint(1, 0);
(3)顏色和不透明度
//設置顏色
mySprite.node.color = cc.Color.RED;
//設置不透明度
mySprite.node.opacity = 128;
4)常用組件接口
cc.Component 是所有組件的基類,任何組件都包括如下的常見接口:
接口 | 作用 |
---|---|
this.node | 該組件所屬的節點實例 |
this.enabled | 是否每幀執行該組件的 update 方法,同時也用來控制渲染組件是否顯示 |
update(dt) | 作為組件的成員方法,在組件的 enabled 屬性為 true 時,其中的代碼會每幀執行 |
onLoad() | 組件所在節點進行初始化時(節點添加到節點樹時)執行 |
start() | 會在該組件第一次 update 之前執行,通常用於需要在所有組件的 onLoad 初始化完畢后執行的邏輯 |
4、生命周期
函數名 | 描述 |
---|---|
onLoad | 在節點首次激活時觸發,或者所在節點被激活的情況下觸發 |
start | 在組件首次激活前 |
update | 動畫更新前 |
lateUpdate | 動畫更新后 |
onEnable | 當組件的 enabled 屬性從 false 變為 true 時,或者所在節點的 active 屬性從 false 變為 true 時(倘若節點首次被創建且 enabled 為 true,則會在 onLoad 之后,start 之前被調用) |
onDisable | 當組件的 enabled 屬性從 true 變為 false 時,或者所在節點的 active 屬性從 true 變為 false 時 |
onDestroy | 當組件或者所在節點調用了 destroy()時 |
5、創建和銷毀節點
(1)創建新節點
cc.Class({
extends: cc.Component,
properties: {
sprite: {
default: null,
type: cc.SpriteFrame,
},
},
start: function () {
//動態創建節點,並將它加入到場景中
var node = new cc.Node('Sprite');
var sp = node.addComponent(cc.Sprite);
sp.spriteFrame = this.sprite;
node.parent = this.node;
}
});
(2)克隆已有節點
//
cc.Class({
extends: cc.Component,
properties: {
target: {
default: null,
type: cc.Node,
},
},
start: function () {
//克隆場景中的已有節點
var scene = cc.director.getScene();
var node = cc.instantiate(this.target);
node.parent = scene;
node.setPosition(0, 0);
}
});
(3)創建預制節點
//
cc.Class({
extends: cc.Component,
properties: {
target: {
default: null,
type: cc.Prefab, //預制
},
},
start: function () {
var scene = cc.director.getScene();
var node = cc.instantiate(this.target);
node.parent = scene;
node.setPosition(0, 0);
}
});
(4)銷毀節點
//
cc.Class({
extends: cc.Component,
properties: {
target: cc.Node,
},
start: function () {
// 5 秒后銷毀目標節點
//銷毀節點並不會立刻被移除,而是在當前幀邏輯更新結束后,統一執行
setTimeout(function () {
this.target.destroy();
}.bind(this), 5000);
},
update: function (dt) {
//判斷當前節點是否已經被銷毀
if (cc.isValid(this.target)) {
this.target.rotation += dt * 10.0;
}
}
});
PS:不要使用removeFromParent去銷毀節點。
原因:調用一個節點的 removeFromParent 后,它不一定就能完全從內存中釋放,因為有可能由於一些邏輯上的問題,導致程序中仍然引用到了這個對象。
6、加載和切換場景
(1)加載和切換
//從當前場景,切換到MyScene場景
cc.director.loadScene("MyScene");
(2)通過常駐節點,進行場景資源管理和參數傳遞
//常駐節點:不隨場景切換,而自動銷毀,為所有場景提供持久性信息
//設置常駐節點
cc.game.addPersistRootNode(myNode);
//取消常駐節點,還原為一般場景節點
cc.game.removePersistRootNode(myNode);
(3)場景加載回調
//fn:加載MyScene場景時觸發
cc.director.loadScene("MyScene", fn);
(4)預加載場景
//后台預加載場景
cc.director.preloadScene("MyScene", fn);
//有需要時,手動加載該場景
cc.director.loadScene("MyScene", fn);
7、獲取和加載資源
(1)資源屬性的聲明
// NewScript.js
cc.Class({
extends: cc.Component,
properties: {
//所有繼承自 cc.Asset 的類型都統稱資源,如 cc.Texture2D, cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等
texture: {
default: null,
type: cc.Texture2D
},
spriteFrame: {
default: null,
type: cc.SpriteFrame
}
}
});
(2)靜態加載(在屬性檢查器里設置資源)
// NewScript.js
onLoad: function () {
//拖拽資源管理器的資源,到屬性檢查器的腳本組件中,即可在腳本里拿到設置好的資源
var spriteFrame = this.spriteFrame;
var texture = this.texture;
spriteFrame.setTexture(texture);
}
(3)動態加載
//動態加載的資源,需要存放於assets的子目錄resources中
//加載單個資源
//cc.loader.loadRes(resources的相對路徑, 類型(可選), 回調函數)
//加載Prefab資源
cc.loader.loadRes("test assets/prefab", function (err, prefab) {
var newNode = cc.instantiate(prefab);
cc.director.getScene().addChild(newNode);
});
//加載SpriteFrame
var self = this;
cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
//批量加載資源
//cc.loader.loadResDir(resources的相對路徑, 類型(可選), 回調函數)
//加載test assets目錄下所有資源
cc.loader.loadResDir("test assets", function (err, assets) {
// ...
});
//加載test assets目錄下所有SpriteFrame,並且獲取它們的路徑
cc.loader.loadResDir("test assets", cc.SpriteFrame, function (err, assets, urls) {
// ...
});
//資源淺釋放
//cc.loader.releaseRes(resources的相對路徑, 類型(可選))
cc.loader.releaseRes("test assets/image", cc.SpriteFrame);
cc.loader.releaseRes("test assets/anim");
//cc.loader.releaseAsset(組件名)
cc.loader.releaseAsset(spriteFrame);
// 資源深釋放,釋放一個資源以及所有它依賴的資源
var deps = cc.loader.getDependsRecursively('prefabs/sample');
(4)加載遠程資源和設備資源
//加載遠程資源
//遠程 url 帶圖片后綴名
var remoteUrl = "http://unknown.org/someres.png";
cc.loader.load(remoteUrl, function (err, texture) {
//...
});
//遠程 url 不帶圖片后綴名,此時必須指定遠程圖片文件的類型
remoteUrl = "http://unknown.org/emoji?id=124982374";
cc.loader.load({url: remoteUrl, type: 'png'}, function () {
//...
});
//加載設備資源
//用絕對路徑加載設備存儲內的資源,比如相冊
var absolutePath = "/dara/data/some/path/to/image.png"
cc.loader.load(absolutePath, function () {
//...
});
加載限制:
1、原生平台遠程加載不支持圖片文件以外類型的資源。
2、這種加載方式只支持圖片、聲音、文本等原生資源類型,不支持SpriteFrame、SpriteAtlas、Tilemap等資源的直接加載和解析。(需要后續版本中的AssetBundle支持)
3、Web端的遠程加載受到瀏覽器的CORS跨域策略限制,如果對方服務器禁止跨域訪問,那么會加載失敗,而且由於WebGL安全策略的限制,即便對方服務器允許http請求成功之后也無法渲染。
(5)資源的依賴和釋放
// 直接釋放某個貼圖
cc.loader.release(texture);
// 釋放一個 prefab 以及所有它依賴的資源
var deps = cc.loader.getDependsRecursively('prefabs/sample');
cc.loader.release(deps);
// 如果在這個 prefab 中有一些和場景其他部分共享的資源,你不希望它們被釋放,可以將這個資源從依賴列表中刪除
var deps = cc.loader.getDependsRecursively('prefabs/sample');
var index = deps.indexOf(texture2d._uuid);
if (index !== -1)
deps.splice(index, 1);
cc.loader.release(deps);
8、監聽和發射事件
(1)監聽事件
//target是可選參數,用於綁定響應函數的調用者
//boolean是可選參數,默認為false,表示冒泡流
this.node.on(event, fn, target, boolean);
(2)關閉監聽
this.node.off(event, fn, target, boolean);
(3)發射事件
//為事件函數,提供參數,最多5個
this.node.emit(event, arg1, arg2, arg3);
(4)派送事件
//grandson.js
//升級版的on,冒泡到的節點,全部注冊事件
this.node.dispatchEvent( new cc.Event.EventCustom('foobar', true) );
//father.js
//在指定的上級節點中,注冊相同的事件,阻止事件冒泡,手動停止派送
this.node.on('foobar', function (event) {
event.stopPropagation();
});
(5)事件對象(回調參數的event對象)
API 名 | 類型 | 意義 |
---|---|---|
type | String | 事件的類型(事件名) |
target | cc.Node | 接收到事件的原始對象 |
currentTarget | cc.Node | 接收到事件的當前對象,事件在冒泡階段當前對象可能與原始對象不同 |
getType | Function | 獲取事件的類型 |
stopPropagation | Function | 停止冒泡階段,事件將不會繼續向父節點傳遞,當前節點的剩余監聽器仍然會接收到事件 |
stopPropagationImmediate | Function | 立即停止事件的傳遞,事件將不會傳給父節點以及當前節點的剩余監聽器 |
getCurrentTarget | Function | 獲取當前接收到事件的目標節點 |
detail | Function | 自定義事件的信息(屬於 cc.Event.EventCustom) |
setUserData | Function | 設置自定義事件的信息(屬於 cc.Event.EventCustom) |
getUserData | Function | 獲取自定義事件的信息(屬於 cc.Event.EventCustom) |
9、節點系統事件
(1)鼠標事件類型和事件對象
枚舉對象定義 | 對應的事件名 | 事件觸發的時機 |
---|---|---|
cc.Node.EventType.MOUSE_DOWN | mousedown | 當鼠標在目標節點區域按下時觸發一次 |
cc.Node.EventType.MOUSE_ENTER | mouseenter | 當鼠標移入目標節點區域時,不論是否按下 |
cc.Node.EventType.MOUSE_MOVE | mousemove | 當鼠標在目標節點在目標節點區域中移動時,不論是否按下 |
cc.Node.EventType.MOUSE_LEAVE | mouseleave | 當鼠標移出目標節點區域時,不論是否按下 |
cc.Node.EventType.MOUSE_UP | mouseup | 當鼠標從按下狀態松開時觸發一次 |
cc.Node.EventType.MOUSE_WHEEL | mousewheel | 當鼠標滾輪滾動時 |
函數名 | 返回值類型 | 意義 |
---|---|---|
getScrollY | Number | 獲取滾輪滾動的 Y 軸距離,只有滾動時才有效 |
getLocation | Object | 獲取鼠標位置對象,對象包含 x 和 y 屬性 |
getLocationX | Number | 獲取鼠標的 X 軸位置 |
getLocationY | Number | 獲取鼠標的 Y 軸位置 |
getPreviousLocation | Object | 獲取鼠標事件上次觸發時的位置對象,對象包含 x 和 y 屬性 |
getDelta | Object | 獲取鼠標距離上一次事件移動的距離對象,對象包含 x 和 y 屬性 |
getButton | Number | cc.Event.EventMouse.BUTTON_LEFT或cc.Event.EventMouse.BUTTON_RIGHT或cc.Event.EventMouse.BUTTON_MIDDLE |
(2)觸摸事件類型和事件對象
枚舉對象定義 | 對應的事件名 | 事件觸發的時機 |
---|---|---|
cc.Node.EventType.TOUCH_START | touchstart | 當手指觸點落在目標節點區域內時 |
cc.Node.EventType.TOUCH_MOVE | touchmove | 當手指在屏幕上目標節點區域內移動時 |
cc.Node.EventType.TOUCH_END | touchend | 當手指在目標節點區域內離開屏幕時 |
cc.Node.EventType.TOUCH_CANCEL | touchcancel | 當手指在目標節點區域外離開屏幕時 |
API 名 | 類型 | 意義 |
---|---|---|
touch | cc.Touch | 與當前事件關聯的觸點對象 |
getID | Number | 獲取觸點的 ID,用於多點觸摸的邏輯判斷 |
getLocation | Object | 獲取觸點位置對象,對象包含 x 和 y 屬性 |
getLocationX | Number | 獲取觸點的 X 軸位置 |
getLocationY | Number | 獲取觸點的 Y 軸位置 |
getPreviousLocation | Object | 獲取觸點上一次觸發事件時的位置對象,對象包含 x 和 y 屬性 |
getStartLocation | Object | 獲取觸點初始時的位置對象,對象包含 x 和 y 屬性 |
getDelta | Object | 獲取觸點距離上一次事件移動的距離對象,對象包含 x 和 y 屬性 |
(3)其它事件
枚舉對象定義 | 對應的事件名 | 事件觸發的時機 |
---|---|---|
無 | position-changed | 當位置屬性修改時 |
無 | rotation-changed | 當旋轉屬性修改時 |
無 | scale-changed | 當縮放屬性修改時 |
無 | size-changed | 當寬高屬性修改時 |
無 | anchor-changed | 當錨點屬性修改時 |
PS:枚舉對象定義、事件名等價,在回調參數中,作用相同。
10、全局系統事件
//全局系統事件的類型
cc.SystemEvent.EventType.KEY_DOWN //鍵盤按下
cc.SystemEvent.EventType.KEY_UP //鍵盤釋放
cc.SystemEvent.EventType.DEVICEMOTION //設備重力傳感
//綁定、解除全局系統事件
cc.systemEvent.on(event, fn, target, boolean);
cc.systemEvent.off(event, fn, target, boolean);
11、動作系統(變換系統)
(1)動作控制
// 執行動作
node.runAction(action);
// 停止一個動作
node.stopAction(action);
// 停止所有動作
node.stopAllActions();
// 給 action 設置 tag
var ACTION_TAG = 1;
action.setTag(ACTION_TAG);
// 通過 tag 獲取 action
node.getActionByTag(ACTION_TAG);
// 通過 tag 停止一個動作
node.stopActionByTag(ACTION_TAG);
(2)容器動作
//順序執行
cc.sequence(action1, action2, ...);
//並發執行
cc.spawn(action1, action2, ...);
//指定次數,重復執行
cc.repeat(action, times)
//無限次數,重復執行
cc.repeatForever(action)
//改變動作速度倍率,再執行
cc.speed(action, rate)
(3)即時動作
cc.show() //立即顯示
cc.hide() //立即隱藏
(4)時間間隔動作
cc.moveTo() //移動到目標位置
cc.rotateTo() //旋轉到目標角度
cc.scaleTo() //將節點大小縮放到指定的倍數
(5)動作回調
var finished = cc.callFunc(fn, target, arg);
(6)緩動動作
var action = cc.scaleTo(0.5, 2, 2);
//使用easeIn曲線,豐富動作表現
action.easing(cc.easeIn(3.0));
PS:可以使用緩動系統,代替動作系統。(緩動系統的API更簡約)
12、計時器
//interval:以秒為單位的時間間隔
//repeat:重復次數
//delay:開始延時
this.schedule(fn, interval, repeat, delay)
this.unschedule(fn)
13、腳本執行順序
editor: {
//executionOrder越小,該組件相對其它組件就會越先執行(默認為0)
//executionOrder只對 onLoad, onEnable, start, update 和 lateUpdate 有效,對 onDisable 和 onDestroy 無效
executionOrder: 1
}
14、標准網絡接口
(1)XMLHttpRequest——短連接
(2)WebSocket——長連接
15、對象池
對象池的概念
在同一場景中,需要多次進行節點的生成、消失時,假如直接進行創建、銷毀的操作,就會很浪費性能。因此,使用對象池,存儲需要消失的節點,釋放需要生成的節點,達到節點回收利用的目的。
工作流程
(1)初始化對象池
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 接口放入對象池
}
}
(2)從對象池請求對象
createEnemy: function (parentNode) {
let enemy = null;
if (this.enemyPool.size() > 0) { // 通過 size 接口判斷對象池中是否有空閑的對象
enemy = this.enemyPool.get();
} else { // 如果沒有空閑對象,也就是對象池中備用對象不夠時,我們就用 cc.instantiate 重新創建
enemy = cc.instantiate(this.enemyPrefab);
}
enemy.parent = parentNode; // 將生成的敵人加入節點樹
enemy.getComponent('Enemy').init(); //接下來就可以調用 enemy 身上的腳本進行初始化
}
(3)將對象返回對象池
onEnemyKilled: function (enemy) {
// enemy 應該是一個 cc.Node
this.enemyPool.put(enemy); // 和初始化時的方法一樣,將節點放進對象池,這個方法會同時調用節點的 removeFromParent
}
清除對象池
//手動清空對象池,銷毀其中緩存的所有節點
myPool.clear();
七、發布游戲
文章轉自:https://blog.csdn.net/ccnu027cs/article/details/101070069