cocos2d中怎么去除cocos2dx物理引擎教程的边界颜色

--旗下,中国最好的系统开发学习平台!
热门推荐:
当前位置: >
cocos2d-x实用效果之BOX2D的圆形包围边界,cocos2d-xbox2d
发布时间: 11:20 | 作者:采集侠 | 来源:网络整理 | 浏览:
cocos2d-x实用效果之BOX2D的圆形包围边界,cocos2d-xbox2d
本文基于cocos2d-x2.2.3,并未在3.0之后的版本下编写,仅仅是提供一个思路,方便日后其他场景使用到该功能点可以参考,也没有详细讲述box2d物理引擎的基础知识,相关知识请自行多参考其他技术文档。
使用box2d物理引擎,通常需要我们自己给定一个边界来限制body的活动范围,最常用的是在屏幕的边界使用四条边来包围,形成一个矩形。但如果我们的需求是在一个圆形范围内,仅仅想通过一个中心点和半径来确定这个范围,该如何处理呢?其实圆弧也可以看成是无数小线段组成的,当线段数目足够多时便无限趋近于圆,因此我们可以在想要做为范围的圆周上面取一定数量的点,将各个点连起来所包围的范围,便可以看做是一个圆形区域。我们需要做的就是确定这些点的坐标,首尾相连就可以围城一个近似圆的区域,当然点数越多越圆,计算量越多,性能越低,所以取适当即可,本文例子中取24个点。
如此一来,我们在创建物理世界初始化的时候,便可以将各个点数据围一个圆形的包围盒,写法如下:
&span& //设置重力参数
gravity.Set(0.0f,0.0f);
//创建世界
m_world = new b2World(gravity);
//是否允许休眠
m_world-&SetAllowSleeping(true);
//是否连续物理测试
m_world-&SetContinuousPhysics(true);
//地面物体定义
b2BodyDef groundBodyD
groundBodyDef.position.Set(0,0);
groundBody = m_world-&CreateBody(&groundBodyDef);
//定义点的个数
float pointNum = 24;
//定义圆形边界的半径
radius = 300;
//定义圆心
m_center = ccp(640,400);
//存放点数据的数组
CCPoint point[24];
for (int i= 0; i & pointN i++) {
//计算每两个点连成的线段的起始点的角度、坐标(第一个为0°)
float angle = (float)i/pointNum *PI*2;
float bx = radius * cos(angle);
float by = radius * sin(angle);
//圆心加上偏移量即为当前点坐标
bx += m_center.x;
by += m_center.y;
point[i].setPoint(bx,by);
point[23].setPoint(point[0].x,point[0].y);
for(int i= 0; i & pointNum-1; i++)
//设置边缘范围
groundBox.Set(b2Vec2(point[i].x/PTM_RATIO,point[i].y/PTM_RATIO),b2Vec2(point[i+1].x/PTM_RATIO,point[i+1].y/PTM_RATIO));
groundBody-&CreateFixture(&groundBox,100);
效果如下:
上面只是给出了主要实现的代码段,仅供参考,也可以下载代码自己运行试试看,根据需要再进行参数的调整,自己mark,免得日后需要的时候找来找去!!代码和资源在下面,请自己创建工程运行
点击下载参考源代码
:///Androidjc/981107.htmlTechArticlecocos2d-x实用效果之BOX2D的圆形包围边界,cocos2d-xbox2d 本文基于cocos2d-x2.2.3,并未在3.0之后的版本下编写,仅仅是提供一个思路,方便日后其他...在cocos2d-x 3.0中使用物理引擎
在cocos2d-x 3.0中使用物理引擎
Cocos2d-x学习日志
原文地址:
& 在游戏中模拟真实的物理世界是个比较麻烦的,通常都是交给物理引擎来做。比较知名的有Box2D了,它几乎能模拟所有的物理效果,而chipmunk则是个更轻量的引擎等。在Cocos2d-x 2.0中,游戏直接使用物理引擎,引擎提供了一个简单的CCPhysicsSprite,处理了物理引擎的body与CCSprite的关系,而物理引擎的其他要素并没有和引擎对应起来,游戏需要选择直接调用chipmunk或Box2D的api来处理逻辑。然而直接使用物理引擎是比较复杂的,它物理引擎的接口参赛很多,很复杂,而且需要开发人员对物理引擎和Cocos2d-x都很了解,才能把两者融合得很好。
这个情况在3.0中有了改变,全新的Physics integration,把chipmunk和Box2D封装到引擎内部,游戏开发不用关心底层具体是用的哪个物理引擎,不用直接调用物理引擎的接口。 物理引擎和Cocos2d-x进行了深度融合:
物理世界被融入到Scene中,即当创建一个场景时,就可以指定这个场景是否使用物理引擎。Node自带body属性,也就是sprite自带body属性。Cocos2d-x 3.0对物理引擎的Body(PhysicsBody),Shape(PhysicsShape),Contact(PhysicsContact),Joint(PhysicsJoint),World(PhysicsWorld)进行了封装抽象,使用更简单。更简单的碰撞检测监听EventListenerPhysicsContact。
创建带物理引擎的游戏工程
& 在3.0中创建工程由/tools/project-creator下的create_project.py脚本完成。 默认创建的工程已支持物理引擎,内部启用的是chipmunk。如果你愿意,也可以改为Box2D,但这对游戏开发没有影响。 android修改内部使用Box2D物理引擎,打开projects/youPorjecyName/proj.android/jni/Application.mk. 修改
DCC_ENABLE_CHIPMUNK_INTEGRATION=1
DCC_ENABLE_BOX2D_INTEGRATION=1
iOS修改内部使用Box2D物理引擎,修改项目配置中的”Preprocessor Macros”,把
CC_ENABLE_CHIPMUNK_INTEGRATION=1
CC_ENABLE_BOX2D_INTEGRATION=1
如下图所示:
Debug和Release都需要修改。
创建带物理世界的scene
& 下面的代码创建带物理世界的scene,并传递给child layer。 在.h文件中添加以下代码
void setPhyWorld(PhysicsWorld* world){m_world = world;}
PhysicsWorld* m_world;
在.cpp文件的createScene方法中添加以下代码
auto scene = Scene::createWithPhysics();
scene-&getPhysicsWorld()-&setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
auto layer = HelloWorld::create();
layer-&setPhyWorld(scene-&getPhysicsWorld());
& Scene类有了新的静态工厂方法,createWithPhysics(),创建带物理世界的scene。 Scene的getPhysicsWorld()方法获取PhysicsWorld实例, PhysicsWorld的setDebugDrawMask()方法,在调试物理引擎中是很有用的,它把物理世界中不可见的shape,joint,contact可视化。当调试结束,游戏发布的时候,你需要把这个debug开关关闭。
通过setPhyWorld()方法来传递PhysicsWorld给ChildLayer。一个scene只有一个PhysicsWorld,其下的所有layer共用一个PhysicsWorld实例。
创建物理边界
& 我们知道物理世界中,所有物体受重力的影响。 物理引擎提供staticShape创建一个不受重力影响的形状,在Cocos2d-x 2.0中,我们需要了解物理引擎的staticShape相关的各种参数来完成边界设置。 在3.0中,PhysicsShape属于Node的一个属性,要设置PhysicsWorld的属性,都需要通过一个Node实例来中介传达。 下面的代码展示如何创建一个围绕屏幕四周的物理边界。
Size visibleSize = Director::getInstance()-&getVisibleSize();
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
auto edgeNode = Node::create();
edgeNode-&setPosition(Point(visibleSize.width/2,visibleSize.height/2));
edgeNode-&setPhysicsBody(body);
scene-&addChild(edgeNode);
PhysicsBody包含很多工厂方法,createEdgeBox创建一个矩形边界,参数含义依次是:
矩形区域大小,这里设置为visibleSize。设置材质,可选参数,默认为PHYSICSBODY_MATERIAL_DEFAULT。边线宽度,可选参数,默认为1。
& 然后我们创建一个Node,把刚才创建的body附加到Node上,并设置好Node的position为屏幕中心点。 最后,把Node添加到scene。 Node的addChild方法,在3.0中,有对物理body做处理,它会自动把node的body设置到scene的PhysicsWorld上去。 PhysicsBody中的工程方法,针对参数设置的body大小,会自动创建对应的PhysicsBody和一个PhysicsShape,这也是通常情况下,直接使用物理引擎创建一个body需要做的事情。3.0的Physics
integration极大的简化了使用物理引擎的代码量。
创建受重力作用的sprite
&& 在3.0中创建一个受重力作用的Sprite也很简单。
void HelloWorld::addNewSpriteAtPosition(Point p)
auto sprite = Sprite::create(&circle.png&);
sprite-&setTag(1);
auto body = PhysicsBody::createCircle(sprite-&getContentSize().width / 2);
sprite-&setPhysicsBody(body);
sprite-&setPosition(p);
this-&addChild(sprite);
&& 首先创建一个sprite,然后用PhysicsBody::createCircle创建一个圆形的body附加在sprite上。 整个过程和之前创建边界的过程是一致的。
&& Cocos2d-x中,事件派发机制做了重构,所有事件均有事件派发器统一管理。物理引擎的碰撞事件也不例外, 下面的代码注册碰撞begin回调函数。
auto contactListener = EventListenerPhysicsContact::create();
contactListener-&onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this);
_eventDispatcher-&addEventListenerWithSceneGraphPriority(contactListener, this);
碰撞检测的所有事件由EventListenerPhysicsContact来监听,创建一个实例,然后设置它的onContactBegin回调函数,CC_CALLBACK_2是Cocos2d-x 3.0使用C++ 11的回调函数指针转换助手函数,由于onContactBegin回调有两个参数,所有这里使用CC_CALLBACK_2来做转换。 _eventDispatcher是基类Node的成员,Layer初始化后就可直接使用。
& 你可以在这里获取文章配套Demo: Demo基于,
clone后放到引擎的projects(如果没有自行创建)文件夹下。
我的热门文章
即使是一小步也想与你分享11089人阅读
游戏开发(170)
网络游戏(137)
iphone(149)
iOS开发那些事(137)
游戏(158)
碰撞检测是使用物理引擎的一个重要目的,使用物理引擎可以进行精确的碰撞检测,而且执行的效率也很高。在Cocos2d-x 3.x中使用事件派发机制管理碰撞事件,EventListenerPhysicsContact是碰撞事件监听器。碰撞检测相关的API我们在前面一节介绍过了,下面通过一个实例介绍碰撞检测的实现。这个实例的运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的精灵,精灵的运行是自由落体运动。当这些精灵之间发生接触时候,它们的颜色被设置为黄色,分离后颜色又恢复到原来状态了。检测碰撞实例本实例涉及到物理引擎中物体之间的检测碰撞,当两个物体接触到两个物体分离过程中,会发生一些事件,我们可以通过注册监听器EventListenerPhysicsContact来响应这些事件。首先看一下看HelloWorldScene.h文件,它的代码如下:#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include &cocos2d.h&
USING_NS_CC;
class HelloWorld : public cocos2d::Layer
static cocos2d::Scene* createScene();
virtual bool init();
virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
virtual void onEnter();
virtual void onExit();
CREATE_FUNC(HelloWorld);
void addNewSpriteAtPosition(Vec2 p);
#endif // __HELLOWORLD_SCENE_H__上述代码声明了onEnter和onExit函数,用来处理层进入和退出回调函数。我们会在onEnter函数注册EventListenerPhysicsContact监听器,以便于响应碰撞检测事件,在onExit函数中注销这些监听器。HelloWorldScene.cpp中创建物理世界和指定世界的边界语句是在HelloWorld::createScene()和HelloWorld::init()函数中,这两个函数类似于上一节的HelloPhysicsWorld实例,这里不再解释这些函数代码了。HelloWorldScene.cpp中与碰撞检测相关的代码是在onEnter和onExit函数中,代码如下:void HelloWorld::onEnter()
Layer::onEnter();
auto listener = EventListenerPhysicsContact::create();
listener-&onContactBegin = [](PhysicsContact& contact)
auto spriteA = (Sprite*)contact.getShapeA()-&getBody()-&getNode();
auto spriteB = (Sprite*)contact.getShapeB()-&getBody()-&getNode();
if (spriteA && spriteA-&getTag() == 1
&& spriteB && spriteB-&getTag() == 1)
spriteA-&setColor(Color3B::YELLOW);
spriteB-&setColor(Color3B::YELLOW);
log(&onContactBegin&);
listener-&onContactPreSolve = [] (PhysicsContact& contact,
PhysicsContactPreSolve& solve) {
log(&onContactPreSolve&);
listener-&onContactPostSolve = [] (PhysicsContact& contact,
const PhysicsContactPostSolve& solve)
log(&onContactPostSolve&);
listener-&onContactSeperate = [](PhysicsContact& contact) {
auto spriteA = (Sprite*)contact.getShapeA()-&getBody()-&getNode();
auto spriteB = (Sprite*)contact.getShapeB()-&getBody()-&getNode();
if (spriteA && spriteA-&getTag() == 1
&& spriteB && spriteB-&getTag() == 1)
spriteA-&setColor(Color3B::WHITE);
spriteB-&setColor(Color3B::WHITE);
log(&onContactSeperate&);
Director::getInstance()-&getEventDispatcher()-&
addEventListenerWithFixedPriority(listener,1);
void HelloWorld::onExit()
Layer::onExit();
log(&HelloWorld onExit&);
Director::getInstance()-&getEventDispatcher()-&removeAllEventListeners();
}上述代码的onEnter()函数是进入场景时候回调的函数,我们可以在这里通过auto listener = EventListenerPhysicsContact::create()语句创建物体碰撞检测事件监听器对象。接下来通过第①、⑥、⑤、⑦行使用Lambda表达式定义了事件处理的匿名函数。代码第②和第③行是从接触点中取出互相接触的两个节点对象,它的取值过程有点复杂,首先接触点使用getShapeA()和getShapeB()函数获得物体形状,在通过形状的getBody()函数获得物体,通过物体的getNode()函数获得与形状相关的节点对象。第④行代码是进行判断,判断从接触点取出的节点对象是否存在,并且判断是否tag属性为1。上面代码第⑧行addEventListenerWithFixedPriority是指定固定的事件优先级注册监听器,事件优先级决定事件响应的优先级别,值越小优先级越高。代码第⑨行是在退出层回调函数onExit()中注销所有的监听事件。HelloWorldScene.cpp中还有onTouchBegan和addNewSpriteAtPosition两个函数,它们的代码如下。&bool HelloWorld::onTouchBegan(Touch* touch, Event* event)
Vec2 location = touch-&getLocation();
addNewSpriteAtPosition(location);
void HelloWorld::addNewSpriteAtPosition(Vec2 p)
auto sp = Sprite::create(&BoxA2.png&);
sp-&setTag(1);
auto body = PhysicsBody::createBox(sp-&getContentSize());
body-&setContactTestBitmask(0xFFFFFFFF);
sp-&setPhysicsBody(body);
sp-&setPosition(p);
this-&addChild(sp);
}这两个函数的代码与上一节介绍的实例基本一致,但是需要注意的是我们在第①行添加了body-&setContactTestBitmask(0xFFFFFFFF)代码,它的作用是设置物体接触时候能否触发EventListenerPhysicsContact中定义的碰撞检测事件。如果两个物体的接触测试掩码(ContactTestBitmask)执行“逻辑与”运算,如果结果为非零值,表明这两个物体会触发碰撞检测事件。默认值是0x,表示清除所有掩码位,0xFFFFFFFF表示所有掩码位都设置为1。假设有三个物体(body1、body2和body3),设置接触测试掩码如下:body1-&setContactTestBitmask (0x01); //0001body2-&setContactTestBitmask (0x03); //0011body3&setContactTestBitmask (0x02); //0010那么body1和body2,以及body2和body3是可以触发EventListenerPhysicsContact的碰撞检测事件的,而body1和body3是不能的。另外,除了接触测试掩码(ContactTestBitmask)外,物理引擎中还定义了类别掩码(CategoryBitmask)和碰撞掩码(CollisionBitmask),它们的作用是当两个物体接触时候是否发生“碰撞反应”,“碰撞反应”会表现为一个物体受到另外物体的碰撞,而改变运动方向。由于两个物体是“刚体”,在碰撞的时候两个物体不会交叉。那么类别掩码(CategoryBitmask)与碰撞掩码(CollisionBitmask)究竟是什么呢?1、类别掩码定义了一个物体所属类别,每一个物体在场景中能被分配到多达32个不同的类别。通过body-&setCategoryBitmask(int bitmask)函数设置类别掩码。2、碰撞掩码当两个物体相互接触时,该物体的碰撞掩码与另一个物体的类别掩码执行“逻辑与”运算,如果结果为非零值,该物体能够对另一个物体的碰撞发生反应。通过body-&setCollisionBitmask(int bitmask) 函数设置的碰撞掩码。综上所述,类别掩码(CategoryBitmask)与碰撞掩码(CollisionBitmask)决定了物体能否发生“碰撞反应”。而接触测试掩码(ContactTestBitmask)的设置,能够检测是否发生接触发生,并且触发EventListenerPhysicsContact监听事件。 接触测试掩码与类别掩码和碰撞掩码没有什么关联。假设有三个物体(body1、body2和body3),它们设置如下:body1-&setCategoryBitmask(0x01); //0001
body1-&setCollisionBitmask(0x03); //0011
body2-&setCategoryBitmask(0x02); //0010
body2-&setCollisionBitmask(0x01); //0001
body3-&setCategoryBitmask(0x04); //0100
body3-&setCollisionBitmask(0x06); //0110body1和 body1之间、body1和 body2、body3和 body3能够互相发生碰撞反应,body1和body3不能发生碰撞反应。box 2不能对box3的碰撞发生反应,但box 3能够对box2的碰撞发生反应。更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》?本书交流讨论网站:更多精彩视频课程请关注智捷课堂Cocos课程:欢迎加入Cocos2d-x技术讨论群:? 《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:?京东:亚马逊:当当:互动出版网:?《Cocos2d-x实战 C++卷》源码及样章下载地址:源码下载地址:样章下载地址: ?欢迎关注智捷iOS课堂微信公共平台
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
技术讨论群cocos群:7760386;iOS学习讨论qq群:4462948 技术讨论论坛,关东升图书读者qq群:
访问:1229034次
积分:15809
积分:15809
排名:第433名
原创:366篇
转载:37篇
评论:317条
难度:高级
类型:技术教程
难度:高级
类型:技术教程
难度:高级
类型:技术教程
文章:78篇
阅读:263407
文章:10篇
阅读:22512
文章:54篇
阅读:281532
(3)(4)(11)(12)(13)(10)(18)(15)(11)(9)(20)(1)(2)(20)(15)(15)(20)(13)(16)(16)(1)(4)(4)(10)(14)(11)(8)(8)(3)(8)(6)(5)(5)(1)(4)(1)(13)(7)(8)(2)(19)(6)(1)(1)(6)(2)(3)cocos2d-x(17)
Quick-cocos2d-x(18)
http://www.cocos2d-x.org/wiki/Physics
上面这个链接是官方的,我随便翻译了一下,其实大意就是:cocos2dx 3.0(只能确定3.0,不知道后面版本有没有添加)中有两种物理
引擎Box2D与chipmunk,但是官方只封装了chipmunk,并没有封装Box2D,也就是说如果使用Box2D的话,需要直接操作Box2D的API,有
好有坏!简单的看看下面的新特性:
(1) 物理世界被融入到Scene中,即当创建一个场景时,就可以指定这个场景是否使用物理引擎。
(2) Node自带body属性,也就是sprite自带body属性。
(3) Cocos2d-x 3.0对物理引擎的Body(PhysicsBody),Shape(PhysicsShape),Contact(PhysicsContact),Joint & &(PhysicsJoint),
& & World(PhysicsWorld)进行了封装抽象,使用更简单。
(4) 更简单的碰撞检测监听EventListenerPhysicsContact。
上面所有的里面都是用使用chipmunk引擎,不管你怎么切换宏。
我本意是学Box2D的物理引擎,目地也就是在cocos2dx中使用物理引擎,这里我简单的把官方的对于cocos2dx使用的物理引擎的方法生
搬过来,但并不打乱我们继续学习cocos2dx中使用Box2D的节奏。
1、创建带物理世界的场景scene
我们来创建一个带物理世界的场景scene,并传递给child layer。
在HelloWorldScene.h中添加如下代码:
PhysicsWorld* m_
void setPhyWorld(PhysicsWorld* world){ m_world =}
在HelloWorldScene.cpp中的createScene方法中添加如下代码:&
auto scene = Scene::createWithPhysics();
scene-&getPhysicsWorld()-&setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
auto layer = HelloWorld::create();
layer-&setPhyWorld(scene-&getPhysicsWorld());
1.1、用Scene新的静态工厂方法createWithPhysics()来创建物理世界的scene。
1.2、Scene的getPhysicsWorld()方法用来获取PhysicsWorld实例。
1.3、PhysicsWorld的setDebugDrawMask()方法,在调试物理引擎中是很有用的,它把物理世界中不可见的shape,joint,contact可视
& & &化。当调试结束,游戏发布的时候,你需要把这个debug开关关闭。
1.4、通过setPhyWorld()方法来传递PhysicsWorld给ChildLayer。一个scene只有一个PhysicsWorld,其下的所有layer共用一个PhysicsWorld实例。
2、创建物理边界
我们知道物理世界中,所有物体受重力的影响。物理引擎提供staticShape创建一个不受重力影响的形状,在Cocos2d-x 2.0中,我们需要了
解物理引擎的staticShape相关的各种参数来完成边界设置。在3.0中,PhysicsShape属于Node的一个属性,要设置PhysicsWorld的属性,都
需要通过一个Node实例来中介传达。下面的代码展示如何创建一个围绕屏幕四周的物理边界:
Size visibleSize = Director::getInstance()-&getVisibleSize();
auto body = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);
auto edgeNode = Node::create();
edgeNode-&setPosition(Point(visibleSize.width/2,visibleSize.height/2));
edgeNode-&setPhysicsBody(body);
scene-&addChild(edgeNode);
2.1、PhysicsBody包含很多工厂方法,createEdgeBox创建一个矩形边界,参数含义依次是:
& & &1、 矩形区域大小,这里设置为visibleSize。
& & &2、 设置材质,可选参数,默认为PHYSICSBODY_MATERIAL_DEFAULT。
& & &3、 边线宽度,可选参数,默认为1。
2.2、然后我们创建一个Node,把刚才创建的body附加到Node上,并设置好Node的position为屏幕中心点。
2.3、最后,把Node添加到scene。
2.4、Node的addChild方法,在3.0中,有对物理body做处理,它会自动把node的body设置到scene的PhysicsWorld上去。
2.6、PhysicsBody中的工程方法,针对参数设置的body大小,会自动创建对应的PhysicsBody和一个PhysicsShape,
& & &这也是通常情况下,直接使用物理引擎创建一个body需要做的事情。3.0的Physics integration极大的简化
& & &了使用物理引擎的代码量。
3、创建受重力作用 sprite
在3.0中创建一个受重力作用的sprite其实不难。示例代码如下:
void HelloWorld::addNewSpriteAtPosition(Point p)
auto sprite = Sprite::create(&circle.png&);
sprite-&setTag(1);
auto body = PhysicsBody::createCircle(sprite-&getContentSize().width / 2);
sprite-&setPhysicsBody(body);
sprite-&setPosition(p);
this-&addChild(sprite);
首先创建一个sprite,然后用PhysicsBody::createCircle创建一个圆形的body附加在sprite上。整个过程和之前创建边界的过程是一致的。&
4、碰撞检测
cocos2d-x中,事件派发机制做了重构,所有事件均有事件派发器统一管理。物理引擎的碰撞事件也不例外,下面的代码注册碰撞begin回调函数:
auto contactListener = EventListenerPhysicsContact::create();
contactListener-&onContactBegin = CC_CALLBACK_2(HelloWorld::onContactBegin, this);
_eventDispatcher-&addEventListenerWithSceneGraphPriority(contactListener, this);
4.1、碰撞检测的所有事件由EventListenerPhysicsContact来监听,创建一个实例,然后设置它的onContactBegin回调函数,CC_CALLBACK_2是
& & &Cocos2d-x 3.0使用C++ 11的回调函数指针转换助手函数,由于onContactBegin回调有两个参数,所有这里使用CC_CALLBACK_2来做转换。
4.2、_eventDispatcher是基类Node的成员,Layer初始化后就可直接使用。
你还可以使用EventListenerPhysicsContactWithBodies, EventListenerPhysicsContactWithShapes, EventListenerPhysicsContactWithGroup
来监听你感兴趣的两个物体、两个形状,或者某组物体的碰撞事件,但是要注意设置物体碰撞相关的mask值(下面会详细说明),因为物体碰撞
事件在默认情况下是不接收的,即使你创建了相应的EventListener。
PhysicsBody碰撞相关的mask设置和group设置跟Box2D的设置是一致的。
mask设置分为三种:
CategoryBitmask-&表示“我是谁”;
ContactTestBitmask--&表示“在我和谁发生碰撞通知我”;
CollisionBitmask--&表示”我和谁发生碰撞“;
如果a-&CategoryBitmask & b-&CollisionBitmask等于0或者b-&CategoryBitmask & a-&CollisionBitmask等于0,不发生碰撞,可以看到物体穿越
另一个物体.你可以通过相关的get/set接口来获得或者设置他们。他们是通过逻辑与来进行测试的,当一个物体的CategoryBitmask跟另一个物体的
ContactTestBitmask的逻辑与测试结果不为零时,将会发送相应的事件,否则不发送。而当一个物体的CategoryBitmask跟另一个物体的
CollisionBitmask的逻辑与测试结果不为零时,将会发生碰撞,否则不发生碰撞。注意,在默认情况下CategoryBitmask的值为0xFFFFFFFF,
ContactTestBitmask的值为0x,CollisionBitmask的值为0xFFFFFFFF,也就是说默认情况下所有物体都会发生碰撞但不发送通知。
另一个碰撞相关的设置是group(组),当它大于零时,同组的物体将发生碰撞,当它小于零时,同组的物体不碰撞。注意,当group不为零时,
他将忽略mask的碰撞设置(是否通知的设置依然有效)。在EventListenerPhysicsContact里有四个碰撞回调函数,他们分别是onContactBegin,
onContactPreSolve,onContactPostSolve和onContactSeperate。在碰撞刚发生时,onContactBegin会被调用,并且在此次碰撞中只会被调用
一次。你可以通过返回true或者false来决定物体是否发生碰撞。你可以通过PhysicsContact::setData()来保存自己的数据以便用于后续的碰
撞处理。需要注意的是,当onContactBegin返回flase时,onContactPreSolve和onContactPostSolve将不会被调用,但onContactSeperate必
定会被调用。
onContactPreSolve发生在碰撞的每个step,你可以通过调用PhysicsContactPreSolve的设置函数来改变碰撞处理的一些参数设定,比如弹力,阻力等。
同样你可以通过返回true或者false来决定物体是否发生碰撞。你还可以通过调用PhysicsContactPreSolve::ignore()来跳过后续的onContactPreSolve
和onContactPostSolve回调事件通知(默认返回true)。onContactPostSolve发生在碰撞计算完毕的每个step,你可以在此做一些碰撞的后续处理,比
如摧毁某个物体等。onContactSeperate发生在碰撞结束两物体分离时,同样只会被调用一次。它跟onContactBegin必定是成对出现的,所以你可以在此
摧毁你之前通过PhysicsContact::setData()设置的用户数据。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:15547次
排名:千里之外
原创:39篇
(3)(5)(3)(7)(4)(3)(6)(1)(3)(1)(1)(4)(2)(2)(2)}

我要回帖

更多关于 cocos2dx 物理引擎 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信