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物理引擎中如何检测碰撞。
首先我们需要在工程中添加一个新类。使用Visual Studio 2012中添加一个新类,需要分别添加C++源文件和头文件。具体 *** 作,如图所示,右键点击工程HelloBox2D下的Classes文件夹,在右键菜单中选择,“添加”→ “新项目”。d出如后面的图所示添加新项对话框,我们在对话框中选择文件的种类,在“名称”中输入文件名ContactListener,然后点击“添加”按钮添加文件。
@H_403_10@
Visual Studio 2012中添加新类 @H_403_10@
@H_403_10@ 添加新项对话框 @H_403_10@ 添加完成新类ContactListener,我们还需要修改它的代码,ContactListener.h文件代码如下:
[HTML] view plain copy @H_403_10@ @H_403_10@ @H_403_10@ #include"cocos2d.h" #include"Box2D/Box2D.h" USING_NS_CC; classContactListener:publicb2ContactListener { private: //两个物体开始接触时会响应 virtualvoIDBeginContact(b2Contact*contact); //持续接触时响应 virtualvoIDPreSolve(b2Contact*contact,constb2Manifold*oldManifold); //持续接触时响应,调用完preSolve后调用 virtualvoIDpostsolve(b2Contact*contact,constb2ContactImpulse*impulse); //分离时响应 virtualvoIDEndContact(b2Contact*contact); }; 在头文件中需要引入cocos2d.h和Box2D/Box2D.h头文件,否则会有编译错误。ContactListener采用共有继承b2ContactListener。 ContactListener.cpp文件代码如下: #include"ContactListener.h" voIDContactListener::BeginContact(b2Contact*contact)① log("BeginContact"); b2Body*bodyA=contact->GetFixtureA()->Getbody();② b2Body*bodyB=contact->GetFixtureB()->Getbody();③ autospriteA=(Sprite*)bodyA->GetUserData();④ autospriteB=(Sprite*)bodyB->GetUserData();⑤ if(spriteA!=nullptr&&spriteB!=nullptr)⑥ spriteA->setcolor(color3B::YELLOW); spriteB->setcolor(color3B::YELLOW); } } voIDContactListener::EndContact(b2Contact*contact)⑦ log("EndContact"); >Getbody(); >Getbody(); >GetUserData(); >GetUserData(); if(spriteA!=nullptr&&spriteB!=nullptr) >setcolor(color3B::WHITE); >setcolor(color3B::WHITE); voIDContactListener::PreSolve(b2Contact*contact,constb2Manifold*oldManifold)⑧ log("PreSolve"); voIDContactListener::postsolve(b2Contact*contact,constb2ContactImpulse*impulse)⑨ log("postsolve"); } @H_403_10@
上述代码第①行是实现碰撞事件BeginContact函数,第②代码和第③行代码是获得接触双方物体对象。第④代码和第⑤行代码是从物体对象的UserData属性中确定精灵对象,UserData属性可以放置任何对象,这里我们能够通过bodyA->GetUserData()语句取得精灵,那是因为在定义物体的时候通过body->SetUserData(sprite)语句,将精灵放入到物体的UserData属性。第⑥行代码是判断两个精灵是否存在。
代码第⑦行是实现碰撞事件EndContact函数,函数的实现与BeginContact函数类似。第⑧和第⑨行代码是实现碰撞事件PreSolve和postsolve函数,这两个函数通常用的不多。
我们还需要在要监听事件的层中,添加相关碰撞检测代码。在HelloWorld.h的代码如下:
copy @H_403_10@ @H_403_10@ @H_403_10@ #ifndef__HELLOWORLD_SCENE_H__ #define__HELLOWORLD_SCENE_H__ #include"cocos2d.h" #include"ContactListener.h"① #definePTM_RATIO32 classHelloWorld:publiccocos2d::Layer { b2World*world; ContactListener*contactListener;② public: ~HelloWorld(); staticcocos2d::Scene*createScene(); virtualboolinit(); virtualvoIDupdate(floatdt); virtualboolontouchBegan(cocos2d::touch*touch,cocos2d::Event*event); CREATE_FUNC(HelloWorld); voIDinitPhysics(); voIDaddNewSpriteAtposition(cocos2d::Vec2p); #endif//__HELLOWORLD_SCENE_H__ @H_403_10@
上述代码第①行是引入头文件ContactListener.h。第②行代码是声明ContactListener类型的成员变量contactListener。
我们还需要修改HelloWorld.cpp中的HelloWorld::initPhysics()代码如下:
copy @H_403_10@ @H_403_10@ @H_403_10@ voIDHelloWorld::initPhysics() …… contactListener=newContactListener(); world->SetContactListener(contactListener); …… 函数中的contactListener = new ContactListener()语句是创建ContactListener对象,采用了new关键字分配内存,创建成员变量contactListener,需要自己释放contactListener对象。这些释放过程是在析构函数中进行,它的析构函数代码如下:
HelloWorld::~HelloWorld()
{
CC_SAFE_DELETE(world);
CC_SAFE_DELETE(contactListener);
}
使用CC_SAFE_DELETE(contactListener)安全释放contactListener成员变量的内存。
总结以上是内存溢出为你收集整理的实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测全部内容,希望文章能够帮你解决实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)