項目鏈接:https://github.com/cocos-creator/tutorial-first-game/tree/master/polished_project
1.通過腳本屬性引用場景節點
通過腳本顯式地暴露屬性,從而引用場景中需要用到的節點對象。也就是說場景需要用到的節點資源,通通都要留個屬性節點作爲入口
2.cc.sys.isMobile
// initialize control hint
var hintText = cc.sys.isMobile ? this.touchHint : this.keyboardHint;
this.controlHintLabel.string = hintText;
cc.sys.isMobile屬性用於判斷當前系統是否爲手機設備
3.NodePool對象緩存池類型
cc.NodePool 是用於管理節點對象的對象緩存池
它可以幫助您提高遊戲性能,適用於優化對象的反覆創建和銷燬
constructor(); 使用構造函數來創建一個節點專用的對象池,您可以傳遞一個組件類型或名稱,用於處理節點回收和複用時的事件邏輯
// initialize star and score pool
this.starPool = new cc.NodePool('Star');
this.scorePool = new cc.NodePool('ScoreFX');
get(); 獲取對象池中的對象,如果對象池沒有可用對象,則返回空
// 使用給定的模板在場景中生成一個新節點
if (this.starPool.size() > 0) {
newStar = this.starPool.get(this); // this will be passed to Star's reuse method
}else {
newStar = cc.instantiate(this.starPrefab);
}
put(); 向緩衝池中存入一個不再需要的節點對象
this.starPool.put(star);
this.scorePool.put(scoreFX);
4.node.active屬性
this.gameOverNode.active = false;
node.active = true || false;用來顯示或隱藏節點
5.node.addChild(newNode);
每次新創建完預製資源以後,記得把新的節點添加到父節點下面
// 將新增的節點添加到 Canvas 節點下面
this.node.addChild(newStar);
易錯點:先設置完屬性,然後再添加到父節點
比如下面這段代碼會導致精靈無法摘取星星
var newStar = cc.instantiate(this.starPrefab);
// 爲星星設置一個隨機位置
newStar.setPosition(this.getNewStarPosition());
// pass Game instance to star
newStar.getComponent('Star').init(this);
// 將新增的節點添加到 Canvas 節點下面
this.node.addChild(newStar);
這段代碼問題出在this.node.addChild(newStar);精靈之所以無法摘取星星,正是因爲newStar節點還沒添加到Canvas畫布下面,所以newStar還不是Canvas下的子節點,所以newStar.setPosition()、newStar.getComponent()這兩個方法執行無效。
只要把this.node.addChild(newStar); 方法放到newStar.setPosition()、newStar.getComponent()這兩個方法的前面即可
修改後的代碼
// 將新增的節點添加到 Canvas 節點下面
this.node.addChild(newStar);
// 爲星星設置一個隨機位置
newStar.setPosition(this.getNewStarPosition());
// pass Game instance to star
newStar.getComponent('Star').init(this);
6.如果函數功能不是太多,就不要嵌套太多的函數
如上代碼,startTimer()只有兩行代碼並且該函數只調用了一次,因此把startTimer()函數合併到spawnNewStar(),從而減少代碼的冗餘性,增強代碼的可讀性
7.if…else改寫成三目運算符
if (this.currentStarX >= 0) {
randX = -Math.random() * maxX;
}else {
randX = Math.random() * maxX;
}
修改後的代碼
randX=this.currentStarX >= 0?-Math.random() * maxX:Math.random() * maxX
將if…else改寫成三目運算符可以減少更多的代碼量
8.通過this.enabled屬性來控制遊戲開始與關閉
Game.js通過this.enabled屬性來控制遊戲開關
也可以從Game.js調用this.player.enabled = false;來關閉Player.js
9.this.currentStar.destroy();
node.destroy(); 銷燬該對象,並釋放所有它對其它對象的引用
通常在遊戲GameOver的時候調用destroy()方法,釋放一些資源
實際銷燬操作會延遲到當前幀渲染前執行。從下一幀開始,該對象將不再可用。 您可以在訪問對象之前使用 cc.isValid(obj) 來檢查對象是否已被銷燬
10.Cocos Creator動畫系統
動畫系統通常用來做些簡單的特效,針對節點做的動畫,如果是複雜的角色動畫,需要藉助spine或者db
11.cc.Sprite.spriteFrame
在時間軸上給spriteFrame屬性添加關鍵幀,從而實現幀幀動畫
12.Animation、animation-clip的關係
一個節點添加Animation組件使之成爲Animation節點,一個Animation節點可以添加多個clip影片剪輯
以Animation節點作爲根節點,只有它的子節點才能添加屬性、添加動畫。給不同的子節點添加不同的動畫,這些子節點最終合成一個clip影片剪輯
13.簡單的形變效果
//壓扁
var squash = cc.scaleTo(this.squashDuration, 1, 0.6);
//拉長
var stretch = cc.scaleTo(this.squashDuration, 1, 1.2);
//恢復原狀
var scaleBack = cc.scaleTo(this.squashDuration, 1, 1);
通過cc.scaleTo();這樣一個方法改變Y軸大小,從而實現精靈球從壓扁到彈跳再到恢復原狀這麼一個過程
14.node.parent屬性或node.getParent()方法獲得父節點
// screen boundaries
this.minPosX = -this.node.parent.width/2;
this.maxPosX = this.node.parent.width/2;
有時需要通過父節點獲得一些信息供子節點使用
15.初始化觸屏輸入監聽
初始化觸屏輸入監聽,與鍵盤輸入監聽類似
// 初始化觸屏輸入監聽
var touchReceiver = cc.Canvas.instance.node;
touchReceiver.on('touchstart', this.onTouchStart, this);
touchReceiver.on('touchend', this.onTouchEnd, this);
onTouchStart (event) {
var touchLoc = event.getLocation();
if (touchLoc.x >= cc.winSize.width/2) {
this.accLeft = false;
this.accRight = true;
} else {
this.accLeft = true;
this.accRight = false;
}
},
向onTouchStart()方法傳入參數event,通過event參數獲得當前屏幕點擊的位置
var touchLoc = event.getLocation();
cc.log(touchLoc.x);
cc.winSize(); 爲當前的遊戲窗口的大小
16.相同動作的case可以合併
onKeyDown (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
this.accLeft = true;
this.accRight = false;
break;
case cc.macro.KEY.d:
this.accLeft = false;
this.accRight = true;
break;
case cc.macro.KEY.left:
this.accLeft = true;
this.accRight = false;
break;
case cc.macro.KEY.right:
this.accLeft = false;
this.accRight = true;
break;
}
},
如上代碼case cc.macro.KEY.a和case cc.macro.KEY.left具有相同的行爲,case cc.macro.KEY.d和case cc.macro.KEY.right也具有相同的行爲,因此可以把相同行爲的case合併。修改後的代碼如下
onKeyDown (event) {
switch(event.keyCode) {
case cc.macro.KEY.a:
case cc.macro.KEY.left:
this.accLeft = true;
this.accRight = false;
break;
case cc.macro.KEY.d:
case cc.macro.KEY.right:
this.accLeft = false;
this.accRight = true;
break;
}
},
把case cc.macro.KEY.a和case cc.macro.KEY.left合併,case cc.macro.KEY.d和case cc.macro.KEY.right合併之後,又減少了更多的代碼
17.update()方法中,什麼時候需要乘上dt
update()方法中,dt是一個重要的時間變量,dt的使用對物體運動的速度有很大的影響
從以上代碼得出一些結論,末速度Vt = V0+at; 路程S = Vt;
因此,我們只要根據物理常識,就知道什麼時候需要乘上dt
18.有兩種引用js文件的方式
①通過組件化方式
②通過require()引用js文件
const Player = require('Player');
至於什麼時候使用組件化、什麼時候使用require(); 這兩種引用js文件方式還是有區別的
①如果既需要獲得節點的信息,又要獲得節點對應的js文件,此時應該使用組件化引用方式
②如果僅僅需要js文件裏的屬性和方法,那就用require()方式更快捷