打開 Cocos Creator 點擊新建空白項目,在默認佈局的左下區域,一個黃黃assets文件夾映入眼簾。做爲前端的你對這個文件是否是再熟悉不過了。是的,和你想象的同樣,開發遊戲中全部資源,腳本都會放置到該文件。javascript
項目創建好之後,對各區域的功能大體瞭解下,做爲前端的你,主要仍是要迅速的掌握cc提供的各類NB的功能。因此,還得趕忙打開 官網 快速瀏覽一遍。官網也寫得很好,提供中文和英文,對於英文能力很差的夥伴來講,簡直是不能太好了。是否是找到了當初學習Vue的感受。做爲前端的你,成天寫了一堆業務控制,處理各類佈局,各類兼容,對奇怪的css優先級搞得雲裏霧裏的。因此是時候換一個更有意思開發場景,給本身作個遊戲解悶多好css
cc是一個跨平臺框架,一端編譯多端發佈。想一想前端的 mpvue taro uni-app,無不是解決此類問題,再加上gulp,webpack,再來一堆node_modules,啥less sass stylus.各類環境配置那是至關的複雜。因此業界流傳,前端已經進入深水區,真的一點不假。 然而cc依然可讓你溫馨的寫JS或者TS ,而且沒有繁雜的配置,一鍵搞定打包發佈。html
<p>上邊說了一大堆,其實並無什麼鳥用。在官網首頁中,給開發者提供了個完整坑爹的遊戲《摘星星》,若是打包到微信小遊戲,須要橫屏,不太友好。本着觸類旁通的求學態度,我利用此場景,換了一個遊戲玩法。開發了本身第一款小遊戲《坦克俠》,固然也很坑爹</p>
<p>遊戲開發主要是肯定遊戲規則,我新改編的玩法就是在星空中隨機生成不一樣數量的星星,並一直往下掉落,個人主角坦克必須在星星掉落前接住。丟失一顆星星生命減一,生命爲0遊戲結束。固然咱們主角每收集一顆星星,根據當前的難度會添加必定的分數。累計到必定的分數,又能夠給主角添加一點生命值</p>
<p>在官網 下載初始項目 下載一個基礎項目,該項目中只有一些項目基本圖片和聲音。接下來,咱們須要創建場景,製做預製資源,添加控制腳本,編譯發佈微信小遊戲,快速開始 </p>前端
製做一個遊戲場景,與官網不一樣的是,我將Canvas的Size屬性,在屬性檢查器中設置爲 288 x 512 ,而且勾選了 Fit Height以及 Fit Width 用以適應同的手機屏幕。而後拖動背景圖片到層級管理器中,並在場景編輯器中設置背景Size屬性,使其等於Canvas的Size屬性。而後依次在層級管理器中新建三個Label控件,依次拖動到背景圖片左上角和右上角,用以記錄生命值,當前分數,以及最高分數。接着在場景中間添加一個Label控件和一個Button按鈕用於顯示遊戲結束和開始遊戲。在場景底部拖動放置咱們的主角坦克。因此最新場景的效果應該是以下顯示的那樣vue
遊戲場景設計,看似酷炫,無非就是拖拖拖。依稀找到了當年C#開發winform的感受,隨便搞整一下,一個界面就出來了。因此致使不少人開發winform,webform很簡單,很傻瓜,其實不是的。重要的仍是後邊的業務邏輯,解決方案,這些都是超越語言之上的東西。因此cc的場景編輯,就很少說了,直接分析咱們遊戲實現邏輯。開始以前咱們先初始一下typescript開發環境,操做以下圖java
依次點擊安裝vs code 擴展插件,添加 Typescript項目配置。接下來就要編寫腳本了,全部仍是有必要了解下cc腳本的生命週期node
作過前端的你必定知道,要想拖動一個DIV,必定是在Body中監聽鼠標的移動事件。在移動端必定是監聽觸摸移動事件。是的,在cc裏邊作遊戲,但願一個組件動起來依然是這麼操做的,那麼cc裏邊是如何註冊事件的呢?兩個方式,一個在場景編輯器下角的屬性中添加腳本里邊的方法,另一種就是直接在腳本里邊添加。固然我推薦第二種。雖然IDE會幫咱們生成不少代碼,若是不本身寫一遍,就永遠不曉得數據流向。就像當年開發winform時,不少人拖動一個按鈕控件,而後雙擊控件,IDE就自動幫你註冊好了一個用戶點擊事件。卻不知,IDE是在xx.design.cs中經過代碼替你註冊好的。因此既然剛開始學,必定要了解清楚它的原理。webpack
<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; }
在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); }
只要是遊戲少不了作碰撞檢測,若是在CC中開啓了物理引擎還好,直接跟星星和主角添加一個剛體就行了,不過咱們沒開啓,那就本身來了。不過碰撞檢測無非就是判斷兩個區域有沒有重疊地方,簡單判斷就上下左右,左上右上左下右下八個點。不過我這裏偷了個懶,直接判斷星星和主角間向量的距離。
//author:herbert qq:464884492 ... let distance = this.node.position.sub(this.tank.getPosition()).mag(); if (distance < (this.tank.width / 2 - 5)) { console.log("接住了"); } ...
遊戲嘛,總不能一成不變那多沒意思,因此隨着時間的推移咱們的調整點難度。我這個遊戲難度無非就一下兩個方面
//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(); ...
遊戲嘛,也不能一直玩下去。否則多沒挑戰。自從調整遊戲難度後個人最高分重來就沒有超過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; } } ...
作技術嘛,大多都是 Talk is cheap,Show me your code.作點總結吧