通過「解救人質」小遊戲教你學會碰撞檢測
遊戲開發中,碰撞檢測無處不在,今天就通過一個簡單的小遊戲教你學會如何在 Cocos Creator 中進行碰撞檢測。配合官方文件學習效果更加(官方文件傳送門:https://docs.cocos.com/creator/manual/zh/physics/collision/),關注公眾號「遊戲開發小白變怪獸」後臺回覆「解救人質」獲取美術資源及原始碼。
遊戲玩法:
通過控制手槍位置,鬆手發射子彈擊中躲在人質後面的歹徒順利解救人質,小心不要打中人質哦!
實現邏輯:
分別給子彈、人質和歹徒新增碰撞元件,檢測到子彈與歹徒發生碰撞時,營救成功;檢測到子彈與人質發生碰撞時,營救失敗。
步驟詳解:
1.按照圖中節點樹建立節點,分別將對應貼圖拖給對應的節點,並設定節點位置如圖,successLabel 和 failLabel 內容分別為「解救成功!」和「解救失敗!」:
2.給 hostage 節點新增碰撞元件,並設定元件 Tag 屬性和 Size 屬性:
當一個節點上有多個碰撞元件時,在發生碰撞後,可以使用 Tag 來判斷是節點上的哪個碰撞元件被碰撞了。此時,碰撞元件大小和節點大小一致,同樣的步驟將 enemy 和 bullet 節點新增好碰撞元件。
3.接下來在專案設定面板裡新增分組:hostage、enemy 和 bullet(注:分組新增後是不可以刪除的,不過你可以任意修改分組的名字),並勾選hostage 和 bullet、enemy 和 bullet:
4.在專案設定新增好分組後,分別在 hostage、enemy 和 bullet 屬性中的 Group 設定對應分組:
5.接下來新建 Bullet.js 指令碼掛載到 bullet 節點下,編輯指令碼如下,主要在 update 方法內實現了子彈的移動和銷燬,以及碰撞回撥函式(注:使用碰撞檢測之前一定要獲取碰撞檢測,且碰撞回撥函式名稱固定,無需註冊!):
1 // Bullet.js 2 3 cc.Class({ 4 extends: cc.Component, 5 6 properties: { 7 mSpeed: 300, 8 }, 9 10 // LIFE-CYCLE CALLBACKS: 11 12 // onLoad () {}, 13 14 start() { 15 var manager = cc.director.getCollisionManager(); // 獲取碰撞檢測系統 16 manager.enabled = true; 17 }, 18 19 update(dt) { // 設定子彈移動,當超出螢幕範圍未發生碰撞時自動銷燬 20 this.node.y += this.mSpeed * dt; 21 22 if (this.node.y > 580) { 23 console.log('超出螢幕範圍,子彈銷燬!'); 24 25 this.node.destroy(); 26 } 27 }, 28 29 /** 30 * 當碰撞產生的時候呼叫 31 * @param {Collider} other 產生碰撞的另一個碰撞元件 32 * @param {Collider} self 產生碰撞的自身的碰撞元件 33 */ 34 onCollisionEnter: function (other, self) { 35 console.log('on collision enter'); 36 37 if (other.tag == 1) { // 子彈碰到人質時,解救失敗! 38 console.log('解救人質失敗!'); 39 40 var failLabel = this.node.parent.getChildByName('failLabel'); 41 failLabel.active = true; 42 43 this.node.destroy(); 44 45 } else if (other.tag == 2) { // 子彈碰到敵人時,解救成功! 46 console.log('解救人質成功!'); 47 48 var successLabel = this.node.parent.getChildByName('successLabel'); 49 successLabel.active = true; 50 51 this.node.destroy(); 52 } 53 }, 54 55 /** 56 * 當碰撞產生後,碰撞結束前的情況下,每次計算碰撞結果後呼叫 57 * @param {Collider} other 產生碰撞的另一個碰撞元件 58 * @param {Collider} self 產生碰撞的自身的碰撞元件 59 */ 60 onCollisionStay: function (other, self) { 61 console.log('on collision stay'); 62 }, 63 64 /** 65 * 當碰撞結束後呼叫 66 * @param {Collider} other 產生碰撞的另一個碰撞元件 67 * @param {Collider} self 產生碰撞的自身的碰撞元件 68 */ 69 onCollisionExit: function (other, self) { 70 console.log('on collision exit'); 71 } 72 });
編寫完指令碼後,將 bullet 節點儲存為預製件待用。
6.然後編寫 gun 節點的控制邏輯指令碼 ControlGun.js:
1 // ControlGun.js 2 3 cc.Class({ 4 extends: cc.Component, 5 6 properties: { 7 mBullet: cc.Prefab 8 }, 9 10 // LIFE-CYCLE CALLBACKS: 11 12 onLoad() { }, 13 14 start() { 15 this.node.on('touchstart', this.onTouchStart, this); 16 this.node.on('touchmove', this.onTouchMove, this); 17 this.node.on('touchend', this.ontouchEnd, this); 18 }, 19 20 // update (dt) {}, 21 22 onTouchStart(event) { // 每次點選之前,都要把結果關掉 23 var successLabel = this.node.parent.getChildByName('successLabel'); 24 successLabel.active = false; 25 26 var failLabel = this.node.parent.getChildByName('failLabel'); 27 failLabel.active = false; 28 }, 29 30 onTouchMove(event) { // 控制節點在螢幕範圍內左右移動 31 let rangePos = event.getDelta(); 32 33 this.node.x += rangePos.x; 34 35 let minX = -this.node.parent.width / 2 + this.node.width / 2; 36 let maxX = Math.abs(minX); 37 38 let currentPos = this.node.getPosition(); 39 40 if (currentPos.x < minX) { 41 currentPos.x = minX; 42 } else if (currentPos.x > maxX) { 43 currentPos.x = maxX; 44 } 45 46 this.node.setPosition(currentPos); 47 }, 48 49 ontouchEnd(event) { // 鬆開時發射子彈 50 console.log('發射子彈'); 51 52 let bullet = cc.instantiate(this.mBullet); 53 bullet.parent = this.node.parent; 54 55 let currentPos = this.node.getPosition(); 56 57 bullet.parent = this.node.parent; 58 bullet.setPosition(currentPos); 59 } 60 });
7.最後編寫 enemy 的移動指令碼:
1 // ControlEnemy.js 2 3 cc.Class({ 4 extends: cc.Component, 5 6 properties: { 7 mSpeed: 300 8 }, 9 10 // LIFE-CYCLE CALLBACKS: 11 12 // onLoad () {}, 13 14 start() { 15 this.minX = -this.node.parent.width / 2 + this.node.width / 2; 16 this.maxX = Math.abs(this.minX); 17 }, 18 19 update(dt) { 20 let currentPos = this.node.getPosition(); 21 22 if (currentPos.x < this.minX) { 23 this.mSpeed = Math.abs(this.mSpeed); 24 } else if (currentPos.x > this.maxX) { 25 this.mSpeed = -Math.abs(this.mSpeed); 26 } 27 28 this.node.x += this.mSpeed * dt; 29 } 30 });
8.編寫完所有的指令碼之後,就可以預覽遊戲了,快來試試你能不能成功的就下人質吧!
最後:
通過這個簡單的小遊戲有沒有學會碰撞檢測的使用呢?快來下載美術資源嘗試一下吧!關注公眾號「遊戲開發小白變怪獸」後臺回覆「解救人質」獲取美術資源及原始碼,更有更多優質內容等你發現!
推薦閱讀:
一文教你實現「飛機大戰」裡戰機的控制邏輯
自定義虛擬搖桿元件讓你一勞永逸
Cocos Creator 如何進行斷點除錯?
如何部署 H5 遊戲到雲伺服器?
我是「Super於」,立志做一個每天都有正反饋的人!