CreatorPrimer|物理小游戏(物理引擎管理器)

前面两篇我们介绍了物理投篮小游戏的界面布局物理组件的基本使用方法,从今天开始进入编程篇的内容。难度在逐渐加深,为了不给大家造成阅读负担,程序篇会分成多次来讲,每篇教程尽量简单,就算没有编程基础,跟着源码、注释、讲解、视频,相信也能帮助大家快速上手Cocos Creator物理引擎。

Demo演示,点击下面连接打开

视频地址:https://v.qq.com/x/page/p0713nsrnr1.html
源码地址:https://github.com/ShawnZhang2015/CreatorPrimer/tree/physics

1. 通用物理组件

在开始本篇时,Shawn已经将源码又重构了几次,重点依然是组件化思维:程序员以游戏设计师为服务对象,向他们提供易用的组件脚本,生产游戏内容。先来看一下Shawn提供5个物理组件脚本:

通用物理组件

使用这5个组件脚本,可以构建非常有趣的物理小游戏,下面我们对这5个自定义组件做一个简单介绍:

  1. PhysicsManager: 物理引擎管理器,使用它无需编程即可开启\关闭物理引擎,并提供刚体的着色调试开关。
物理引擎管理器.png
  1. PhysicsVelocity: 物理速度控制组件,提供了一个force函数方便使用cc.Button在编辑器中调用,为刚体施加外力。
  2. PhysicsColliderNotification: 物理碰撞通知组件,使用它可以让非物理组件或脚本能收到物理碰撞事件。
  3. ScoreNotificationHandle:得分通知处理组件,该组件监听PhysicsColliderNotification发出的事件通知,更新Label文本。
  4. ScoreVerifyNotificationHandle:带验证功能的得分通知处理组件,它可以监听PhysicsColliderNotification发出的事件,检查刚体碰撞过程中的方向(从上向下、从上向上、从左向右、从右向左),请看下图:
增强得分通知处理组件

我们的Demo就是由系统物理组件与这5个自定义这几个组件构成,其它没有任何代码,建议大家下载源码把玩把玩!

2. 物理引擎管理器

PhysicsManager组件是本篇教程的重点,我们看一下它的编辑器属性:

物理引擎管理器

此组件用于开启Cocos Creator的物理引擎,如果没有开启物理引擎,引擎提供的物理组件是不会生效的。通常开启物理引擎需要编写代码,这对非程序人员来说是一个不小的挑战,现在好了只要将此PhysicsManager组件放入你的工程,挂载到某个节点就好了。同时它还可以,设置物理刚体着色调试开关,使用非常方便,就算你不打算学习编程,也可以直接使用。

属性设计

接下来我们看看PhysicsManager组件的properties属性接口的编码:

/**
 * PhysicsManager.js
 */ 
cc.Class({
    extends: cc.Component,

    properties: {
       active: { 
           default: true,
           tooltip: '是否启用物理引擎',
       },
       aabb:{
           default: true,
           tooltip: '是否显示包围盒',
       },
       pair: {
           default: true,
           tooltip: '我也不知道是什么用:-('
       },
       centerOfMass: { 
           default: true,
           tooltip: '是否显示中心点'
       },
       joint: { 
           default: true,
           tooltip: '是否显示关节连接线'
       },
       shape: {
           default: true,
           tooltip: '是否填充形状'
       },
       mouseJoint: {
           default: false,
           tooltip: '是否开启鼠标关节,可以拖动动态刚体'
       }
    },
    ...
}

从上面代码可以看到,为每个组件属性的tooltip设置了文本,方便设计人员从编辑器上了解组件属性的功能含义:

tooltip

PhysicsManager组件属性完全不依赖外部节点、组件、资源,是一个非常干净的组件,符合我们功能型通用组件的设计标准(哈哈,自我吹嘘!)。

开启物理引擎

定义好接口,我们看如何实现物理引擎的开启和关闭,以及active属性的使用,请看下面代码:

/**
 * PhysicsManager.js
 */ 
cc.Class({
    extends: cc.Component,

    properties: {
        ...
    },

    /**
    *组件激活
    **/
    onEnable() {
        //从导演对象上获取引擎物理管理器 
        let physicsManager = cc.director.getPhysicsManager();
        //如果物理引擎重复开启,给出一个警告提示
        if (physicsManager.enabled && this.active) {
            cc.warn('The physical system is enabled!');
        }

        //开启或关闭物理系统
        physicsManager.enabled = this.active;
        //如果是关闭物理引擎,退出
        if (!this.active) {
            return;
        }
        
        //调试选项
        ...
    },

    /**
    *组件禁用
    **/
    onDisable() {
        //组件失效时关闭物理引擎
        cc.director.getPhysicsManager().enabled = false;
    }
});

上面代码中核心关键是在onEnable事件中通过cc.director.getPhysicsManager()获取PhysicsManager对象,控制物理引擎的开启和关闭。注意,物理引擎在整个游戏中只需要开启一次就可以了,如果你挂载了多次PhysicsManager组件并重复开启物理引擎,运行时会收到一个警告哦!

物理调试开关

6个物理调试开关

PhysicsManager组件提供了6个调试开关,方便观察刚体的物理表现,在开发过程中特别有用。我们再看一下实现这些功能的代码:

/**
 * PhysicsManager.js
 */ 
cc.Class({
    extends: cc.Component,

    properties: {
       ....
    },

    onEnable() {
        ....
        //设置调试标志
        let DrawBits = cc.PhysicsManager.DrawBits;
        physicsManager.debugDrawFlags = 
            (this.aabb && DrawBits.e_aabbBit) |
            (this.pair && DrawBits.e_pairBit) |
            (this.centerOfMass && DrawBits.e_centerOfMassBit) |
            (this.joint && DrawBits.e_jointBit) |
            (this.shape && DrawBits.e_shapeBit);
        ...  
    },
   ...
});

cc.PhysicsManager.DrawBits是引擎定义的一个枚举类型,通过设置physicsManager对象的debugDrawFlags属性来开启绘制刚体调试开关,方便看到刚体外形是否与节点渲染出的外形相匹配。请看下图,你就能明白这些刚体调试开关的作用了:

DrawBits部分调试开关说明

其中joint开关需要在Joint类型的物理组件上才能看到,当你开启了Mouse Joint属性时,快速拖动动态刚体也能看到一关节连接线。

物理调试开关中还有一个e_pairBit开关,Shawn也没观察出它有什么作用,如果你知道希望能告诉我,非常感谢!

动态刚体自由拖拽

MouseJoint是物理引擎关节组件中的一个,使用MouseJoint组件可以方便在开发中任意拖拽刚体,在开发期间方便测试,我们看一下具体代码:

/**
 * 物理引擎管理组件,开启各种调试
 */
cc.Class({
    extends: cc.Component,
    properties: {
       ...
       mouseJoint: {
           default: false,
           tooltip: '是否开启鼠标关节,可以拖动动态刚体'
       }
    },

    onEnable() {
        ...
        this._setMouseJoint();    
    },

    _setMouseJoint() {
        //鼠标可拖刚体
        if(this.mouseJoint && this.active) {
            let node = this.node;
            //获取节点上的刚体组件
            let rigidBody = node.getComponent(cc.RigidBody);
            //不存在添加一个
            if (!rigidBody) {
                rigidBody = node.addComponent(cc.RigidBody);
            }
            //获取组件上的鼠标关节组件
            let mouseJoint = node.getComponent(cc.MouseJoint);
            //不存在添加一个
            if (!mouseJoint) {
                mouseJoint = node.addComponent(cc.MouseJoint);
            }
            //设置为静态刚体
            rigidBody.type = cc.RigidBodyType.Static;
            //设置鼠标范围
            mouseJoint.mouseRegion = node;
        }
    },
    ...
});

_setMouseJoint函数是动态为当前节点添加物理刚体(cc.RigidBody)和鼠标关节(cc.MouseJoint)。同时设置当前节点为静态刚体,设置鼠标控制范围为当前节点范围。因此PhysicsManager组件适合放在根节点上或顶层父类节点上,管理它下面的子孙节点。

上面讲了这么多,使用时只需要将PhysicsManager组件挂载到Canvas节点上,设置需要的调试开关即可,运行在非预览环境时,调试开关不会起作用。

3. 小结

本篇介绍了物理投篮Demo游戏中使用到的自定义组件,重点讲解了PhysicsManager组件的实现细节,有了它任何人都可以启动Cocos Creator的物理引擎,你可以把它放到自己的项目中使用,可以根据自己的需求进行修改调整。

最后预告下次的教程内容,继续我们的物理小游戏程序篇-物理碰撞监听,同时还会介绍Cocos Creator的事件机制的运用:组件间通信,敬请期待!


如果觉得公众号上的文章对你或你的朋友有所帮助,请记得分享给大家,愿我们一起成长!

奎特尔星球
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容