接着前面几章说,到这一步我们已经做了大部分的事情,下面就是当主角跑动的时候与特定的刚体和传感器碰撞时,我们需要监听这些事件并做出一些相应,下面写下如何操作。
首先我们要创建一个监听类,它继承于b2ContactListener
// MyContactListener.h
// HamsterRun
//
// Created by 伟栋 孙 on 12-3-9.
// Copyright (c) 2012年 easymobi. All rights reserved.
//
#import “Box2D.h”
#import “cocos2d.h”
#import
class MyContactListener : public b2ContactListener {
public:
MyContactListener();
~MyContactListener();
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);
};
// MyContactListener.mm
// HamsterRun
//
// Created by 伟栋 孙 on 12-3-9.
// Copyright (c) 2012年 easymobi. All rights reserved.
//
#import “MyContactListener.h”
MyContactListener::MyContactListener() {
}
MyContactListener::~MyContactListener() {
}
void MyContactListener::BeginContact(b2Contact *contact) {
} //当刚体发生碰撞开始的时候调用
void MyContactListener::EndContact(b2Contact *contact) {
}//当刚体结束碰撞时调用
void MyContactListener::PreSolve(b2Contact *contact, const b2Manifold *oldManifold) {
} //碰撞开始前调用
void MyContactListener::PostSolve(b2Contact *contact, const b2ContactImpulse *impulse) {
}
每个方法的作用已经进行了标注,我们通常通过BeginContact和EndContact来对碰撞进行相应。
接下来我们为世界增加这个监听。使用world->SetContactListener()方法。
这样,当碰撞发生时,就会触发监听当中对应的方法。我们通过contact可以得到碰撞的刚体信息。举个例子
在BeginContact方法中:
void MyContactListener::BeginContact(b2Contact *contact) {
CCSprite *o1 = (CCSprite*)contact->GetFixtureA()->GetBody()->GetUserData();
CCSprite *o2 = (CCSprite*)contact->GetFixtureB()->GetBody()->GetUserData();
if(o1.tag == SORT_END && o2.tag == SORT_HAMSTER)
{
}
}
这样就可以对tag为end和hamster的两个精灵及其刚体进行操作。此外,我们还可以通过 b2Manifold* GetManifold = contact->GetManifold(); 来获得接触信息,例如碰撞的向量GetManifold->localNormal.y(Y轴方向) 如果为0-1则表示从上方发生的碰撞,如果为0 – -1则表示从下方发生的碰撞,X轴以此类推。这样我们就可以根据他们的碰撞的方向来做出不同的反应,例如从下面顶一个箱子可以顶出道具,从上面的话可以走过。
最后,来讲一下碰撞筛选。这个大家可以参考一下http://blog.sina.com.cn/s/blog_6a2061a20100n0or.html
什么意思呢,就是说我可以为刚体的一个夹具设置谁与他碰撞,谁与他不会产生碰撞。这里有两个属性可以设置,一个是groupIndex属性 一个是filter.前者比较好理解,当他们属于同一个groupIndex的时候会发生碰撞,反之则不发生,他的优先级是高于filter的。至于filter,是通过它的categoryBits值与maskBits值完成的。categoryBits用于定义自己所属的碰撞种类,maskBits则是指定碰撞种类。categoryBits 一共有16种群,分别是
0×0001 = 1
0×0002 = 2
0×0004 = 4
0×0008 = 8
0×0010 = 16
0×0020 = 32
0×0040 = 64
0×0080 = 128
0×0100 = 256
0×0200 = 512
0×0400 = 1024
0×0800 = 2048
0×1000 = 4096
0×2000 = 8192
0×4000 = 16384
0×8000 = 32768
如果想让夹具与另一个夹具发生碰撞,那么他的categoryBits的必须包含在另一个夹具的maskBits值当中,同样另一个夹具也需要满足这个条件。当我们不想让两个刚体发生碰撞时,只需要修改其加爵的filter即可。