转自: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;
    },221);"> 
  
  • 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。

    逻辑清楚的代码是不需要过多讲解的,对吧,对的。

    源码在此:https://github.com/potato47/brick-breaker-master

    游戏试玩:http://119.29.40.244/brick-breaker/

    关爱失踪人口:

    《毕业前的程序员》系列正在更新。。。如果你不关注,你就会错过一个天才的成长历程。。。233

    【Cocos Creator实战教程(8)】——打砖块(物理引擎)的更多相关文章

    1. ios – 仅用于碰撞检测,Chipmunk或Box2d是更好的工具吗?

      对于基于Cocos2d的项目,我只想使用物理工具包进行碰撞检测.使用Chipmunk或Box2d有什么优缺点?解决方法我们在谈论什么样的碰撞?根据什么使你更容易使用你的决定而不是一个任意的,未定义的,高度主观的关于一个物理引擎是否比另一个更好的想法,因为技术差异是微不足道的,你只能评估他们对如果你们都知道你自己的游戏设计和物理引擎内部算法,你的游戏设计真的很好.

    2. Swift中的UIKit重力学

      实例化UIDynamicAnimator时,它的构造函数需要传入一个referenceView参数,用于告知它要跟踪并制定坐标的View。collision.translatesReferenceBoundsIntoBoundary=true//为碰撞效果中添加一个隐形的边界。UITouchsnap=UISnapBehavioranimator.addBehavior}//自定义行为:UIDynamcItemBehaviorletitemBehavIoUr=UIDynamicItemBehaviorite

    3. Swift中的UIKit动力学

      添加重力行为在ViewController.swift文件中添加两个属性://UIKit物理引擎varanimator:UIDynamicAnimator!在UIKit的重力世界中,计算重力加速度的公式是一样的,但是单位有所不同。从上面代码我可以注意到collision.translatesReferenceBoundsIntoBoundary=true;这行代码,它的意思是将UIDynamicAnimator引用的View的边界作为碰撞行为的触发边界,这样就不用我们再去设置边界的坐标了,非常好用。

    4. 怎样在CocosCreator中使用物理引擎关节

      这篇文章主要介绍了怎样在CocosCreator中使用物理引擎关节,对物理引擎感兴趣的同学,着重要看一下

    5. Cocos2D OR libgdx for Android游戏开发

      本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

    6. cocos2d-x 物理引擎

      上面的例子代码流程:PhysicsBody对象创建Sprite对象创建PhysicsBody对象以组件的形式被添加到Sprite对象创建监听器以响应onContactBegin()事件刚体刚体描述了抽象物体的物理属性,包括:质量、位置、旋转角度、速度和阻尼。Cocos2d-x用PhysicsBody对象表示刚体。PhysicsWorld物理世界PhysicsWorld与场景进行了深入的整合,只需要调用Scene对象的initWithPhysics()方法,就可以创建一个包含物理世界的场景,注意在初始化的时

    7. 【Cocos Creator实战教程(8)】——打砖块(物理引擎)

      新建一个工程,取名叫做brick-breaker,brick是什么意思呢,就是砖块的意思,每次给工程起名字,我都能学会一个新单词。为什么不选kinematic呢?另外要设置wall,ground,paddle,brick的type为staticbrick的tag为1,ground的tag为2,paddle的tag为3,wall的tag位4下面来看脚本BrickLayout.js12345678910111213141516171819202122自己写了一个动态添加砖块的布局脚本,传入需要添加的砖块数量就

    8. Cocos2d-x之初级物理引擎

      一切故事发生的背景同济大学软件学院每个学期会要求学生独立或者组队完成一个大项目,于是2016年的大项目是用cocos2d-x这款引擎制作一个自己的游戏。之前写了一篇cocos2d-x关于键盘按住事件的教程,不足之处还请大家多多指出。物理引擎的基础两种物理引擎根据官方文档的介绍,目前有两大重要的物理引擎,Box2D和Chipmunk,并且cocos2d-x已经集成了它们,在3.x版本中可基于Chipmunk的核心API的物理引擎使用。一句话:cocos2d-x3.x版本中使用Chipmunk物理引擎更加方便

    9. 关于cocos2d中物理引擎碰撞掩码的设置

      当物理引擎检测到两个Body发送的碰撞信息后,会调用相应的时间方法来通知系统,比如两个Body已经发生碰撞,两个Body已经分离。同时导弹、飞船以及七边形只要碰撞都可以调用onContactBegin的方法注:会遇到使用默认值无法调用onContactBegin的方法,解决办法是对每个body重新设置三个掩码就能解决

    10. cocos2dx physics物理引擎 碰撞的三个掩码含义

      产生碰撞和发生碰撞响应是不同的概念。如人物奔跑时碰到了金币,这里如果没有碰撞处理函数,且把什么掩码都设为1,那么你会发现角色碰到金币时角色不再向前移动了,金币成了一个挡在路上的砖块,这时已经发生了碰撞了,但如果你把人的类别设为1,金币的类别设为0,而两者的CollisionBitmask都为1,则金币和人的CategoryBitmask和CollisionBitmask掩码相与为0,则不会发生碰撞,在游戏里效果就是人奔跑时穿过了金币,金币就像空气一样,这就是没有发生碰撞的含义。

    随机推荐

    1. 【cocos2d-x 3.x 学习笔记】对象内存管理

      Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

    2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

      由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

    3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

      在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

    4. cocos2dx3.x 新手打包APK注意事项!

      这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

    5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

      如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

    6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

      needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

    7. 02 Cocos2D-x引擎win7环境搭建及创建项目

      官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

    8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

      一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

    9. 03 Helloworld

      程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

    10. MenuItemImage*图标菜单创建注意事项

      学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

    返回
    顶部