继续物理小游戏,我们先回顾一下CreatorPrimer仓库中提供的五个组件脚本:

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

  1. PhysicsManager: 物理引擎管理器,使用它无需编程即可开启\关闭物理引擎,并提供刚体的着色调试开关。


2. PhysicsVelocity: 物理速度控制组件,提供了一个force函数方便使用cc.Button在编辑器中调用,为刚体施加外力。
3. PhysicsColliderNotification: 物理碰撞通知组件,使用它可以让非物理组件或脚本能收到物理碰撞事件。
4. ScoreNotificationHandle:得分通知处理组件,该组件监听PhysicsColliderNotification发出的事件通知,更新Label文本。
5. ScoreVerifyNotificationHandle:带验证功能的得分通知处理组件。

我们今天的重点是PhysicsColliderNotification组件的实现。

1. 开启刚体碰撞监听

PhysicsColliderNotification组件功能是监听刚体的碰撞事件,因此它需要依赖刚体组件(RigidBody),同时在运行时自动开启刚体的enabledContactListener属性。

cc.Class({//依赖刚体组件editor: CC_EDITOR && {requireComponent: cc.RigidBody,},extends: cc.Component,...start () {//获取刚体组件let rigidBody = this.getComponent(cc.RigidBody);//开启碰撞接触监听rigidBody.enabledContactListener = true;},...
});

最初,有网友在使用Shawn提供的脚本发现时有不灵,发现是因为未开启刚体碰撞监听开关的原故,因此重构时增加了RigidBody的依赖,同时在组件start生命周期函数中开启刚体的enabledContactListener属性,增强使用体验,减少意外发生。

2. 碰撞事件监听

在篮框节点上开启了刚体的碰撞监听,就可以此节点的任意组件代码上编写碰撞监听处理函数了,我们看一下PhysicsColliderNotification碰撞处理函数的实现细节:

/*** 物理碰撞通知组件,要以让非物理组件或脚本能收到物理碰撞事件*/
cc.Class({...extends: cc.Component,properties: {notificationName:'',_p0: null,_p1: null,},/*** 只在两个碰撞体开始接触时被调用一次*/onBeginContact(contact, selfCollider, otherCollider) {cc.log(otherCollider.node.name);this._p0 = otherCollider.node.position;},/*** 只在两个碰撞体结束接触时被调用一次*/onEndContact: function (contact, selfCollider, otherCollider) {this._p1 = otherCollider.node.position;if (this.notificationName) {cc.director.emit(this.notificationName, contact, this._p0, this._p1);}},
});

不知道大家是否还记得,在篮框的碰撞组件中需要设置Sensor属性,它可以使用节点不产生物理碰撞效果,让其它动态刚体可以穿透它,但能监听物理碰撞事件,请看下图:

开启了Sensor属性,通过引擎提供的onBeginContact、onEndContact两个事件监听函数获取篮球刚体的坐标点,识别篮球是从上向下投进的,还是从下向上进框的,从而实现正确记分。

组件中的_p0、_p1变量就是刚体碰撞时的开始点和结束点,在onEndContact事件中通过cc.director.emit将自定义事件、碰撞开始\结束坐标点广播出去。

3. 自定义事件

为什么不直接在刚体节点上直接处理得分呢?要使用cc.director.emit中转一下呢?因为刚体碰撞事件,只能在刚体节点上才能监听到,得分的表现使用的是一个Label组件,如果将代码写在一堆,那这个PhysicsColliderNotification组件做的事情就不只一件,而且太过具体,而且设计多个对象,导致通用性会大大降低。

使用cc.director.emit(‘xxx’)将广播一个事件出去,在任意脚本中使用cc.director.on(‘xxx’)接收事件,不论是更新得分,还是处理游戏的流程、特效等等,会更加的灵活可变,可以让策划或设计师发挥出更多的创作空间。

cc.Director是继承成自cc.EventTarget,cc.director是一个全局变量,因此使用cc.director.emit、cc.director.on实现事件的订阅、发布非常简单,是实现组件间的通信的一种非常方便的方案。

很多人都使用过cc.Node.emit、cc.Node.on来发送和监听事件,唯一不方便的就是你需要先获取发送事件的节点对象。相信还有人怀念Cocos2d-x中的CCNotificationCenter,完全可以使用cc.EventTarget实例化一个全局的EventTarget对象来模拟,实现相同的效果。

通过事件可以方便解耦对象之间的依赖,用一个通俗点的说法就是:“你不要打电话给我,我会打电话给你!”。打电话首先需要电话号码就是事件名称,说这句话的人就是EventTarget对象,听话的人就是递交电话号码(事件名)、接听电话的程序同学。

4. 小结

本篇介绍了PhysicsColliderNotification组件的实现,全是代码和逻辑,不能照顾到非程序员同学,还请包涵。

监听物理碰撞一定要开启刚体的enabledContactListener属性,在onBeginContact、onEndContact事件中获取刚体的位置以识别刚体的运行方向。同时使用cc.director.emit将事件、坐标点广播出去,在关心的地方做对应的逻辑处理。

目前源码已经合并到CreatorPrimer仓库主干,欢迎把玩,提出你的建议!
源码地址:https://github.com/ShawnZhang2015/CreatorPrimer


如果觉得公众号上的文章对您或您身边的朋友有帮助,请分享给他,愿我们一起成长!

CreatorPrimer | 物理小游戏(碰撞事件监听)相关推荐

  1. 微信小游戏的电量监听

    在说小游戏的电量监听事件之前,我想先提一下小程序的电量监听事件. 在微信小程序中,是没有电量监听事件的,因为小程序没有全屏,手机端的电量和wifi等信息一直可以看得到,所以小程序里就没有这样的api了 ...

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

    前面两篇我们介绍了物理投篮小游戏的界面布局.物理组件的基本使用方法,从今天开始进入编程篇的内容.难度在逐渐加深,为了不给大家造成阅读负担,程序篇会分成多次来讲,每篇教程尽量简单,就算没有编程基础,跟着 ...

  3. CreatorPrimer|物理小游戏(物理组件)

    Demo演示视频: 视频地址:https://v.qq.com/x/page/p0713nsrnr1.html 本视频的工程已经上传github,CreatroPrimer仓库physics分支,传送 ...

  4. CreatorPrimer | 物理小游戏(开篇)

    我们前面讲了组件化开发的一些思路以及Cocos Creator的最佳工作流.但真正要做到界面与逻辑分离,开发人员与设计师高效协作,并不是一朝一夕之事,Shawn会在这条道路上继续前行,也希望大家能多多 ...

  5. JS:打字游戏_键盘事件监听

    1. 打字游戏 屏幕随机出现字母或数字 用户按下键盘,屏幕显示回答正确与否 当用户按下ESC时游戏结束 <!DOCTYPE html> <html lang="en&quo ...

  6. Uniapp-微信小程序实现全局事件监听并进行数据埋点

    Uniapp-微信小程序实现全局事件监听并进行数据埋点 零.前言 最近接到需求,领导希望使用微信开放平台上免费的We分析进行数据埋点,但又不希望在现有uniapp开发的微信小程序代码上做侵入式修改,笔 ...

  7. android点击不抬起,Android小坑-OnTouchListener()事件监听长按后抬手MotionEvent.ACTION_MOVE不触发问题...

    场景: 控件使用OnTouchListener()事件监听,正常的流程是,按下瞬间屏幕捕捉到触摸,触发MotionEvent.ACTION_DOWN事件,滑动屏幕会触发MotionEvent.ACTI ...

  8. java中事件监听_Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...

  9. Vue 模板语法 插值操作 绑定属性 计算属性 事件监听 条件判断 循环遍历 阶段案例

    1 插值操作 1.1 Mustache语法 也就是双大括号 {{ }} <div id="app"> <!-- mustche语法中,不仅可以直接写变量,也可以写 ...

最新文章

  1. 合肥工业大学—SQL Server数据库实验一:数据库的创建和删除
  2. linux系统命令学习系列-文件和目录管理
  3. android怎么监听多点触摸_大尺寸触摸屏厂家定制多点触摸框
  4. UNITY录制视屏解决方案 - ShareREC For Unity3D
  5. ICH10R服务器主板是什么芯片,Intel ICH10R 芯片组 RAID配置
  6. [Leetcode][第93题][JAVA][复原IP地址][剪枝][回溯]
  7. MySQL自动备份shell脚本
  8. 服务器性能考察指标,服务器性能考察指标
  9. C#正则表达式提取HTML中IMG标签中的SRC地址
  10. java xml stax_如何使用Java StAX Iterator API用Java编写XML文件
  11. 解决linux下 firefox 浏览器 视频无法播放问题
  12. RF 无法连接到服务器,这可能由于连接的服务不存在,TCP 错误代码 10061
  13. x86 BIOS 中断 INT 10h
  14. FITS python
  15. 安卓应用方法数超过64k解决办法:分割Dex
  16. 临港新片区设立知识产权综合服务窗口和维权援助中心提升知识产权服务效能
  17. 使用Nmap进行端口扫描和服务识别
  18. 《天天数学》连载17:一月十七日
  19. 微信小程序--代码包压缩策略
  20. 一芯拿捏丨APM32F107单相并网储能变流器应用方案

热门文章

  1. HDU 5575 Discover Water Tank 并查集 树形DP
  2. Git操作 --忽略文件
  3. python写的串口助手并连接腾讯云服务器数据库
  4. YRCloudFile新版本携数据分层功能闪亮发布
  5. java经典学习路线
  6. 支持拼音检索的TextBox扩展控件
  7. 与曾宪寿共探中医应用属性数学之路一(作者:赵致生)
  8. Linux 之 挂载nfts格式硬盘
  9. 基于STM32F411使用SPI+DMA驱动LCD
  10. matlab读取grb、grb2数据并导出、绘图