分享內容預覽javascript
小遊戲體驗:css
Q:cocos creator 是什麼,能幹什麼?
A:cocos creator是用來作遊戲的,能夠打包構建到web,h5,ios,android,微信小遊戲等各端平臺運行。html
開發前的準備:組件與實體
Cocos Creator 的工做流程是以組件式開發爲核心的,組件式架構也稱做 組件-實體系統(或 Entity-Component System),簡單的說,就是以組合而不是繼承的方式進行實體的構建。
參考:理解 組件-實體-系統 (ECS \CES)遊戲編程模型java
下面新建一個cocos creator項目工程,帶着你們瀏覽一下creator場景編輯器相關,生成的項目目錄文件,最終打包編譯的文件。node
這裏的數據驅動,是creator的變革。全部場景都會被序列化爲純數據,在運行時使用這些純數據來從新構建場景,界面,動畫甚至組件等元素。
也就是說,在編輯器中的修改,會保存爲json數據,保留在版本控制中,並在運行時起做用。android
新建的hello world項目目錄
ios
assets(資源文件夾)css3
library(資源庫)git
settings(項目設置)github
project.json
bulid(構建目錄)
在 Cocos Creator 中,遊戲場景(Scene)是開發時組織遊戲內容的中心,也是呈現給玩家全部遊戲內容的載體。遊戲場景中通常會包括如下內容:
當玩家運行遊戲時,就會載入遊戲場景,遊戲場景加載後就會自動運行所包含組件的遊戲腳本,實現各類各樣開發者設置的邏輯功能。因此除了資源之外,遊戲場景是一切內容創做的基礎。
舉個例子,下圖中,是在咱們的hello world的工程中的節點(實體),node屬性(Node 標題開始的部分就是節點的屬性),組件及組件屬性。
節點、node屬性、組件的關係也就是:節點的顯示,是根據node屬性調整(放大,縮小等)以及組件渲染共同決定的。
接下來具體介紹node屬性以及組件相關。
重點介紹rotation,anchor, position。
舉個例子: 全部子節點都是以 父親錨點所在位置 做爲座標系原點,只用顧及到內部就能夠。好比英雄的移動,移動整個父親就行,裏面的血條,任務都跟着移動,相對於父親的節點座標是不變的。
sprite組件,label組件,button組件,代碼組件
重點了解:Type模式,在咱們的使用過程當中,應用普遍。可讓咱們處理起圖像來更加方便。
九宮格(sliced)。圖像將被分割成九宮格,並按照必定規則進行縮放以適應可隨意設置的尺寸(size)。一般用於 UI 元素,或將能夠無限放大而不影響圖像質量的圖片製做成九宮格圖來節省遊戲資源空間。
例如: 圓角的圖形,只拉伸中間部分就能夠。(聊天氣泡)
填充模式(filled)。根據原點,以及設置的填充類型。能夠按照比例,方向繪畫出整個圖像。
填充類型:HORIZONTAL(橫向填充)、VERTICAL(縱向填充)和 RADIAL (扇形填充)三種。
橫向填充: 進度條的展現。扇形填充: 技能cd小圖標。
顯示文字,文字能夠是系統字體,TrueType 字體或者 BMFont 字體和藝術數字。更改font屬性就能夠。
Target: 帶有腳本組件的節點。
Component: 腳本組件名稱。
Handler: 指定一個回調函數,當用戶點擊 Button 並釋放時會觸發此函數。
CustomEventData: 用戶指定任意的字符串做爲事件回調的最後一個參數傳入。
開發者能夠爲節點添加腳本組件。在腳本組件中,能夠獲取各個節點,控制節點作一些遊戲上的變化。下面一節仔細闡述。
打開新建的hello world腳本組件的 js文件。
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!'
},
// use this for initialization
onLoad: function () {
this.label.string = this.text;
},
// called every frame
update: function (dt) {
},
});
複製代碼
class() 是 cc 模塊下的一個方法,這個方法用於聲明 Cocos Creator 中的類。返回一個構造函數。在creator編輯器中,添加用戶腳本組件,至關於new
這個構造函數,也就是添加的實例。
既能夠定義節點的位置,顏色,大小等屬性(系統),也能夠定義爲本身編寫的組件類型。
// 1. 例如:套牛小遊戲。更換牛的種類,以及切換背景圖。
// 2. 拋出去的腳本組件中,cowSkinType屬性,是一個數組,用來表示牛的種類。
// 3. 他的類型就是一個自定義的cowSkin的組件。cowSkin組件的屬性是一個數組,類型是cc.SpriteFrame,能夠實現背景圖更換,引發牛的視覺上跑動。
const cowSkinComponent = cc.Class({
name: 'cowSkin',
properties: {
cowAnimate: {
type: cc.SpriteFrame,
default: [],
},
},
})
cc.Class({
extends: cc.Component,
properties: {
cowSkinType: {
type: cowSkinComponent,
default: [],
}
},
})
複製代碼
onload
,節點首次激活時觸發,好比所在的場景被載入,或者所在節點被激活的狀況下。注意,此時場景的節點和數據都已經準備好了。start
,一般用於初始化一些中間狀態的數據,這些數據可能在 update 時會發生改變。在onload以後執行。update
,每一幀(1s / 幀數)渲染前更新物體的行爲,狀態和方位。onEnable
, onDisable
, lateUpdate
, onDestroy
不經常使用。this
,指向new
出來的組件實例。
this.node
,組件所屬的節點。能夠在該節點下改變node屬性,也能夠找到各個組件,改變組件的屬性。
getComponent
方法,尋找節點上的組件。start: function () {
cc.log( this.node.getComponent(cc.Label) === this.getComponent(cc.Label) ); // true
}
複製代碼
// 全部子節點
const children = this.node.children
// 根據name查找單個子節點
let child = this.node.getChildByName('cow')
// 根據路徑查找子節點,適合子節點層級比較深的狀況。
child = cc.find('Canvas/score/val', this.node)
複製代碼
this.time = cc.find('Canvas/time/tiemLabel')
複製代碼
start () {
// 激活,關閉節點
this.node.active = false
// // 更改節點位置
this.node.x = 120
this.node.y = 320
this.node.position = cc.v2(100, 50)
// // 節點旋轉
this.node.rotation = 90
this.node.setScale(2, 2)
// // 更改節點尺寸
this.node.width = 100
this.node.height = 100
// // 更改顏色
this.node.color = cc.Color.RED
},
複製代碼
const node1 = cc.instantiate(cc.Node); // 克隆節點。
const node2 = cc.instantiate(cc.Prefab) // 複製預製節點。(好比,重複生成的牛)
cc.Node.destroy() // 銷燬節點
複製代碼
這裏要說一下,預製資源(預製節點)。預製資源cc.Prefab,適用於 通用性強、重複使用的且個體之間存異較少時。
建立Prefab很簡單,在層級管理器視圖建立的任意節點->拖動到->資源管理器視圖便可完成建立。
節點系統事件:鼠標,觸摸,
全局系統事件:鍵盤,重力傳感
(1)鼠標事件:
// 使用枚舉類型來註冊
this.node.on(cc.Node.EventType.MOUSE_DOWN, function (event) {
console.log('Mouse down');
}, this);
// 使用事件名來註冊
this.node.on('mousedown', function (event) {
console.log('Mouse down');
}, this);
複製代碼
觸摸事件同上,touchstart
, touchmove
,touchend
,touchcancel
。
event
給咱們提供了不少的api,幫助咱們獲取位置相關信息。例如,touchmove
中,能夠根據getDelta
,獲取觸點距離上一次時間移動的距離對象。在飛機大戰中適用。
this.node.on('touchmove', (e) => {
const delta = e.getDelta()
const {x, y}= delta
this.node.x += x
this.node.y += y
})
複製代碼
(2)鍵盤事件
onLoad () {
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this)
},
onKeyDown(event) {
const { KEY } = cc.macro
switch (event.keyCode) {
case KEY.a:
console.log(event.keyCode)
console.log(KEY.a)
console.log('aaaaaaaaa')
break;
case 'b':
console.log('bbbbbb')
break;
default:
break;
}
},
複製代碼
輸出結果:
一開始覺得就是簡單的字符串對應關係,經過console發現不是。bbbb是輸出不了的。
(3)自定義事件
// 發送事件
this.node.emit()
this.node.dispatchEvent() // 事件派送,冒泡,能夠跨節點
// 監聽
this.node.on()
// 取消監聽
this.node.off()
複製代碼
(1)聲明一個動做類型,運行這個動做。
const action = cc.moveTo(2, 20, 300)
this.node.runAction(action)
// 中止一個動做
this.node.stopAction(action);
// 中止全部動做
this.node.stopAllActions();
複製代碼
(2)一些經常使用動做。
const a1 = cc.scaleTo(1, 30)
const a2 = cc.fadeIn(2)
複製代碼
動做列表:click me
(3)容器動做,讓每一個動做組合起來運動。cc.sequence
(順序), cc.spawn
(同步), cc.repeat
(重複一次), cc,repeatForever
(永久重複)。
// sequence, spawn
const ac1 = cc.moveTo(2, 50, -130)
const ac2 = cc.scaleTo(1, 4, 4)
const ac3 = cc.rotateTo(2, 90)
const sq = cc.sequence(ac1, ac2, ac3)
this.node.runAction(sq)
// repeat, repeatForever
const ac1 = cc.moveBy(2, 50, -130)
const ac2 = cc.scaleBy(1, 4, 4)
const ac3 = cc.rotateBy(2, 90)
const sq = cc.sequence(ac1, ac2, ac3)
const rep = cc.repeat(sq, 4)
this.node.runAction(rep)
複製代碼
(4)動做回調,能夠在這裏處理一些邏輯。好比運動中的節點,判斷是否碰到物體。
const action = cc.moveTo(5, 20, 300)
const finished1 = cc.callFunc(() => {
// 好比套牛遊戲中,判斷牛的位置,是否符合繩子套牛的範圍
console.log(1111111111111111)
})
const ac2 = cc.moveTo(8, 333, 4444)
const end = cc.callFunc(() => {
console.log(222222222222222)
})
const myAction = cc.sequence(action, finished1, ac2, end);
this.node.runAction(myAction)
複製代碼
(5)cc.delayTime(4)
延遲,搭配動做使用。好比說,暴出裝備消失。
(6)緩動動做。
緩動動做不能夠單獨存在,它永遠是爲了修飾基礎動做而存在的,它能夠用來修改基礎動做的時間曲線,讓動做有快入、緩入、快出或其它更復雜的特效。須要注意的是,只有時間間隔動做才支持緩動。
和css3 的 animation-timing-function速度曲線類似
// 節點旋轉,慢慢變慢
const action = cc.rotateBy(3, 360)
const doAction = action.easing(cc.easeCubicActionOut())
const repAction = doAction.repeatForever(doAction)
this.node.runAction(repAction)
複製代碼
// 場景切換
cc.director.loadScene("test")
複製代碼
scheduleOnce
一次schedule
(回調函數,間隔,重複次數,延遲)unschedule
取消一個計時器unscheduleAllCallbacks
取消該組件的全部計時器this.scheduleOnce(() => {
console.log('scheduleOnce')
}, 2)
const interval = 4
const repeat = 3
const delay = 4
this.callBack = () => {
console.log('schedule')
this.unschedule(this.callBack)
this.unscheduleAllCallbacks()
}
this.scheduleOnce(this.callBack, interval, repeat, delay)
複製代碼
若是使用schedule
,永久重複,可使用cc.macro.REPEAT_FOREVER
,或者默認不寫。
// xhr
// 能夠直接使用 new XMLHttpRequest() 來建立一個鏈接對象,也能夠經過 cc.loader.getXMLHttpRequest() 來建立,二者效果一致
const url = 'https://easy-mock.com/mock/5cf0b076d205e36f67612985/test/testXhr'
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status < 400)) {
var response = xhr.responseText;
console.log('response', response);
}
};
xhr.open("GET", url, true);
xhr.send();
複製代碼
體驗地址: 建議移動端訪問
開始以前,先來梳理一下流程:
注意:
(1)修改根節點Canvas高度,適用於手機。
(2)插入相關節點,這裏注意button的屬性。button是個按鈕組件,須要添加出sprite組件之外,應該添加個button組件,用來控制點擊。其中,觸摸按鈕的變化,button的ransition屬性是咱們上文提到的重點。
牛須要隨機出現,並且要移動。那麼咱們能夠作一個牛的預製體。每次產生時,克隆這個預製體便可。
(1)生成三個隨機的,而且是移動的牛。維護一個二維數組來控制。映射到咱們的組件上也就是這裏用到了自定義組件,自定義類型。
// cowSkinType屬性,是一個數組,用來表示牛的種類。
// 他的類型就是一個自定義的cowSkin的組件。cowSkin組件的屬性是一個數組,類型是cc.SpriteFrame,能夠實現背景圖更換,引發牛的視覺上跑動。
const cowSkinComponent = cc.Class({
name: 'cowSkin',
properties: {
cowAnimate: {
type: cc.SpriteFrame,
default: [],
},
},
})
cc.Class({
extends: cc.Component,
properties: {
cowSkinType: {
type: cowSkinComponent,
default: [],
}
},
})
複製代碼
在編輯器中,cow組件的每一個屬性,sprite frame對應着不一樣的動做的牛。
(2)讓牛自己動做運動起來,經過切換背景圖片
onLoad () {
//隨機生成牛
this.cowType = Math.floor(Math.random() * 3)
// 以及 牛的背景更換
this.cowShow = this.node.getComponent(cc.Sprite)
},
cowPlay(dt) {
// 牛的背景更換
this.playTime += dt
let index = Math.floor(this.playTime / this.duration) // 向下取整數
if (index >= this.cowAniArray.length) {
index = 0
this.playTime -= (this.duration * this.cowAniArray.length) // 接着上面的時間結算
}
// 在合法的範圍以內
this.cowShow.spriteFrame = this.cowAniArray[index]
},
複製代碼
(3)牛的移動,在update
函數中,每幀 * 速度 - 偏移量。
// 初始化速度
this.cowSpeed = -(Math.random() * 300 + 200)
update (dt) {
const s = this.cowSpeed * dt
this.node.x += s
}
複製代碼
(4)牛基本製做完了,咱們要想重複利用cow這個組件,把他轉化爲prefab預製體,每次生成新的牛的時候,克隆預製體,就能夠生成一個牛。
generatCow() {
const newCow = cc.instantiate(this.cowPrefab)
this.node.addChild(newCow)
newCow.active = true
newCow.setPosition(this.cowPosition.x, this.cowPosition.y)
// 調用本身生成牛
this.scheduleOnce(this.generatCow.bind(this), Math.random() * 3 + 2)
},
startGame() {
if (!this.isStart) {
this.isStart = true
// 生成牛以前,先把全部的計時器取消
this.unscheduleAllCallbacks()
this.generatCow()
}
},
onLoad () {
// 預製體牛的位置
this.cowPosition = {
x: 520,
y: -120,
}
// 遊戲是否開始
this.isStart = false
this.startGame()
},
複製代碼
// 初步的繩子套牛動做銜接
shootRopeOut() {
if (this.isShooting) return
this.isShooting = true
const aniOut = cc.moveTo(0.5, 0, -60)
const aniIn = cc.moveTo(0.5, 0, -550)
const endFn = cc.callFunc(() => {
this.setRopeEmpty()
this.isShooting = false
}, this.node)
const seq = cc.sequence([aniOut, aniIn, endFn])
this.node.runAction(seq)
},
複製代碼
generateCow
生成牛,保存起來。牛出了畫面,從數組中清空。// 拿到如今牛的類型
hitCow() {
let cowType = -1
for(let i = 0; i < this.cowGet.length; i++) {
if (this.cowGet[i].x >= 70 && this.cowGet[i].x <= 190) {
// cow節點對應的代碼組件中的cowType屬性
cowType = this.cowGet[i].getComponent('cow').cowType
this.cowGet[i].removeFromParent()
this.cowGet.splice(i, 1)
return cowType
}
}
return -1
},
// 上面(3.套牛動做銜接)中,再加入繩子套到牛,背景圖的改變
const getCow = cc.callFunc(() => {
const cowType = this.gameScene.hitCow()
if (cowType >= 0 && cowType <= 2) {
this.node.y = 42
this.setRopeCow(cowType)
}
}, this.node)
const seq = cc.sequence([aniOut, getCow, aniIn, endFn])
複製代碼
startGame
事件綁定到該按鈕的點擊事件上。注意:mask蒙層面板,須要添加一個button。攔下用戶點擊行爲對於套繩按鈕的影響。就是不能在點擊套繩按鈕了。
繩子套到牛,加上音樂和粒子特效的提示。
cc.loader.loadRes('mou', cc.AudioClip, function (err, clip) {
cc.audioEngine.play(clip);
});
複製代碼
注意:這裏的音樂資源,須要放在resources目錄下,不然不會被加載。
const rope = this.node.getChildByName('rope')
rope.zIndex = 1000
const startBtn = this.node.getChildByName('startBtn')
startBtn.zIndex = 2000
this.check = cc.find('Canvas/check')
this.check.zIndex = 3000
複製代碼
在微信開發工具裏查看如圖。
cocos creator集成的處理開發方案,不管是直接操做畫面,或者是和js腳本的結合,都提供了便利。
最後,本次分享的主要目的是和你們一塊兒認識Cocos Creator,瞭解它的工做流程,以及如今的用途。感興趣的同窗,能夠繼續了下進階中的動畫剪輯系統,碰撞檢測系統,微信小遊戲分包加載等。