1. 程式人生 > >【Cocos Creator實戰教程(8)】——打磚塊(物理引擎)

【Cocos Creator實戰教程(8)】——打磚塊(物理引擎)

轉自:http://blog.csdn.net/potato47/article/details/73197021

失蹤人口迴歸

這裡寫圖片描述 
本篇教程要基於Cocos Creator1.5的物理引擎,編寫一個簡單的打磚塊遊戲,儘可能多講一點,但現在已經快11點了,我12點要睡覺啊,好像又講不了多少,這個世界啊,本來就是一個矛盾體。

這裡寫圖片描述

新建一個工程,取名叫做brick-breaker,brick是什麼意思呢,就是磚塊的意思,每次給工程起名字,我都能學會一個新單詞。

目錄結構如下:

這裡寫圖片描述

game場景,設定Canvas 
這裡寫圖片描述

先搭一個遊戲背景 
這裡寫圖片描述 
(因為我已經做完了,我就不從頭做一遍了,所以暫時用不到的節點我就把active關掉)

再建一個物理層,用來裝遊戲裡的帶有物理屬性的東西,設定錨點為左下角 
這裡寫圖片描述

又到了學單詞的時間,請拿出你們的小本本:

wall:牆//小球碰到就會反彈的那種牆 
ground:地面//球碰到地面,這局遊戲就結束了 
brick_layout:磚塊佈局//這個單詞我們之前講過了就不講了 
ball:球//就是球 
paddle:槳//這裡特指那個可以控制移動的白色長方形

這個wall肯定是要有碰撞屬性的,在屬性面板,新增一個物理元件 
這裡寫圖片描述

因為我們的牆有上,左,右三面,所以再新增三個碰撞元件(一個節點可以有多個碰撞元件)。 
這裡寫圖片描述

編輯一下 
這裡寫圖片描述

地面同理,小球同理,托盤同理 
這裡寫圖片描述 
(這裡把地面和牆分開是為了後面牆和地面可能有不同的邏輯)

現在已經編輯了幾個物理節點的碰撞包圍盒,但還沒有編輯他們的物理屬性(cc.RigidBody)

先從小球開始,點選ball節點,在屬性檢查器可以看到

這裡寫圖片描述

把第一個引數勾選,代表啟用碰撞回撥,可以在腳本里寫回調函式

Bullet:高速運動的物體開啟,避免穿透,這裡不用勾選

type選擇Dynamic,

static:不會受到力的影響,不會受到速度影響,指的是物理引擎,我們依然可以通過移動節點來改變位置 
kinematic:不受力的影響,會受到速度影響 
dynamic:受力影響,受速度影響 
animated:據說和動畫結合使用,我還沒弄懂。。。

為什麼不選kinematic呢?留個作業。

Gravity Scale設定為0(標準是1,數值代表比例),也就是沒有重力。

設定線速度(1000,1000)

這裡寫圖片描述 
在下面的碰撞元件裡,設定Friction (摩擦係數)等於0(沒有摩擦力),Restitution(彈性係數)等於1(沒有動量損耗)

因為小球是我們的主角,左右的碰撞都是對球來說的,所以碰撞屬性都在小球這一方設定就可以了。

另外要設定wall,ground,paddle,brick的type為static 
brick的tag為1, 
ground的tag為2, 
paddle的tag為3, 
wall的tag位4

下面來看指令碼

BrickLayout.js

cc.Class({
    extends: cc.Component,

    properties: {
        padding: 0,
        spacing: 0,
        cols: 0,
        brickPrefab: cc.Prefab,
        bricksNumber: 0,
    },

    init(bricksNumber) {
        this.node.removeAllChildren();
        this.bricksNumber = bricksNumber;
        for (let i = 0; i < this.bricksNumber; i++) {
            let brickNode = cc.instantiate(this.brickPrefab);
            brickNode.parent = this.node;
            brickNode.x = this.padding + (i % this.cols) * (brickNode.width + this.spacing) + brickNode.width / 2;
            brickNode.y = -this.padding - Math.floor(i / this.cols) * (brickNode.height + this.spacing) - brickNode.height / 2;
        }
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

自己寫了一個動態新增磚塊的佈局指令碼,傳入需要新增的磚塊數量就可以動態加入的佈局節點中。

BrickPrefab長這樣,我就預設你會做prefab了 
這裡寫圖片描述

OverPanel.js

cc.Class({
    extends: cc.Component,

    properties: {
        resultLabel:cc.Label,
        scoreLabel:cc.Label,
    },

    // use this for initialization
    onLoad: function () {

    },

    init(gameCtl){
        this.gameCtl = gameCtl;
        this.node.active = false;
    },

    show(score,isWin){
        this.node.active = true;
        if(isWin){
            this.resultLabel.string = 'YOU WIN!';
        }else{
            this.resultLabel.string = 'YOU LOSE!';
        }
        this.scoreLabel.string = score+'';
    },

    onBtnRestart(){
        this.gameCtl.startGame();
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

結束介面 
這裡寫圖片描述

Paddle.js

cc.Class({
    extends: cc.Component,

    onLoad: function () {
        this.node.parent.on("touchmove", (event) => {
            //將世界座標轉化為本地座標
            let touchPoint = this.node.parent.convertToNodeSpace(event.getLocation());
            this.node.x = touchPoint.x;
        });
    },

    init(){
        this.node.x = 360;
    }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

托盤隨著手指移動

Ball.js

cc.Class({
    extends: cc.Component,

    properties: {

    },

    init(gameCtl) {
        this.gameCtl = gameCtl;
        this.node.position = cc.v2(360,270);//初始化位置
        this.getComponent(cc.RigidBody).linearVelocity = cc.v2(800,800);//初始化速度
    },

    onBeginContact(contact, self, other) {
        switch (other.tag) {
            case 1://球碰到磚塊
                this.gameCtl.onBallContactBrick(self.node, other.node);
                break;
            case 2://球碰到地面
                this.gameCtl.onBallContactGround(self.node, other.node);
                break;
            case 3://球碰到托盤
                this.gameCtl.onBallContactPaddle(self.node, other.node);
                break;
            case 4://球碰到牆
                this.gameCtl.onBallContactWall(self.node, other.node);
                break;
        }
    },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

球碰到其他物體,讓gameCtl處理

GameCtl.js

const GameModel = require('GameModel');
cc.Class({
    extends: cc.Component,

    properties: {
        gameView: require('GameView'),
        ball: require('Ball'),
        paddle: require('Paddle'),
        brickLayout: require('BrickLayout'),
        overPanel: require('OverPanel'),
    },

    // use this for initialization
    onLoad: function () {
        //安卓返回鍵退出
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, (event) => {
            if (event.keyCode === cc.KEY.back) {
                cc.director.end();
            }
        });
        this.physicsManager = cc.director.getPhysicsManager();
        this.gameModel = new GameModel();
        this.startGame();

    },

    //this.physicsManager.debugDrawFlags =0;
    // cc.PhysicsManager.DrawBits.e_aabbBit |
    // cc.PhysicsManager.DrawBits.e_pairBit |
    // cc.PhysicsManager.DrawBits.e_centerOfMassBit |
    // cc.PhysicsManager.DrawBits.e_jointBit |
    // cc.PhysicsManager.DrawBits.e_shapeBit
    // ; 

    init() {
        this.physicsManager.enabled = true;
        this.gameModel.init();

        this.gameView.init(this);
        this.ball.init(this);
        this.paddle.init();
        this.brickLayout.init(this.gameModel.bricksNumber);
        this.overPanel.init(this);

    },

    startGame() {
        this.init();
    },

    pauseGame() {
        this.physicsManager.enabled = false;
    },

    resumeGame() {
        this.physicsManager.enabled = true;
    },

    stopGame() {
        this.physicsManager.enabled = false;
        this.overPanel.show(this.gameModel.score, this.gameModel.bricksNumber === 0);
    },

    onBallContactBrick(ballNode, brickNode) {
        brickNode.parent = null;
        this.gameModel.addScore(1);
        this.gameModel.minusBrick(1);
        this.gameView.updateScore(this.gameModel.score);
        if (this.gameModel.bricksNumber <= 0) {
            this.stopGame();
        }
    },

    onBallContactGround(ballNode, groundNode) {
        this.stopGame();
    },

    onBallContactPaddle(ballNode, paddleNode) {

    },

    onBallContactWall(ballNode, brickNode) {

    },

    onDestroy() {
        this.physicsManager.enabled = false;
    }

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

GameCtl掛在Canvas上,保證第一個執行,將對應的元件拖入 
這裡寫圖片描述

GameView.js

cc.Class({
    extends: cc.Component,

    properties: {
        scoreLabel:cc.Label,
    },

    init(gameCtl){
        this.gameCtl = gameCtl;
        this.scoreLabel.string = '0';
    },

    updateScore(score){
        this.scoreLabel.string = score;
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

GameModel.js

cc.Class({
    extends: cc.Component,

    properties: {
        score:0,
        bricksNumber:0,
    },

    init(){
        this.score = 0;
        this.bricksNumber = 50;
    },

    addScore(score){
        this.score += score;
    },

    minusBrick(n){
        this.bricksNumber -= n;
    },

});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

嘗試著寫的mvc,並不規範,簡單的理解就是,model和view分離,溝通都通過control。

邏輯清楚的程式碼是不需要過多講解的,對吧,對的。

關愛失蹤人口:

這裡寫圖片描述

《畢業前的程式設計師》系列正在更新。。。如果你不關注,你就會錯過一個天才的成長曆程。。。233


相關推薦

Cocos Creator實戰教程(8)——磚塊(物理引擎)

轉自:http://blog.csdn.net/potato47/article/details/73197021失蹤人口迴歸 本篇教程要基於Cocos Creator1.5的物理引擎,編寫一個簡單的打磚塊遊戲,儘可能多講一點,但現在已經快11點了,我12點要睡覺啊,好像又講

Cocos Creator 實戰教程(2)——天天酷跑(動畫、動作相關)

轉載請保留原文連結,個人公眾號:xinshouit(新手程式設計師),歡迎關注 準備工作 把背景圖拉長,很長很長的那種。。。。一會我們要讓它滑動起來 背景動畫 為背景節點

Cocos Creator實戰教程(6)——get47(數字消除)

先來看一下游戲效果 遊戲玩法: 遊戲操作仿的是天天愛消除,點選一個方塊向相鄰的方塊滑動就會交換兩個方塊 當沒有可移動的方塊時,可以點選下面的update按鈕 橫向相連的方塊數字之和會增加分數,縱向相連的方塊數字之和會減少分數 最終目的就是get47

Cocos Creator 基礎教程(其他)—— 利用 Github Pages 釋出遊戲

首先你要有一個做好的遊戲 點選選單欄下的 專案-》構建釋出 釋出平臺選擇Web Desktop(適合電腦端訪問) 點選構建後再點選執行,根據執行效果 調整解析度,儘量讓整個遊戲可以完整的顯示在一頁。 像這樣 釋出平臺再改成 Web Mobile

Cocos Creator教程——蝸牛過橋(

初學Cocos Creator,做了個小遊戲與大家分享線上體驗:(IE10可行,360瀏覽器可能會有問題,其它瀏覽器自測)1.     建立以下資料夾,新建一個場景game_scene,並將圖片、字型資源匯入。2.     設定Canvas大小為720x1280,新建單色節點

Cocos creator檔案資料讀寫,使用者資料儲存

【首先吐槽一下:對於Cocos creator,一方面自己對相關知識不太熟悉,但是另一方面cocos creator 的api文件也太不完善了,想實現對Json檔案進行資料讀寫的功能花了我一天時間。還

Cocos creator繪圖系統:Graphics元件之動態改變生成影象的透明度

在Cocos creator 中,要想在使用Graphics元件繪製圖像的過程中改變影象的透明度有兩種方法: 1.在編輯器中Graphics元件的fillColor屬性中設定; 2.通過程式碼動態設定。 drawLine:function(){ var

cocos creatorcocos creator的官網demo小遊戲--小星星

       在官網的教程基礎之上,修改了官網遺漏下的bug。雖然可以下載cocos.com官網的原始碼,直接使用,更改BUG,但對於自己一個剛接觸cocos開發新手,通過自己的努力,去發現官網的

v2.x OGE教程 12 關卡編輯器幫助文檔

spa 集成 delet exc 取消 map attribute exceptio nal 【v2.x OGE教程 12】 關卡編輯器幫助文檔 一、簡單介紹 關卡編輯器用於遊戲關卡界面元素的可視化編輯,包含元素的位置、尺寸以及其他自己定義屬性。通過解析生成的

Zigbee技術入門教程-01Zigbee無線組網技術入門的學習路線

自組織 問題 作者 項目 建築 企業 color 基本概念 基礎 【Zigbee技術入門教程-01】Zigbee無線組網技術入門的學習路線 廣東職業技術學院 歐浩源 一、引言 在物聯網技術應用的知識體系中,Zigbee無線組網技術是非常重要的一環,也是大家感覺比較難

3470. NOIP2013模擬聯考8最短路(path) (Standard IO)

sizeof max code and RoCE sea NPU write 所有 Description 給定一個n個點m條邊的有向圖,有k個標記點,要求從規定的起點按任意順序經過所有標記點到達規定的終點,問最短的距離是多少。 Input 第一行5個整數n、m

Python爬蟲實戰專案一爬取大眾點評團購詳情及團購評論

1 專案簡介 從大眾點評網收集北京市所有美髮、健身類目的團購詳情以及團購評論,儲存為本地txt檔案。 技術:Requests+BeautifulSoup 以美髮為例:http://t.dianping.com/list/beijing?q=美髮 爬取內容包括: 【團購詳情】團購名稱、原

MySQLl優化附帶優化視訊教程全套

可以從以下幾個方面對MySQL進行優化,  效果: SQL和索引 > 資料庫表結構 > 系統配置 > 硬體  但成本從低到高。 1.SQL和索引優化 1.1SQL 1.1.1優化SQL語句的一般步驟: ①通過show status 命令瞭解各種S

C++深度剖析教程40使用數值型模板技術計算1+2+3+...+N的值

上一篇文章學習了數值型模板技術,並利用相關技術,實現了C++的陣列類模板。點選文章檢視上一篇文章:點選連結檢視 本篇文章,繼續利用模板技術來解決一個問題。 如果想求1+2+3+…+N的結果,有很多種方法。可以迴圈遍歷,可以直接使用公式求解。但是他們都不是最快的方法,我們今天使用模

C++深度剖析教程39實現C++陣列類模板

上一篇文章在那個學習了多引數類模板與特化的分析:點選連結檢視上一篇文章:類模板深度剖析 本篇文章學習記錄: 數值型模板引數 實現C++陣列類模板 1、模板中的數值型引數 模板引數可以是數值型引數。也就是非型別引數。如下圖所示: 我們可以像上面定義

Cocos Creator實戰-使用粒子資源實現螢幕點選效果

效果圖 涉及到的知識點 粒子特效製作 觸控事件監聽以及座標轉化 預製資源製作 物件池的使用 動態顯示特效 製作粒子特效 推薦免費線上工具Particle2dx,這裡就使用模板中已有的Click特效circle1 選擇粒子特效模板

C++學習詳細教程目錄

學習交流加 個人qq: 1126137994 個人微信: liu1126137994 學習交流資源分享qq群: 962535112 本文記錄之前寫的【C++深度剖析學習記錄】專欄裡的C++文章的一個總的目錄。這樣

SpringBoot教程:SpringBoot+FreeMark模板引擎

SpringBoot+FreeMark模板引擎 最近專案有點忙,一直沒有時間過來發部落格。。。趁現在週末,趕快寫 一. Spring boot 在spring預設基礎上,自動配置添加了以下特性: 1. 包含了ContentNegotiatingViewResol

凸優化長鏈剖分2019冬令營模擬1.8tree

PROMBLEM 給你一棵樹,你需要在樹上選擇恰好 m條點不相交的、長度至少為 k的路徑,使得路徑所覆蓋的點權和儘可能大。求最大點權和。 資料保證有解。 SOLUTION 這是一道綜合的題目,考察凸優化、長鏈剖分、樹形DP、以及關於陣列空間的優化 首先引進凸優

REACT NATIVE 系列教程之一觸控事件的兩種形式與四種TOUCHABLE元件詳解

本文是RN(React Native)系列教程第一篇,當然也要給自己的群做個廣告:  React Native @Himi :126100395  剛建立的群,歡迎一起學習、討論、進步。本文主要講解兩點:1.   PanResponder:觸控事件,用以獲取使用者手指所在螢幕的座標(x,y)或觸發、或滑動、或