這世上只有一種成功,就是能夠用自己喜歡的方式度過自己的一生!
1. 項目基本結構
+assets (項目資源的根目錄名)
-Texture (存放其他資源)
-Script (存放腳本文件) ccc中腳本名就是組件名,大小寫敏感!
-Scene (存放遊戲場景)
2. 腳本文件的結構
cc.Class({
extends: cc.Component,
properties: {
label: {
default: null,
type: cc.Label
},
// defaults, set visually when attaching this script to the Canvas
text: 'Hello, World!'
},
// 用於初始化
onLoad: function () {
this.label.string = this.text;
},
// called every frame
update: function (dt) {
},
});
properties :組件(掛載到場景中的節點上,提供控制節點的各種功能;這些properties可以直接在屬性檢查器中設置)
onload :頁面一加載完就執行裏面的函數代碼
update : 根據時間實時更新,更新回調
3. Prefab(預製資源)
需要重複生成的節點,我們可以將他保存成Prefab(預製)資源,作爲我們動態生成節點時使用的模板
比如將Texture文件夾下的一張圖片,拖到層級管理器系統即是場景的canvas裏面,再從層級管理器拖到Texture文件夾中就是預製資源(預製資源的圖標是個灰色正方形)啦(我也覺得這操作有點奇怪)
4. 學習ccc需要對JavaScript非常熟悉
5. 常見基礎 API
cc.moveBy("幾秒",cc.p("橫座標","縱座標")) 移動指定的距離
cc.moveTo("幾秒",cc.p("橫座標","縱座標")) 移動到目標位置
cc.easeCubicActionOut() 創建 easeCubicActionOut 緩動對象 ,就是緩慢減速的一種效果
cc.repeatForever("一個序列") 永遠地重複一個動作
node.runAction("動作序列名") 執行並返回該執行的動作。該節點將會變成動作的目標。
this.node.addChild("節點名","層級數字"); 添加子節點
"節點名".setPosition(); 設置節點在父節點座標系中的位置
cc.callFunc 執行回調函數
"節點名".removeFromParent 從父節點中刪除該節點
cc.sequence(); 順序執行動作,創建的動作將按順序依次運行
6. Scene介紹和基本操作
Scene 每個遊戲都會用到場景切換!
Director類 遊戲導航儀,控制 初始化,場景切換,遊戲暫停繼續等等
cc.director.loadScene("場景名"); 加載一個場景
cc.director.preloadScene("場景名"); 預加載場景(比如圖片資源比較大就可以用它預先加載)
this.node.on("事件名","函數"); 事件(事件名,function)
this.schedule(function(){},1); 類似js的setTimeout
改變一個標籤上面的文字居然是這樣的 this.timeLabel.string=4; (說好的和js差不多呢)
模擬手機遊戲的場景的canvas要改成 W:640 H: 960
7. 玩家輸入事件語法
EventTarget 事件目標是事件觸發時,分派的事件對象,Node 是最常見的事件目標, 但是其他對象也可以是事件目標
8. 關閉左下角的fps面板,在場景腳本的文件中 onLoad 的函數中寫以下:
cc.director.setDisplayStats(false);
=======================================================
騰訊課堂-cocos creator/cocos 2dx 入門 聽課筆記
1. 使用ts來做ccc開發新建的腳本文件是這樣的: (代碼實現一隻扇翅膀的小鳥)
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
@property(cc.Label)
label: cc.Label = null;
@property(cc.Sprite)
bird0: cc.Sprite = null;
@property(cc.Sprite)
bird1: cc.Sprite = null;
@property(cc.Sprite)
bird2: cc.Sprite = null;
@property(cc.Sprite)
bird3: cc.Sprite = null;
@property(cc.Node)
birdParent: cc.Node = null;
@property
text: string = 'hello';
time: number = 0; // 距離上次切換顯示的小鳥 流失的時間
// LIFE-CYCLE CALLBACKS:
// onLoad () {}
start () {
}
update (dt: number) {
// console.log(dt);
let timeTmp = this.time + dt;
this.time = timeTmp;
if(this.time > 0.5){
if(this.bird0.node.active){
this.bird0.node.active = false;
this.bird1.node.active = true;
}else if (this.bird1.node.active){
this.bird1.node.active = false;
this.bird2.node.active = true;
}else if (this.bird2.node.active){
this.bird2.node.active = false;
this.bird3.node.active = true;
}else if (this.bird3.node.active){
this.bird3.node.active = false;
this.bird0.node.active = true;
}
this.time = 0;
}
let birdY = this.birdParent.y;
this.birdParent.y = birdY - 1;
}
}
// 重點來了,自定義枚舉
/**
* 全局變量
* const LEVEL = cc.Enum({EASY:1,HARD:2});
*/
@property({
type:LEVEL
})
enumVa = LEVEL.EASY;
2. 幀的概念是這樣的: 比如一秒60幀,說明一秒鐘畫面刷新了60次,幀數爲 1/60
3. 節點 Node 是包含 組件的
4. 代碼執行遇到return整個函數就都不執行了
5. BMfont 可以用圖片數字來代替真實數字(不知道怎麼做的)
=============================================================
1. ccc是一個組件化的開發工具
2. Prefab: 預製體,預製資源
// 預(提前)制體
@property(cc.Prefab)//預製體類型
myPrefab:cc.Prefab=null;//需要被克隆的對象
//程序運行後加載對象
start(){
var loadobj =cc.instantiate(this.myPrefab);//將預製體克隆到場景
this.node.addChild(loadobj);//將克隆出的物體作爲子物體
//設置物體位置
loadobj.setPosition(cc.p(300,-150));
//5秒之後銷燬對象
setTimeout(
function(){ //匿名方法
loadobj.destroy();
}
,5000);
}
3. ccc 的生命週期函數:
- onLoad(會在這個組件所在的場景被載入的時候觸發,執行最早的方法 只執行一次,在場景加載後立刻執行)
- start(會在組件第一次激活前,也就是第一次執行 update 之前觸發,start 在onload 之後執行只執行一次)
- update(遊戲開發一個關鍵是在每一幀渲染前更新物體的行爲,狀態和方位。這些更新操作通常都放在 update 回調中,會在所有動畫更新前執行)(update 可以不帶參數 參數的意思是遊戲一幀執行的時間 大概爲0.017秒 數值不固定)
- lateUpdate(動畫更新後進行額外操作,在update執行之後馬上執行 ,需要用到 lateUpdate 回調)
- onDestroy(當組件調用了 destroy(),會在該幀結束被統一回收,此時會調用 onDestroy 回調。執行最晚的方法,物體被銷燬之前執行)
- onEnable(當組件的 enabled 屬性從 false 變爲 true 時,會激活 onEnable 回調。倘若節點第一次被 創建且 enabled
爲 true,則會在 onLoad 之後,start 之前被調用。腳本啓用會執行)- onDisable(當組件的 enabled 屬性從 true 變爲 false 時,會激活 onDisable 回調,腳本禁用會執行)
4. Cocos Creator 中腳本名稱就是組件的名稱,這個命名是大小寫敏感的!如果組件名稱的大小寫不正確,將無法正確通過名稱使用組件!
5. 通過學習官網demo摘星星總結開發流程:
- 找好遊戲相關資源,包括圖片,音頻,位圖字體文件等
- 新建遊戲場景(幾個遊戲畫面就幾個場景)(往場景添加背景,主角等)
- 給你的主角寫腳本(在 properties 中定義主角會用到的變量--想象主角會做什麼動作,如主角會一直跳,我們還可以控制他左右走,跳有高度,也有跳一次所需 時間,左右走有速度,加速度等)
properties: {
}
- 編寫主角動作代碼(主角自動執行的動作,如跳躍,爲跳躍寫一個方法),既然是自動執行就可以寫在生命週期函數onload方法裏面初始化調用;控制移動的再寫一個方法,監聽我們的按鍵,設置速度之類的屬性
- 重複生成的東西就要做成預製資源,爲這個預製資源新建一個腳本文件
- 添加遊戲控制腳本,主邏輯包括計分,遊戲開始,遊戲失敗等邏輯,一般綁在場景的canvas上面
- 得分一般都是一個label標籤,再價格位圖字體,然後主邏輯腳本繼續寫得分邏輯
- 最後加入音效
=================================================
1. 在場景的canvas的屬性檢查器中找到Group點擊編輯可以分組配置碰撞檢測
2. 添加物理邊緣步驟(點擊節點-添加組件-物理-collider-Box)如果邊界是靜止的嗎,要在Rigidbody--type--static
3. 什麼是ccc組件化開發: 節點 + 組件1 + 組件2 + 組件3 。。。 (也就是一個節點帶着不同功能的組件)(開發一個功能,都是從組件開始的)
a: 創建一個組件類
b: new 組件類出來
c: 管理這些組件實例
(1): 運行場景的時候初始化:
遍歷場景裏面的每個節點,
遍歷節點上面的每個組件實例;
調用 組件實例.onLoad, --> 組件實例在加載的時候調用;
調用 組件實例.start -->組件實例在開始運行之前調用一次;
(2): 每次遊戲刷新的時候
4. 在一個節點操作 添加我們自己定義的腳本組件原來就是 實例化一個類
5. 開啓物理引擎:
cc.director.getPhysicsManager().enabled = true;
開啓調試狀態/模式(給指定物理系統需要繪製哪些調試信息):
var draw = cc.PhysicsManager.DrawBits;
cc.director.getPhysicsManager().debugDrawFlags = draw.e_shapeBit|draw.e_jointBit;
物理引擎的腳本要掛載到根節點上,然後一定要在該腳本的onload()方法中所有的動作初始化前開啓物理引擎。
6. 弧度轉角度: 角度值 = 弧度值*180 / Math.PI
7. 碰撞檢測:
- onBeginContact: 碰撞開始被調用
- onEndContact: 碰撞結束被調用
- onPreSolve: 碰撞接觸更新前調用
- onPostSolve: 碰撞接觸更新後調用
- 參數:contact 碰撞信息 ,selfCollider 自己的碰撞器 , otherCollider 撞到的誰
8. 微信打包發佈:
- 發佈微信的話 canvas 節點上只能選擇 Fit Width ,Fit Height 不能選
- 項目--構建發佈--發佈平臺(Wechat Game),MD5 Cache 選上,設備方向(豎屏選Portrait,橫屏選landscape),appid(自己填自己的)--構建--運行(就會打開微信開發工具)--預覽--掃描二維碼玩遊戲
- cocos creator--偏好設置--原生開發環境--wechatGame程...(選擇微信開發工具的地址exe的位置)
===============================================
1. moveBy:移動指定的距離
var jumpUp = cc.moveBy(this.jumpTimes,cc.p(0,this.jumpHeight));
2. cc.sequence: 順序執行動作,創建的動作將按順序依次運行
var seq = cc.sequence(this.jumpAction,this.maxMoveSpeed);
3. runAction: 執行並返回該執行的動作。該節點將會變成動作的目標。
this.node.runAction(seq);
4. getComponent: 獲取節點上指定類型的組件,如果節點有附加指定類型的組件,則返回,如果沒有則爲空。
傳入參數也可以是腳本的名稱。
var HeroPlayer = require("HeroPlayer");
...
var hero = self.player.getComponent(HeroPlayer);
5. 除了微信小遊戲以外,其他類型的小遊戲 Canvas 中的Fit Height與Fit Width 一定要勾選上(爲了適配)
6. cc.winSize: 爲當前的遊戲窗口的大小。
7. 獲取一張圖片的寬度:
this._width = this.groundImg.spriteFrame.getRect().width;
8. 定時器:參數是回調函數和時間
this.schedule(function(),this.move_time)
9. 寫動畫(幀動畫,例如 像素鳥的小鳥不斷煽動翅膀)
動畫編輯器--添加animation組件--新建animationClip(存儲在anim文件夾裏面)--點擊動畫編輯器的左上角編輯按鈕--屬性列表點擊 add property---選擇 cc.Sprite.spriteFrame--點 “+” 號 -- 拉一幀點一次 “+” 號 -- 替換幀對應的圖片--wrapMode選擇Loop--點擊左上角的播放按鈕--保存--關閉--新建腳本--腳本拉到屬性檢查器--動畫文件拉到對應位置--playOnload打鉤--預覽
10. 獲取節點上指定類型的組件,如果節點有附加指定類型的組件,則返回,如果沒有則爲空。傳入參數也可以是腳本的名稱:
var pipeUp = cc.instantiate(this.pipePrefabs[0]);
pipe.getComponent('Pipe').init(0);
11. 返回父節座標系下的軸向對齊的包圍盒:(包圍後是以盒的左下角爲中心的)
var boundingBox = node.getBoundingBox();
12. 獲取與設置本地 localstorage 的值:
cc.sys.localStorage.getItem('name');
cc.sys.localStorage.setItem('name',score);
13. 動畫效果(例如爲得分文字添加小動畫):
- scaleTo 將節點大小縮放到指定的倍數
- sequence 順序執行動作,創建的動作將按順序依次運行。
var action1 = cc.scaleTo(this.scoreTime,1.1,0.6);
var action2 = cc.scaleTo(this.scoreTime,0.8,1.2);
var action3 = cc.scaleTo(this.scoreTime,1,1);
//播放形變動畫
this.curScoreText.node.runAction(cc.sequence(action1,action2,action3));
========================================
1. 任何一個節點都會有一個 cc.Node(cc.Node是場景樹中的節點對象);
2. cc.Node.rotation: 旋轉,順時針爲正,數學逆時針爲正;
3. cc.Node.anchor: 錨點,左下角(0,0),右上角(1,1),可以超過這個範圍;
4. 在代碼組件裏面,使用 this.node 訪問這個組件實例掛載的節點對象;
5. cc.Node.children/childrenCount: 獲得孩子節點數組、孩子節點數量;
6. cc.Node場景樹相關方法:
- getChildByName: 通過名稱獲取節點的子節點
-
new cc.Node():代碼中創建一個節點
-
setPosition/getPosition: 獲取或設置節點的相對位置
-
cc.find(): 方便,不通用, 消耗
7. 觸摸事件的類型:START, MOVED, ENDED(物體內彈起), CANCEL(物體外彈起);
- cc.Node.EventType.TOUCH_START
- cc.Node.EventType.TOUCH_MOVE
- cc.Node.EventType.TOUCH_END
- cc.Node.EventType.TOUCH_CANCEL
8. 監聽觸摸事件: node.on(類型, callback, target(回掉函數的this), [useCapture]);
9. 關閉觸摸事件: node.off(類型, callback, target(回掉函數的this), [useCapture]);
4. targetOff(target):移除所有的註冊事件;
5. 觸摸事件中回調函數的參數t:t.getLocation() 獲取當前觸點位置 ; t.getDelta() 獲取觸點距離上一次事件移動的距離對象,對象包含 x 和 y 屬性(也就是距離上一次觸摸變化了多少)
//在觸摸移動的事件類型中的回調函數
var delta = t.getDelta();
this.node.x += delta.x;
this.node.y += delta.y;
//以上代碼實現節點物體隨着你點擊移動的位置移動
6. stopPropagationImmediate: 立即停止當前事件的傳遞,事件甚至不會被分派到所連接的當前目標;
7. 監聽鍵盤事件:cc.SystemEvent.on(type, function, target, useCapture);監聽的時候,我們需要一個cc.SystemEvent類的實例,我們有一個全局的實例cc.systemEvent,小寫開頭(實際使用時小寫開頭的)
- cc.SystemEvent.EventType.KEY_DOWN 按鍵按下;
- cc.SystemEvent.EventType.KEY_UP 按鍵彈起;
8. 自定義事件:
- 監聽:this.node.on(“自定義事件名稱”, function, target, useCapture);
- 自派送: emit(“事件名稱”, [detail]); 只有自己能夠收到;
- 冒泡派送: dispatchEvent(new cc.Event.EventCustom(“name”, 是否冒泡傳遞));
start: function() {
// 派發者,只能傳遞給自己,不會向上傳遞
this.node.emit("pkg_event", {blake: "huang"});
// end
// 派送者,不只是發給自己,發給我們這個體系;
// true/false, true向上傳遞, false不向向上傳遞
var e = new cc.Event.EventCustom("pkg_event", true);
e.detail = {blake: "huang"};
this.node.dispatchEvent(e);
},
9. ccc座標系:
-
相對(節點)座標系,兩種相對節點原點的方式(1) 左下角爲原點, (2) 錨點爲原點(AR)
-
節點座標和屏幕座標的相互轉換; 我們到底使用哪個?通常情況下帶AR;
// 節點座標轉到屏幕(世界)座標 cc.p(0, 0)
var w_pos = this.node.convertToWorldSpace(cc.p(0, 0)); // 左下角爲原點的 cc.p(430, 270)
console.log(w_pos);
w_pos = this.node.convertToWorldSpaceAR(cc.p(0, 0)); // 錨點爲原點 cc.p(480, 320)
console.log(w_pos);
// end
var w_pos = cc.p(480, 320);
var node_pos = this.node.convertToNodeSpace(w_pos);
console.log(node_pos); // cc.p(50, 50)
node_pos = this.node.convertToNodeSpaceAR(w_pos);
console.log(node_pos); // cc.p(0, 0)
// 獲取節點的包圍盒, 相對於父親節點座標系下的包圍盒
var box = this.node.getBoundingBox();
console.log(box);
// 世界座標系下的包圍盒
var w_box = this.node.getBoundingBoxToWorld();
console.log(w_box);
this.node.on(cc.Node.EventType.TOUCH_START, function(t) {
var w_pos = t.getLocation();
var pos = this.node.convertToNodeSpaceAR(w_pos);
console.log(pos);
pos = this.node.convertTouchToNodeSpaceAR(t);
console.log("====", pos);
}, this);
// 我要把當前這個sub移動到世界座標爲 900, 600;
//
// 把世界座標轉到相對於它的父親節點的座標
var node_pos = this.node.parent.convertToNodeSpaceAR(cc.p(900, 600));
this.node.setPosition(node_pos); // 相對於this.node.parent這個爲參照物,AR爲原點的座標系
// end
// 獲取當前節點的世界座標;
this.node.convertToWorldSpaceAR(cc.p(0, 0));
10. Action的使用:
- Action類是動作命令,我們創建Action,然後節點運行action就能夠執行Action的動作;
- Action分爲兩類: (1) 瞬時就完成的ActionInstant, (2) 要一段時間後才能完成ActionIntervial;
- cc.Node runAction: 節點運行action;
- cc.moveTo, cc.moveBy To: 目標 By: 變化
MoveTo:(x, y) → (x1, y1)
MoveBy:(x, y) → (x + x1, y + y1)
-
cc.sequnce, cc.repeat, cc.repeatForever
-
Action easing(緩動的方式): 加上緩動特效, cc.easeXXXXX查看文檔設置自己想要的緩動對象
-
stopAction: 停止運行action
-
stopAllActions: 停止所有的action;
onLoad: function () {
// move
// var mto = cc.moveTo(1, cc.p(100, 100)); // cc.moveTo(1, x, y);
// this.node.runAction(mto);
// var mby = cc.moveBy(1, cc.p(100, 100)); // cc.moveBy(1, x, y); 變化多少
// this.node.runAction(mby);
// rotate
// var rto = cc.rotateTo(1, 180); // 旋轉到180度; rotation 180;
// this.node.runAction(rto);
// var rby = cc.rotateBy(1, 75); // 在原來的基礎上,變化75,可正,可負
// this.node.runAction(rby);
// scale
// this.node.scale = 2;
// var sto = cc.scaleTo(1, 1.1); // 到1.1倍
// this.node.runAction(sto);
// this.node.scale = 2;
// var sby = cc.scaleBy(1, 1.1); // 原來的基礎,變化1.1 * 2
// this.node.runAction(sby);
// opactify
// var fin = cc.fadeIn(1);
// this.node.opacity = 0;
// this.node.runAction(fin);
// var fout = cc.fadeOut(1);
// this.node.runAction(fout); // 物體還是在的的
// var fto = cc.fadeTo(1, 128);
// this.node.runAction(fto);
// function Action
/*var func = cc.callFunc(function() {
console.log("call Func actin!!!!!");
}.bind(this));
console.log("begin ####");
this.node.runAction(func);
console.log("end ####");*/
// 移動到 目的地,後,隱藏這個物體怎辦? // 命令清單, [Action1, A2, A3],
// seq Action
/*var m1 = cc.moveTo(1, 100, 100);
var fout = cc.fadeOut(0.5);
var seq = cc.sequence([m1, fout]);
this.node.runAction(seq);*/
// 一個節點可以同時運行多個Action, 一邊,一邊
/*var m1 = cc.moveTo(1, 100, 100);
var fout = cc.fadeOut(0.5);
this.node.runAction(fout);
this.node.runAction(m1);*/
// 不斷的放大縮小
/*var s1 = cc.scaleTo(0.8, 1.1);
var s2 = cc.scaleTo(0.8, 0.8);
var seq = cc.sequence([s1, s2]);
var rf = cc.repeatForever(seq);
this.node.runAction(rf);*/
// 勻速的飛過,傻了, 緩動
// 回彈
/*this.node.y = 0;
var m = cc.moveTo(1, 100, 0).easing(cc.easeBackOut());
this.node.runAction(m);*/
/*var r = cc.rotateBy(3, 360).easing(cc.easeCubicActionOut());
var rf = cc.repeatForever(r);
this.node.runAction(rf);
// this.node.stopAction(rf);
this.node.stopAllActions();*/
// end
// 移動了到100, 0,刪除
/*var m = cc.moveTo(1, 100, 0);
var end_func = cc.callFunc(function() {
this.node.removeFromParent();
}.bind(this));
var seq = cc.sequence([m, end_func]);
this.node.runAction(seq);*/
// cc.Delay,
var d1 = cc.delayTime(3);
var fout = cc.fadeOut(0.5);
var end_func = cc.callFunc(function() {
this.node.removeFromParent();
}.bind(this))
var seq = cc.sequence([d1, fout, end_func]);
this.node.runAction(seq);
},
11. cc.Component屬性(組件類,所有組件的基類)
var my_item = require("my_item");
...
properties: {
//基本數據類型,數,bool,字符串,color,pos,size
speed: 100,
is_debug: false,
url_str: "",
color: cc.color(0,0,0,255),
pos: cc.p(0,0),
size: cc.Size(100,100)
// 系統的組件
sprite_item: {
type: cc.Sprite,
default: null, // null/[]
}
// 組件的代碼組件
custom_comp: {
type: my_item,
default: null, // null/[]
},
}
12. cc.Sprite: 配置圖片的SIZE_MODE
-
CUSTOM 大小和CCNode的大小一致;
-
RAW 原始的圖片大小;
-
TRIMMED 大小爲原始圖片大小, 顯示的內容是裁剪掉透明像素後的圖片;
trim: 是否裁剪掉 圖片的透明區域, 如果勾選,就會把完全透明的行和列裁掉, 做幀動畫的時候,我們一般是用原始大小不去透明 度,動畫,不至於抖動;
13. Filled模式(遊戲中道具的時間進度顯示條、個性化時間進度條案例等應用,比較常用,最好掌握)
- 配置Filled模式, 設置爲Radius參數
- 配置Radius的參數模式,
- 中心: 位置座標(0, 1小數), (0, 0)左下腳, (1, 1) 右上角 (0.5, 0.5) 中心點
-
Fill Start 開始的位置: 0 ~1, 右邊中心點開始,逆時針走
-
Fill Range: 填充總量(0, 1];
-
FillRange爲正,那麼就是逆時針,如果爲負,那麼就是順時針;