內容基本來自Copy Paste Cocos Creator 的官網文檔
主要來自于閱讀的時候同時做筆記
CC Class
CCclass 構造函數 ctor: function () {}
聲明變量的時候加上類型第美,本質上是在聲明處填寫構造函數胃碾,設置get/set方法
playerNode:cc.Node
節(jié)點訪問和常用接口
獲取組件所在的節(jié)點this.node
獲取其他組件
通過類型 this.getComponent(cc.Label);
通過類名 var rotate = this.getComponent("SinRotate");
模塊化方法 var Player = require("Player");
然后 player:{defualt:null , type:Player}
查找子節(jié)點this.node.children
或his.node.getChildByName("Cannon 01");
或cc.find("Cannon 01/Barrel/SFX", this.node);
全局查找拿霉,只有一個參數的find
this.backNode = cc.find("Canvas/Menu/Back");
通過全局變量訪問或require模塊化方法來實現(xiàn)跨文件操作
var Global = require("Global");
節(jié)點激活 this.node.active = false;
更改父節(jié)點 this.node.parent = parentNode;
更改節(jié)點位置
this.node.x = 100;
this.node.setPosition(cc.v2(100, 50));
更改節(jié)點旋轉
this.node.rotation = 90;
this.node.setRotation(90);
縮放
this.node.scaleX = 2;
或 this.node.setScale(2);
尺寸
this.node.width = 100;
或this.node.setContentSize(cc.size(100, 100));
錨點位置
this.node.setAnchorPoint(1, 0);
或 this.node.anchorX = 1;
顏色透明度
在使用 Sprite、Label 這些基本的渲染組件時劝术,要注意修改顏色和不透明度的操作只能在節(jié)點的實例上進行缩多,因為這些渲染組件本身并沒有設置顏色和不透明度的接口呆奕。)
mySprite.node.color = cc.Color.RED;
mySprite.node.opacity = 128;
cc.Component
是所有組件的基類养晋,任何組件都包括如下的常見接口(該組件的腳本中,以 this 指代本組件):
this.node
:該組件所屬的節(jié)點實例
this.enabled
:是否每幀執(zhí)行該組件的 update 方法梁钾,同時也用來控制渲染組件是否顯示
update(dt)
:作為組件的成員方法绳泉,在組件的 enabled 屬性為 true 時,其中的代碼會每幀執(zhí)行
onLoad()
:組件所在節(jié)點進行初始化時(節(jié)點添加到節(jié)點樹時)執(zhí)行
start()
:會在該組件第一次 update 之前執(zhí)行姆泻,通常用于需要在所有組件的 onLoad 初始化完畢后執(zhí)行的邏輯
創(chuàng)建節(jié)點
new cc.Node()
并且通過node.addComponent(cc.Sprite)
方式來進行
克隆和根據Prefab預制件生成節(jié)點 cc.instantiate
銷毀節(jié)點 node.destroy()
銷毀節(jié)點并不會立刻被移除零酪,而是在當前幀邏輯更新結束后,統(tǒng)一執(zhí)行拇勃。當一個節(jié)點銷毀后四苇,該節(jié)點就處于無效狀態(tài),可以通過 cc.isValid
判斷當前節(jié)點是否已經被銷毀方咆。if (cc.isValid(this.target))
生命周期回調 Lifetime Callback Function | 鏈接
onLoad
組件腳本的初始化階段月腋,我們提供了 onLoad 回調函數。onLoad 回調會在節(jié)點首次激活時觸發(fā),比如所在的場景被載入榆骚,或者所在節(jié)點被激活的情況下片拍。在 onLoad 階段,保證了你可以獲取到場景中的其他節(jié)點妓肢,以及節(jié)點關聯(lián)的資源數據捌省。onLoad 總是會在任何 start 方法調用前執(zhí)行,這能用于安排腳本的初始化順序碉钠。通常我們會在 onLoad 階段去做一些初始化相關的操作
start
start 回調函數會在組件第一次激活前纲缓,也就是第一次執(zhí)行 update 之前觸發(fā)。start 通常用于初始化一些需要經常修改的數據喊废,這些數據可能在 update 時會發(fā)生改變色徘。
update
游戲開發(fā)的一個關鍵點是在每一幀渲染前更新物體的行為,狀態(tài)和方位操禀。
lateUpdate
update 會在所有動畫更新前執(zhí)行褂策,但如果我們要在動效(如動畫、粒子颓屑、物理等)更新之后才進行一些額外操作斤寂,或者希望在所有組件的 update 都執(zhí)行完之后才進行其它操作,那就需要用到 lateUpdate 回調揪惦。
onEnable
當組件的 enabled 屬性從 false 變?yōu)?true 時遍搞,或者所在節(jié)點的 active 屬性從 false 變?yōu)?true 時,會激活 onEnable 回調器腋。倘若節(jié)點第一次被創(chuàng)建且 enabled 為 true溪猿,則會在 onLoad
之后,start
之前被調用纫塌。
onDisable
當組件的 enabled
屬性從 true
變?yōu)?false
時诊县,或者所在節(jié)點的 active
屬性從 true
變?yōu)?false
時,會激活 onDisable
回調措左。
onDestroy
當組件或者所在節(jié)點調用了 destroy()
依痊,則會調用 onDestroy
回調,并在當幀結束時統(tǒng)一回收組件怎披。當同時聲明了 onLoad
和 onDestroy
時胸嘁,它們將總是被成對調用。也就是說從組件初始化到銷毀的過程中凉逛,它們要么就都會被調用性宏,要么就都不會被調用。
一個組件從初始化到激活状飞,再到最終銷毀的完整生命周期函數調用順序為:onLoad
-> onEnable
-> start
-> update
-> lateUpdate
-> onDisable
-> onDestroy
毫胜。
onLoad
節(jié)點激活時立即調用 組件 enabled 時才會調用蝌借?否
start
節(jié)點激活時延遲調用 組件 enabled 時才會調用?是
加載和場景切換
通過場景名索引和加載切換cc.director.loadScene("MyScene");
對于AssetBundle區(qū)分加載和運行需要使用 cc.director.runScene(scene);
如果需要有全局不因為場景加載而銷毀的常駐節(jié)點指蚁,類似Unity DontDestroyOnLoad
可以使用常駐節(jié)點菩佑,或全局變量訪問
cc.game.addPersistRootNode(myNode);
會將 myNode 變?yōu)槌qv節(jié)點,這樣掛在上面的組件都可以在場景之間持續(xù)作用凝化,我們可以用這樣的方法來儲存玩家信息稍坯,或下一個場景初始化時需要的各種數據。
取消常駐 cc.game.removePersistRootNode(myNode);
場景加載回調函數 cc.director.loadScene("MyScene", onSceneLaunched);
上一行里 onSceneLaunched 就是聲明在本腳本中的一個回調函數搓劫,在場景加載后可以用來進一步的進行初始化或數據傳遞的操作瞧哟。由于回調函數只能寫在本腳本中,所以場景加載回調通常用來配合常駐節(jié)點枪向,在常駐節(jié)點上掛載的腳本中使用勤揩。
預加載 cc.director.preloadScene(string sceneName, callback())
可以靜默加載等待
設置和獲取資源
所有繼承自 cc.Asset 的類型都統(tǒng)稱資源,如 cc.Texture2D, cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等秘蛔。它們的加載是統(tǒng)一并且自動化的陨亡,相互依賴的資源能夠被自動預加載。例如深员,當引擎在加載場景時负蠕,會先自動加載場景關聯(lián)到的資源,這些資源如果再關聯(lián)其它資源倦畅,其它也會被先被加載遮糖,等加載全部完成后,場景加載才會結束叠赐。
手動加載
定義資源屬性后手動加載 texture: { default: null, type: cc.Texture2D,},
動態(tài)加載
動態(tài)加載資源:cc.resources.load
通常我們會把項目中需要動態(tài)加載的資源放在 resources
目錄下欲账,配合接口動態(tài)加載。你只要傳入相對 resources
的路徑即可芭概,并且路徑的結尾處 不能 包含文件擴展名赛不。
cc.resources.load("test assets/prefab", function (err, prefab) {
var newNode = cc.instantiate(prefab);
cc.director.getScene().addChild(newNode);
});
所有需要通過腳本動態(tài)加載的資源,都必須放置在 resources 文件夾或它的子文件夾下谈山。resources 文件夾需要在 assets 根目錄 下手動創(chuàng)建俄删。資源動態(tài)加載的時候都是 異步 的,需要在回調函數中獲得載入的資源奏路。這么做是因為 Creator 除了場景關聯(lián)的資源,沒有另外的資源預加載列表臊诊,動態(tài)加載的資源是真正的動態(tài)加載鸽粉。
有些資源需要指定其類型,否則加載出來的默認類型有誤(例如把spriteFrame加載為Texture2D)
// 加載 SpriteFrame
var self = this;
cc.resources.load("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
資源釋放 cc.resources.release("test assets/image", cc.SpriteFrame);
或 cc.assetManager.releaseAsset(spriteFrame);
進行釋放
資源預加載 cc.resources.preload(path, cctype);
預加載的加載參數與正常加載時一樣抓艳,不過預加載只會去下載必要的資源触机,并不會進行資源的反序列化和初始化工作,所以性能消耗更小,適合游戲運行中使用儡首。
cc.resources.preload('test assets/image', cc.SpriteFrame);
// wait for while
cc.resources.load('test assets/image', cc.SpriteFrame, function (err, spriteFrame) {
self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});
加載遠程資源和設備資源 cc.assetManager.loadRemote
片任。
這種方式有一定限制:1. 這種加載方式只支持圖片、聲音蔬胯、文本等原生資源類型对供,不支持 SpriteFrame、SpriteAtlas氛濒、Tilemap 等資源的直接加載和解析产场。(如需遠程加載所有資源,可使用 Asset Bundle) 2. Web 端的遠程加載受到瀏覽器的 CORS 跨域策略限制舞竿,如果對方服務器禁止跨域訪問京景,那么會加載失敗,而且由于 WebGL 安全策略的限制骗奖,即便對方服務器允許 http 請求成功之后也無法渲染确徙。
// 遠程 url 帶圖片后綴名
var remoteUrl = "http://unknown.org/someres.png";
cc.assetManager.loadRemote(remoteUrl, function (err, texture) {
// Use texture to create sprite frame
});
資源的依賴與釋放
在加載完資源之后,所有的資源都會臨時被緩存到 cc.assetManager
中
針對 JavaScript 中無法跟蹤對象引用的問題执桌,Asset Manager 提供了一套基于引用計數的資源釋放機制米愿,讓開發(fā)者可以簡單高效地釋放資源,不用擔心項目規(guī)模的急劇膨脹鼻吮。每一個資源對象都提供了兩個方法 addRef
育苟,decRef
,你可以使用這兩個接口來對動態(tài)資源的引用進行控制
Asset Bundle
從 v2.4 開始椎木,Cocos Creator 推出了 Asset Bundle 功能违柏,支持 代碼、資源 和 場景 的分包加載香椎。開發(fā)者可將項目中的部分場景漱竖、資源、代碼等內容劃分到不同的 Asset Bundle 中畜伐,這些 Asset Bundle 不會在游戲啟動時加載馍惹,而是由開發(fā)者在游戲過程中手動調用 loadBundle 進行加載,從而有效降低游戲啟動的時間玛界,盡可能做到按需加載万矾。關于 Asset Bundle 的更多介紹,請參考 Asset Bundle慎框。
加載asset bundle cc.assetManager.loadBundle
加載時需要傳入 Asset Bundle 配置面板中的 Bundle 名稱 或者 Asset Bundle 的 url良狈。
cc.assetManager.loadBundle('01_graphics', (err, bundle) => {
bundle.load('xxx');
});
從 v2.4.3 開始,cc.assetManager.loadBundle 還支持傳入用戶空間中的路徑來加載用戶空間中的 Asset Bundle笨枯。通過對應平臺提供的下載接口將 Asset Bundle 提前下載到用戶空間中薪丁,然后再使用 loadBundle 進行加載遇西,開發(fā)者就可以完全自己管理 Asset Bundle 的下載與緩存過程,更加靈活严嗜。
// 提前下載某個 Asset Bundle 到用戶空間 pathToBundle 目錄下粱檀。
//需要保證用戶空間下的 Asset Bundle 和對應原始 Asset Bundle 的結構和內容完全一樣
// ...
// 通過 Asset Bundle 在用戶空間中的路徑進行加載
// 微信小游戲平臺
cc.assetManager.loadBundle(wx.env.USER_DATA_PATH + '/pathToBundle/bundleName', (err, bundle) => {
// ...
});
當 Asset Bundle 加載完成后,會觸發(fā)回調并返回錯誤信息和 cc.AssetManager.Bundle
類的實例漫玄,這個實例就是 Asset Bundle API 的主要入口茄蚯,開發(fā)者可以使用它去加載 Asset Bundle 中的各類資源。在 Asset Bundle 加載完成后称近,返回了一個 cc.AssetManager.Bundle
類的實例第队。
可以通過名稱進行獲取
let bundle = cc.assetManager.getBundle('01_graphics');
加載資源: bundle.load
方法來加載 Asset Bundle 中的資源,此方法的參數與 cc.resources.load
相同刨秆,
加載場景:Asset Bundle 提供了 loadScene
方法用于加載指定 bundle 中的場景凳谦,你只需要傳入 場景名 即可。loadScene
與 cc.director.loadScene
不同的地方在于 loadScene
只會加載指定 bundle 中的場景衡未,而不會運行場景尸执,你還需要使用 cc.director.runScene
來運行場景。
預加載:Asset Bundle 中提供了 preload
和 preloadDir
接口用于預加載 Asset Bundle 中的資源缓醋。具體的使用方式和 cc.assetManager
一致
釋放資源:常規(guī)的cc.assetManager.releaseAsset
或bundle.release('image', cc.SpriteFrame);
或 bundle.releaseAll();
移除AssetBundle:cc.assetManager.removeBundle(bundle);
當手動移除了某個不需要的 bundle如失,那么此 bundle 的緩存也會被移除,如果需要再次使用送粱,則必須再重新加載一次褪贵。在移除 Asset Bundle 時,并不會釋放該 bundle 中被加載過的資源抗俄。如果需要釋放脆丁,請先使用 Asset Bundle 的 release / releaseAll
方法:
監(jiān)聽與發(fā)射事件
事件處理是在節(jié)點(cc.Node)
中完成的。對于組件动雹,可以通過訪問節(jié)點 this.node
來注冊和監(jiān)聽事件槽卫。監(jiān)聽事件可以通過 this.node.on()
函數來注冊,除了使用on
監(jiān)聽胰蝠,我們還可以使用 once
方法歼培。once
監(jiān)聽在監(jiān)聽函數響應后就會關閉監(jiān)聽事件。
監(jiān)聽事件
注冊監(jiān)聽方法:this.node.on('mousedown', function ( event ) {console.log('Hello!');});
/ 例:點擊事件的綁定 this.node.on(‘touchstart’,this.fire,this);
事件監(jiān)聽函數 on 可以傳第三個參數 target茸塞,用于綁定響應函數的調用者躲庄。
// 使用函數綁定
this.node.on('mousedown', function ( event ) {this.enabled = false;}.bind(this));
// 使用第三個參數
this.node.on('mousedown', function (event) {this.enabled = false;}, this);
關閉監(jiān)聽:off
方法,推薦和onEnable()
與 onDisable()
配合案例
cc.Class({
extends: cc.Component,
_sayHello: function () {
console.log('Hello World');
},
onEnable: function () {
this.node.on('foobar', this._sayHello, this);
},
onDisable: function () {
this.node.off('foobar', this._sayHello, this);
},
});
發(fā)射事件
發(fā)射事件有兩種方式:emit
和 dispatchEvent
翔横。兩者的區(qū)別在于读跷,后者可以做事件傳遞。
在發(fā)射事件時禾唁,我們可以在 emit
函數的第二個參數開始傳遞我們的事件參數效览。同時,在 on
注冊的回調里荡短,可以獲取到對應的事件參數丐枉。出于底層事件派發(fā)的性能考慮,這里最多只支持傳遞 5 個事件參數掘托。
onLoad () { //事件注冊
this.node.on('foo', function (arg1, arg2, arg3) {
console.log(arg1, arg2, arg3); // print 1, 2, 3
});
},
start () {
// 事件發(fā)射
let arg1 = 1, arg2 = 2, arg3 = 3;
// At most 5 args could be emit.
this.node.emit('foo', arg1, arg2, arg3);
},
派送事件 (用于我不想觸發(fā)全部瘦锹,而是可以截獲)
dispatchEvent
方法,通過該方法發(fā)射的事件闪盔,會進入事件派送階段弯院。在 Cocos Creator 的事件派送系統(tǒng)中,我們采用冒泡派送的方式泪掀。冒泡派送會將事件從事件發(fā)起節(jié)點听绳,不斷地向上傳遞給他的父級節(jié)點,直到到達根節(jié)點或者在某個節(jié)點的響應函數中做了中斷處理 event.stopPropagation()
异赫。
發(fā)送的節(jié)點c
this.node.dispatchEvent( new cc.Event.EventCustom('foobar', true) );
截獲的節(jié)點b
this.node.on('foobar', function (event) {event.stopPropagation();});
事件對象
在事件監(jiān)聽回調中椅挣,開發(fā)者會接收到一個 cc.Event
類型的事件對象 event
,stopPropagation
就是 cc.Event
的標準 API塔拳。
在發(fā)送用戶自定義事件的時候鼠证,請不要直接創(chuàng)建 cc.Event
對象,因為它是一個抽象類靠抑,請創(chuàng)建 cc.Event.EventCustom
對象來進行派發(fā)量九。
其中重要的API包含:
API - 類型 - 意義
type
-String
事件的類型(事件名)
target
- cc.Node
接收到事件的原始對象
currentTarget
- cc.Node
接收到事件的當前對象,事件在冒泡階段當前對象可能與原始對象不同
getType
-Function
獲取事件的類型
stopPropagation
-Function
停止冒泡階段颂碧,事件將不會繼續(xù)向父節(jié)點傳遞荠列,當前節(jié)點的剩余監(jiān)聽器仍然會接收到事件
stopPropagationImmediate
- Function
立即停止事件的傳遞,事件將不會傳給父節(jié)點以及當前節(jié)點的剩余監(jiān)聽器
getCurrentTarget
-Function
獲取當前接收到事件的目標節(jié)點
detail
-Function
自定義事件的信息(屬于 cc.Event.EventCustom)
setUserData
-Function
設置自定義事件的信息(屬于 cc.Event.EventCustom)
getUserData
-Function
獲取自定義事件的信息(屬于 cc.Event.EventCustom)
系統(tǒng)內置事件
Cocos Creator 支持的系統(tǒng)事件包含鼠標稚伍、觸摸弯予、鍵盤、重力傳感四種个曙,其中本章節(jié)重點介紹與節(jié)點樹相關聯(lián)的鼠標和觸摸事件锈嫩,這些事件是被直接觸發(fā)在相關節(jié)點上的,所以被稱為節(jié)點系統(tǒng)事件垦搬。與之對應的呼寸,鍵盤和重力傳感事件被稱為全局系統(tǒng)事件。
系統(tǒng)事件遵守通用的注冊方式猴贰,開發(fā)者既可以使用枚舉類型也可以直接使用事件名來注冊事件的監(jiān)聽器对雪,事件名的定義遵循 DOM 事件標準舔哪。
// 使用枚舉類型來注冊
node.on(cc.Node.EventType.MOUSE_DOWN, function (event) {
console.log('Mouse down');
}, this);
// 使用事件名來注冊
node.on('mousedown', function (event) {
console.log('Mouse down');
}, this);
鼠標事件類型與事件對象
鼠標事件在桌面平臺才會觸發(fā):
鼠標事件在桌面平臺才會觸發(fā)乔外,系統(tǒng)提供的事件類型如下:
枚舉對象定義- 對應的事件名- 事件觸發(fā)的時機
cc.Node.EventType.MOUSE_DOWN
- mousedown
當鼠標在目標節(jié)點區(qū)域按下時觸發(fā)一次
cc.Node.EventType.MOUSE_ENTER
- mouseenter
當鼠標移入目標節(jié)點區(qū)域時,不論是否按下
cc.Node.EventType.MOUSE_MOVE
- mousemove
當鼠標在目標節(jié)點區(qū)域中移動時,不論是否按下
cc.Node.EventType.MOUSE_LEAVE
- mouseleave
當鼠標移出目標節(jié)點區(qū)域時题暖,不論是否按下
cc.Node.EventType.MOUSE_UP
- mouseup
當鼠標從按下狀態(tài)松開時觸發(fā)一次
cc.Node.EventType.MOUSE_WHEEL
- mousewheel
當鼠標滾輪滾動時
鼠標事件(cc.Event.EventMouse)的重要 API 如下(cc.Event 標準事件 API 除外):
函數名- 返回值類型 -意義
getScrollY
Number
獲取滾輪滾動的 Y 軸距離邦蜜,只有滾動時才有效
getLocation
Object
獲取鼠標位置對象甲脏,對象包含 x 和 y 屬性
getLocationX
Number
獲取鼠標的 X 軸位置
getLocationY
Number
獲取鼠標的 Y 軸位置
getPreviousLocation
Object
獲取鼠標事件上次觸發(fā)時的位置對象拓诸,對象包含 x 和 y 屬性
getDelta
Object
獲取鼠標距離上一次事件移動的距離對象,對象包含 x 和 y 屬性
getButton
Number
獲取cc.Event.EventMouse.BUTTON_LEFT
或 cc.Event.EventMouse.BUTTON_RIGHT
或 cc.Event.EventMouse.BUTTON_MIDDLE
觸摸事件類型和事件對象 網頁
有TOUCH_START
還有TOUCH_MOVE
TOUCH_END
TOUCH_CANCEL
四種微妙差別
觸摸事件API 部分可以獲取 觸點對象touch
,getID
,getLocation
桑李,獲取上次觸點getPreviousLocation
踱蛀,獲取觸點初始位置 getStartLocation
, 獲取移動的距離對象getDelta
需要注意的是,觸摸事件支持多點觸摸贵白,每個觸點都會發(fā)送一次事件給事件監(jiān)聽器率拒。
觸摸事件的傳遞問題,參考事件冒泡:如果c是b的子節(jié)點禁荒,b是a的子節(jié)點:會通過c - b - a 冒泡在觸摸事件冒泡的過程中不會有觸摸檢測猬膨,這意味著即使觸點不在 A B 節(jié)點區(qū)域內,A B 節(jié)點也會通過觸摸事件冒泡的機制接收到這個事件圈浇。
cc.Node 的其它事件
position-changed
當位置屬性修改
rotation-changed
當旋轉屬性修改時
scale-changed
當縮放屬性修改時
size-changed
當寬高屬性修改時
anchor-changed
當錨點屬性修改時
屏蔽多點觸摸系統(tǒng)
cc.macro.ENABLE_MULTI_TOUCH = false;
暫停和恢復節(jié)點事件系統(tǒng)
this.node.pauseSystemEvents();
與this.node.resumeSystemEvents();
全局系統(tǒng)事件
全局系統(tǒng)事件是指與節(jié)點樹不相關的各種全局事件寥掐,由 cc.systemEvent
來統(tǒng)一派發(fā)
定義輸入事件
鍵盤、設備重力傳感器此類全局事件是通過函數 cc.systemEvent.on(type, callback, target)
注冊的磷蜀。
可選的 type 類型有:
cc.SystemEvent.EventType.KEY_DOWN
(鍵盤按下)
cc.SystemEvent.EventType.KEY_UP
(鍵盤釋放)
cc.SystemEvent.EventType.DEVICEMOTION
(設備重力傳感)
鍵盤事件
cc.Class({
extends: cc.Component,
onLoad: function () {
// add key down and key up event
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
onKeyDown: function (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
console.log('Press a key');
break;
}
},
onKeyUp: function (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
console.log('release a key');
break;
}
}
});
重力傳感器事件 cc.SystemEvent.EventType.DEVICEMOTION