在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:
virtual void BeginContact(b2Contact* contact)。两个物体開始接触时会响应,但仅仅调用一次。

virtual void EndContact(b2Contact* contact)。分离时响应。

但仅仅调用一次。

virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold)。持续接触时响应,它会被多次调用。

virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)。持续接触时响应,调用完preSolve后调用。

以下通过将12.2.3一节的实例採用Box2D技术重构。了解一下Box2d物理引擎中怎样检測碰撞。
首先我们须要在project中加入一个新类。

使用Visual Studio 2012中加入一个新类。须要分别加入C++源文件和头文件。详细操作,如图所看到的。右键点击projectHelloBox2D下的Classes目录。在右键菜单中选择。“加入”→ “新项目”。

弹出如后面的图所看到的加入新项对话框,我们在对话框中选择文件的种类,在“名称”中输入文件名称ContactListener,然后点击“加入”button加入文件。

Visual Studio 2012中加入新类

加入新项对话框

加入完毕新类ContactListener。我们还须要改动它的代码,ContactListener.h文件代码例如以下:

#include "cocos2d.h"
#include "Box2D/Box2D.h" USING_NS_CC; class ContactListener : public b2ContactListener
{
private:
//两个物体開始接触时会响应
virtual void BeginContact(b2Contact* contact); //持续接触时响应
virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
//持续接触时响应,调用完preSolve后调用
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse); //分离时响应
virtual void EndContact(b2Contact* contact);
};
在头文件里须要引入cocos2d.h和Box2D/Box2D.h头文件,否则会有编译错误。ContactListener採用共同拥有继承b2ContactListener。
ContactListener.cpp文件代码例如以下:
#include "ContactListener.h" void ContactListener::BeginContact(b2Contact* contact) ①
{
log("BeginContact"); b2Body* bodyA = contact->GetFixtureA()->GetBody(); ②
b2Body* bodyB = contact->GetFixtureB()->GetBody(); ③
auto spriteA = (Sprite*)bodyA->GetUserData(); ④
auto spriteB = (Sprite*)bodyB->GetUserData(); ⑤ if (spriteA != nullptr && spriteB != nullptr) ⑥
{
spriteA->setColor(Color3B::YELLOW);
spriteB->setColor(Color3B::YELLOW);
}
} void ContactListener::EndContact(b2Contact* contact) ⑦
{
log("EndContact"); b2Body* bodyA = contact->GetFixtureA()->GetBody();
b2Body* bodyB = contact->GetFixtureB()->GetBody();
auto spriteA = (Sprite*)bodyA->GetUserData();
auto spriteB = (Sprite*)bodyB->GetUserData(); if (spriteA != nullptr && spriteB != nullptr)
{
spriteA->setColor(Color3B::WHITE);
spriteB->setColor(Color3B::WHITE);
}
} void ContactListener::PreSolve(b2Contact* contact, const b2Manifold* oldManifold) ⑧
{
log("PreSolve");
} void ContactListener::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse) ⑨
{
log("PostSolve");
}

上述代码第①行是实现碰撞事件BeginContact函数,第②代码和第③行代码是获得接触两方物体对象。第④代码和第⑤行代码是从物体对象的UserData属性中确定精灵对象,UserData属性可以放置不论什么对象,这里我们可以通过bodyA->GetUserData()语句取得精灵,那是由于在定义物体的时候通过body->SetUserData(sprite)语句,将精灵放入到物体的UserData属性。

第⑥行代码是推断两个精灵是否存在。

代码第⑦行是实现碰撞事件EndContact函数。函数的实现与BeginContact函数相似。第⑧和第⑨行代码是实现碰撞事件PreSolve和PostSolve函数。这两个函数通经常使用的不多。

我们还须要在要监听事件的层中,加入相关碰撞检測代码。在HelloWorld.h的代码例如以下:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h"
#include "Box2D/Box2D.h"
#include "ContactListener.h" ① #define PTM_RATIO 32 class HelloWorld : public cocos2d::Layer
{
b2World* world;
ContactListener* contactListener; ② public: ~HelloWorld(); static cocos2d::Scene* createScene();
virtual bool init(); virtual void update(float dt);
virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
CREATE_FUNC(HelloWorld); void initPhysics();
void addNewSpriteAtPosition(cocos2d::Vec2 p); }; #endif // __HELLOWORLD_SCENE_H__

上述代码第①行是引入头文件ContactListener.h。第②行代码是声明ContactListener类型的成员变量contactListener。

我们还须要改动HelloWorld.cpp中的HelloWorld::initPhysics()代码例如以下:

void HelloWorld::initPhysics()
{
… …
contactListener = new ContactListener();
world->SetContactListener(contactListener);
… …
}

函数中的contactListener = new ContactListener()语句是创建ContactListener对象,採用了newkeyword分配内存,创建成员变量contactListener,须要自己释放contactListener对象。这些释放过程是在析构函数中进行。它的析构函数代码例如以下:
HelloWorld::~HelloWorld()
{
    CC_SAFE_DELETE(world);    
CC_SAFE_DELETE(contactListener);
}

使用CC_SAFE_DELETE(contactListener)安全释放contactListener成员变量的内存。

很多其它内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》‍

本书交流讨论站点:http://www.cocoagame.net

很多其它精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
欢迎增加Cocos2d-x技术讨论群:257760386

《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:‍

京东:http://item.jd.com/11584534.html

亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

当当:http://product.dangdang.com/23606265.html

互动出版网:http://product.china-pub.com/3770734

《Cocos2d-x实战 C++卷》源代码及样章下载地址:

源代码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1

样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

欢迎关注智捷iOS课堂微信公共平台

实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測的更多相关文章

  1. 实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D

    我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用.这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触 ...

  2. 实例介绍Cocos2d-x中Box2D物理引擎:使用关节

    下面我们将使用Box2D物理引擎技术进行重构.使得关节能够掌握如何在Box2D使用关节约束.HelloWorldScene.cpp中与使用关节的相关代码如下: void HelloWorld::add ...

  3. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  4. cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检測(1)

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  5. cocos2d-x中的Box2D物理引擎

    在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D.前者是用C语言编写的,文档和例子相对较少:Box2D是用C++写的,并且有比较完善的文档和资料.所以在需要使用物理引 ...

  6. 瘸腿蛤蟆笔记29-cocos2d-x-3.2 Box2d物理引擎dynamics模块介绍

    转载标明出处:http://blog.csdn.net/notbaron/article/details/38611335 上篇回想 本篇名言:奋斗.寻觅.发现,而不屈服.[诗人丁尼生] 上篇中,我们 ...

  7. libgdx学习记录18——Box2d物理引擎

    libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创 ...

  8. python下的Box2d物理引擎的配置

    /******************************* I come back! 由于已经大四了,正在找工作 导致了至今以来第二长的时间内没有更新博客.向大家表示道歉 *********** ...

  9. 【极客学院出品】Cocos2d-X系列课程之九-BOX2D物理引擎

    Cocos2d-x 是时下最热门的手游引擎,在国内和国外手机游戏开发使用的份额各自是70%和25%,在App Store的top10中,有7个是用它开发的. 本节课程为Cocos2d-x系列课程之九, ...

随机推荐

  1. C# 利用反射进行类型转换

    /// <summary> /// 父类转子类 /// </summary> /// <typeparam name="TParent">< ...

  2. Windows下apache+tomcat负载均衡

    Windows下apache+tomcat负载均衡 网上已经有很多的资料,但是很多都比较零碎,需要整合一起才能搭建出理想的负载均衡,正好前段时间搭建了windows与linux下的负载均衡,在此记录, ...

  3. Paint、Canvas

    1.Canvas类 public class Canvas { public static final int ALL_SAVE_FLAG = 31; /** @deprecated */ @Depr ...

  4. Python常用的标准库及第三方库

    标准库Python拥有一个强大的标准库.Python语言的核心只包含数字.字符串.列表.字典.文件等常见类型和函数,而由Python标准库提供了系统管理.网络通信.文本处理.数据库接口.图形系统.XM ...

  5. Matrix computations in C

    meschach配置使用 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...

  6. MyBatis入门3_mapper.xml优化(parameterType简写_NameSpace简写_sql片段_特殊字符处理)_动态SQL

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 优化 1.起别名(一般不用,写全方便查看类出处) 以前 ...

  7. ABP初始化

    默认认为你手中已经有abp-zero项目,当前4.6.0 angularJS切换到jquery 运行项目,初始化是跳转到~/App/common/views/layout/layout.cshtml, ...

  8. 错误处理:vmware下克隆centos7配置静态ip地址网卡问题

    vmware下克隆centos7,在配置静态ip地址,重启网卡存在问题,还是mac地址问题 ip addr show 查看下mac地址,配置文件修改下,重启网卡正常了

  9. C# WebKitBrowser 设置内容

    WebKit.WebKitBrowser kitBrowser = new WebKit.WebKitBrowser(); kitBrowser.Dock = DockStyle.Fill; // k ...

  10. day07-列表类型/元组类型/字典类型/集合类型内置方法

    目录 列表类型内置方法 元组类型内置方法 字典类型内置方法 集合类型内置方法 列表类型内置方法 用来存多个元素,[]内用逗号隔开任意数据类型的元素 1. list()强制类型转换 print(list ...