cocos creator游戲開發


1. 初來乍到

打開 Cocos Creator 點擊新建空白項目,在默認布局的左下區域,一個黃黃assets文件夾映入眼簾。作為前端的你對這個文件是不是再熟悉不過了。是的,和你想象的一樣,開發游戲中所有資源,腳本都會放置到該文件。

2. 初步探索

項目建立好以后,對各區域的功能大致了解下,作為前端的你,主要還是要迅速的掌握cc提供的各種NB的功能。所以,還得趕緊打開 [官網](https://docs.cocos.com/creator/manual/zh/) 快速瀏覽一遍。官網也寫得很好,提供中文和英文,對於英文能力不好的伙伴來說,簡直是不能太好了。是不是找到了當初學習Vue的感覺。作為前端的你,整天寫了一堆業務控制,處理各種布局,各種兼容,對奇怪的css優先級搞得雲里霧里的。所以是時候換一個更有意思開發場景,給自己做個游戲解悶多好

cc是一個跨平台框架,一端編譯多端發布。想想前端的 mpvue taro uni-app,無不是解決此類問題,再加上gulp,webpack,再來一堆node_modules,啥less sass stylus.各種環境配置那是相當的復雜。所以業界流傳,前端已經進入深水區,真的一點不假。 然而cc依然可以讓你舒適的寫JS或者TS ,並且沒有繁雜的配置,一鍵搞定打包發布。

3. 小試牛刀

上邊說了一大堆,其實並沒有什么鳥用。在官網首頁中,給開發者提供了個完整坑爹的游戲《摘星星》,如果打包到微信小游戲,需要橫屏,不太友好。本着舉一反三的求學態度,我利用此場景,換了一個游戲玩法。開發了自己第一款小游戲《坦克俠》,當然也很坑爹

游戲開發主要是確定游戲規則,我新改編的玩法就是在星空中隨機生成不同數量的星星,並一直往下掉落,我的主角坦克必須在星星掉落前接住。丟失一顆星星生命減一,生命為0游戲結束。當然我們主角每收集一顆星星,根據當前的難度會添加一定的分數。累計到一定的分數,又可以給主角添加一點生命值

在官網 [下載初始項目](https://github.com/cocos-creator/tutorial-first-game/releases/download/v2.0/start_project.zip) 下載一個基礎項目,該項目中只有一些項目基本圖片和聲音。接下來,我們需要建立場景,制作預制資源,添加控制腳本,編譯發布微信小游戲,[快速開始](https://docs.cocos.com/creator/manual/zh/getting-started/quick-start.html)

制作一個游戲場景,與官網不同的是,我將Canvas的Size屬性,在屬性檢查器中設置為 288 x 512 ,並且勾選了 Fit Height以及 Fit Width 用以適應同的手機屏幕。然后拖動背景圖片到層級管理器中,並在場景編輯器中設置背景Size屬性,使其等於Canvas的Size屬性。然后依次在層級管理器中新建三個Label控件,依次拖動到背景圖片左上角和右上角,用以記錄生命值,當前分數,以及最高分數。接着在場景中間添加一個Label控件和一個Button按鈕用於顯示游戲結束和開始游戲。在場景底部拖動放置我們的主角坦克。所以最新場景的效果應該是如下顯示的那樣

小程序碼 場景預覽 微信群

4. 一頓操作猛如虎

游戲場景設計,看似酷炫,無非就是拖拖拖。依稀找到了當年C#開發winform的感覺,隨便搞整一下,一個界面就出來了。所以導致很多人開發winform,webform很簡單,很傻瓜,其實不是的。重要的還是后邊的業務邏輯,解決方案,這些都是超越語言之上的東西。所以cc的場景編輯,就不多說了,直接分析我們游戲實現邏輯。開始之前我們先初始一下typescript開發環境,操作如下圖

 

typescript


依次點擊安裝vs code 擴展插件,添加 Typescript項目配置。接下來就要編寫腳本了,所有還是有必要了解下cc腳本的生命周期

 

  1. onLoad 首次激活時觸發,一般做一些初始化操作。對比Vue我覺得最合適的應該是beforeMount回調

  2. start 首次激活時觸發,一般初始化一些中間狀態的數據,改方法在onLoad之后,在第一次update之前,對比Vue自然應該是mounted回調

  3. update 該回調會頻繁調用,每一幀調用一次。對比Vue應該是beforeUpdate回調,雖然他們性質不一樣

  4. lateUpdate 該回調會頻繁調用,也是每幀調用一次,對比Vue應該updated回調

  5. onDestroy 根據條件調用,當組件調用了自身的 destroy()方法,會觸發此回調

  6. onEnable 根據條件調用, enabled 屬性從 false 變為 true 或 active 屬性從 false 變為 true 觸發此回調

  7. onDisable 根據條件調用, enabled 屬性從 true 變為 false 或active 屬性從 true 變為 false觸發此回調

4.1 讓主角動起來

做過前端的你一定知道,要想拖動一個DIV,一定是在Body中監聽鼠標的移動事件。在移動端一定是監聽觸摸移動事件。是的,在cc里邊做游戲,希望一個組件動起來依然是這么操作的,那么cc里邊是如何注冊事件的呢?兩個方式,一個在場景編輯器下角的屬性中添加腳本里邊的方法,另外一種就是直接在腳本里邊添加。當然我推薦第二種。雖然IDE會幫我們生成很多代碼,如果不自己寫一遍,就永遠不曉得數據流向。就像當年開發winform時,很多人拖動一個按鈕控件,然后雙擊控件,IDE就自動幫你注冊好了一個用戶點擊事件。殊不知,IDE是在xx.design.cs中通過代碼替你注冊好的。所以既然剛開始學,一定要了解清楚它的原理。

  • cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this) 注冊一個系統事件 ,支持按鍵事件和重力感應事件

  • this.node.parent.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this) 在某個節點注冊一個Node 支持的事件類型

所以,主角移動無非實在TouchMove時改自己的X/Y

// author:herbert qq:464884492
onTouchMove(e: cc.Event.EventTouch) {
let deltaX = e.getDeltaX(); //獲取本次和上次移動的增量
let deltaY = e.getDeltaY();
//左移
if (deltaX < 0 && this.node.x <= this.leftMinX) return;
if (deltaX > 0 && this.node.x >= this.rightMaxX) return;
if (deltaY > 0 && this.node.y >= this.topMaxY) return;
if (deltaY < 0 && this.node.y <= this.bottomMinY) return;
this.node.x += deltaX;
this.node.y += deltaY;
}

4.2 生成坑爹的星星

在cc里邊需要重復生成的對象,我們一般會制作成一個預制資源。然后在基本中通過代碼實例化。何為預制資源,就權當它是一個模板吧。現在生成我們第一顆小星星

// author:herbert qq:464884492
buildOneStar() {
let star = cc.instantiate(this.starPrefab);
this.node.addChild(star);
return star;
}

是的,就是這么簡單,有沒有class.newInstance()的感覺,當然這個只是在場景的默認位置生成了一個星星而已。我們需要更多的信息,位置肯定也不是默認位置,所以還得繼續碼代碼

// author:herbert qq:464884492
buildRandomStar() {
let tempX = 0;
let tempY = 0;
tempX = Math.floor(this.starMaxX - Math.random() * this.starMaxX);//生成一個不大於MaxX的坐標
tempY = Math.floor(this.starMaxY - Math.random() * this.starMaxY);
if (Math.random() < 0.5) tempX = tempX * -1;
let star = this.buildOneStar();
star.setPosition(tempX, tempY);
star.zIndex = this.tank.zIndex - 1;
star.name = "star";
star.getComponent("Star").index = this;
}

這樣感覺好多了,可以生成很多星星了,不過,我們的星星也得往下掉才行,作為前端的你首先想到的是不是更新星星的Y值,是的,我就是這么做的。利用生命周期中start方法,定義一個從上往最小Y運動的動畫。后來才了解到所有的游戲引擎都有物理特性,開啟了自己就掉下來了。不過原理肯定還是改變y值。何況這么簡單的游戲完全沒必要使用

start() {
// 定義一個Action
let downAction = cc.moveTo(this.index.starFallSpeed, this.node.x, this.minY - 60);
downAction.easing(cc.easeSineOut());
this.node.runAction(downAction);
}

4.3 是時候接住星星了

只要是游戲少不了做碰撞檢測,如果在CC中開啟了物理引擎還好,直接跟星星和主角添加一個剛體就好了,不過我們沒開啟,那就自己來了。不過碰撞檢測無非就是判斷兩個區域有沒有重疊地方,簡單判斷就上下左右,左上右上左下右下八個點。不過我這里偷了個懶,直接判斷星星和主角間向量的距離。

//author:herbert qq:464884492
...
let distance = this.node.position.sub(this.tank.getPosition()).mag();
if (distance < (this.tank.width / 2 - 5)) {
console.log("接住了");
}
...

4.4 來點刺激的

游戲嘛,總不能一成不變那多沒意思,所以隨着時間的推移我們的調整點難度。我這個游戲難度無非就一下兩個方面

  1. 生成星星的速度加快

  2. 星星掉落的速度加快

//author:herbert qq:464884492
...
this.index.scoreNum += this.index.starScoreSpeed;
this.index.score.string = "得分:" + this.index.scoreNum;
// 降落速度加
if (Math.floor(this.index.scoreNum / 100) == this.index.starScoreSpeed - 4 && this.index.starFallSpeed > 1) {
this.index.starFallSpeed -= 0.2; //下降速度加快
if (this.index.starBuildTimeOut > 200) {
this.index.starBuildTimeOut -= 100; //生成速度加快
}
this.index.lifeNum += 1;
if (this.index.starScoreSpeed < 10) {
this.index.starScoreSpeed += 1;
}
}
cc.audioEngine.play(this.index.scoreClip, false, 0.2);
this.index.allStars.splice(this.index.allStars.indexOf(this.node), 1)
this.node.destroy();
...

4.5 是時候結束了

游戲嘛,也不能一直玩下去。不然多沒挑戰。自從調整游戲難度后我的最高分重來就沒有超過4000.

//author:herbert qq:464884492
...
if (this.node.y <= this.minY) {
this.index.lifeNum -= 1;
this.index.life.string = "生命:" + this.index.lifeNum;
this.node.destroy();
this.index.allStars.splice(this.index.allStars.indexOf(this.node), 1)
if (this.index.lifeNum <= 0) {
this.index.gameOver.node.active = true;
this.index.btnPlay.node.active = true;
this.index.starIsRunning = false;
let storageValue = cc.sys.localStorage.getItem(this.index.HIGHSTORAGEKEY);
if (storageValue && parseInt(storageValue) > this.index.scoreNum) {
return;
}
cc.sys.localStorage.setItem(this.index.HIGHSTORAGEKEY, this.index.scoreNum);
this.index.highScore.string = "最高分:" + this.index.scoreNum;
}
}
...

5. 來點實際的

做技術嘛,大多都是 Talk is cheap,Show me your code.做點總結吧

    • 開源地址

    • 在基本中定義的屬性,切記在編輯器中拖動綁定

    • 多看官網api,多開實例代碼

    • 發布微信小游戲一定不要有英文,會導致審核不通過


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM