cocos creator遊戲開發

1.初來乍到

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

2. 初步探索

項目創建好之後,對各區域的功能大體瞭解下,做爲前端的你,主要仍是要迅速的掌握cc提供的各類NB的功能。因此,還得趕忙打開 官網 快速瀏覽一遍。官網也寫得很好,提供中文和英文,對於英文能力很差的夥伴來講,簡直是不能太好了。是否是找到了當初學習Vue的感受。做爲前端的你,成天寫了一堆業務控制,處理各類佈局,各類兼容,對奇怪的css優先級搞得雲裏霧裏的。因此是時候換一個更有意思開發場景,給本身作個遊戲解悶多好css

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

3. 小試牛刀

<p>上邊說了一大堆,其實並無什麼鳥用。在官網首頁中,給開發者提供了個完整坑爹的遊戲《摘星星》,若是打包到微信小遊戲,須要橫屏,不太友好。本着觸類旁通的求學態度,我利用此場景,換了一個遊戲玩法。開發了本身第一款小遊戲《坦克俠》,固然也很坑爹</p>
<p>遊戲開發主要是肯定遊戲規則,我新改編的玩法就是在星空中隨機生成不一樣數量的星星,並一直往下掉落,個人主角坦克必須在星星掉落前接住。丟失一顆星星生命減一,生命爲0遊戲結束。固然咱們主角每收集一顆星星,根據當前的難度會添加必定的分數。累計到必定的分數,又能夠給主角添加一點生命值</p>
<p>在官網 下載初始項目 下載一個基礎項目,該項目中只有一些項目基本圖片和聲音。接下來,咱們須要創建場景,製做預製資源,添加控制腳本,編譯發佈微信小遊戲,快速開始 </p>前端

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

場景預覽

小程序碼

微信羣

4. 一頓操做猛如虎

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

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

  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中經過代碼替你註冊好的。因此既然剛開始學,必定要了解清楚它的原理。webpack

  • cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this) 註冊一個系統事件 ,支持按鍵事件和重力感應事件
  • this.node.parent.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this) 在某個節點註冊一個Node 支持的事件類型

<p>因此,主角移動無非實在TouchMove時改本身的X/Y</p>git

// 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裏邊須要重複生成的對象,咱們通常會製做成一個預製資源。而後在基本中經過代碼實例化。何爲預製資源,就權當它是一個模板吧。如今生成咱們第一顆小星星github

// 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,多開實例代碼
  • 發佈微信小遊戲必定不要有英文,會致使審覈不經過
相關文章
相關標籤/搜索