1. 程式人生 > >通過「解救人質」小遊戲教你學會碰撞檢測

通過「解救人質」小遊戲教你學會碰撞檢測

遊戲開發中,碰撞檢測無處不在,今天就通過一個簡單的小遊戲教你學會如何在 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於」,立志做一個每天都有正反饋的人!