1.add method to set collider filter

This commit is contained in:
2youyou2 2013-11-01 14:36:44 +08:00
parent 4eaaaddc34
commit a9054ba14a
7 changed files with 161 additions and 33 deletions

View File

@ -728,6 +728,16 @@ Bone *Armature::getParentBone()
return _parentBone; return _parentBone;
} }
void CCArmature::setColliderFilter(ColliderFilter *filter)
{
DictElement *element = NULL;
CCDICT_FOREACH(_boneDic, element)
{
Bone *bone = static_cast<Bone*>(element->getObject());
bone->setColliderFilter(filter);
}
}
#if ENABLE_PHYSICS_BOX2D_DETECT #if ENABLE_PHYSICS_BOX2D_DETECT
b2Body *Armature::getBody() b2Body *Armature::getBody()
{ {

View File

@ -175,6 +175,8 @@ public:
virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture); virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture);
virtual void setColliderFilter(ColliderFilter *filter);
#if ENABLE_PHYSICS_BOX2D_DETECT #if ENABLE_PHYSICS_BOX2D_DETECT
virtual b2Fixture *getShapeList(); virtual b2Fixture *getShapeList();
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT #elif ENABLE_PHYSICS_CHIPMUNK_DETECT

View File

@ -441,4 +441,31 @@ Array *Bone::getColliderBodyList()
} }
void Bone::setColliderFilter(ColliderFilter *filter)
{
Array *array = _displayManager->getDecorativeDisplayList();
Object *object = NULL;
CCARRAY_FOREACH(array, object)
{
DecorativeDisplay *decoDisplay = static_cast<DecorativeDisplay *>(object);
if (ColliderDetector *detector = decoDisplay->getColliderDetector())
{
detector->setColliderFilter(filter);
}
}
}
ColliderFilter *Bone::getColliderFilter()
{
if (DecorativeDisplay *decoDisplay = _displayManager->getCurrentDecorativeDisplay())
{
if (ColliderDetector *detector = decoDisplay->getColliderDetector())
{
return detector->getColliderFilter();
}
}
return NULL;
}
} }

View File

@ -159,6 +159,8 @@ public:
*/ */
virtual cocos2d::Array *getColliderBodyList(); virtual cocos2d::Array *getColliderBodyList();
virtual void setColliderFilter(ColliderFilter *filter);
virtual ColliderFilter *getColliderFilter();
public: public:
/* /*
* The origin state of the Bone. Display's state is effected by _boneData, m_pNode, _tweenData * The origin state of the Bone. Display's state is effected by _boneData, m_pNode, _tweenData

View File

@ -37,13 +37,44 @@ using namespace cocos2d;
namespace cocostudio { namespace cocostudio {
#if ENABLE_PHYSICS_BOX2D_DETECT
ColliderFilter::ColliderFilter(unsigned short categoryBits, unsigned short maskBits, signed short groupIndex)
: _categoryBits(categoryBits)
, _maskBits(maskBits)
, _groupIndex(groupIndex)
{
}
void ColliderFilter::updateShape(b2Fixture *fixture)
{
b2Filter filter;
filter.categoryBits = _categoryBits;
filter.groupIndex = _groupIndex;
filter.maskBits = _maskBits;
fixture->SetFilterData(filter);
}
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
ColliderFilter::ColliderFilter(cpCollisionType collisionType, cpGroup group)
: _collisionType(collisionType)
, _group(group)
{
}
void ColliderFilter::updateShape(cpShape *shape)
{
shape->collision_type = _collisionType;
shape->group = _group;
}
#endif
#if ENABLE_PHYSICS_BOX2D_DETECT #if ENABLE_PHYSICS_BOX2D_DETECT
ColliderBody::ColliderBody(ContourData *contourData) ColliderBody::ColliderBody(ContourData *contourData)
: _fixture(NULL) : _fixture(NULL)
, _filter(NULL)
, _contourData(contourData) , _contourData(contourData)
{ {
CC_SAFE_RETAIN(_contourData); CC_SAFE_RETAIN(_contourData);
_filter = new ColliderFilter();
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
_calculatedVertexList = Array::create(); _calculatedVertexList = Array::create();
@ -57,6 +88,7 @@ ColliderBody::ColliderBody(ContourData *contourData)
, _contourData(contourData) , _contourData(contourData)
{ {
CC_SAFE_RETAIN(_contourData); CC_SAFE_RETAIN(_contourData);
_filter = new ColliderFilter();
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
_calculatedVertexList = Array::create(); _calculatedVertexList = Array::create();
@ -68,14 +100,20 @@ ColliderBody::ColliderBody(ContourData *contourData)
ColliderBody::~ColliderBody() ColliderBody::~ColliderBody()
{ {
CC_SAFE_RELEASE(_contourData); CC_SAFE_RELEASE(_contourData);
CC_SAFE_DELETE(_filter);
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
CC_SAFE_RELEASE(_calculatedVertexList); CC_SAFE_RELEASE(_calculatedVertexList);
#endif #endif
}
#if ENABLE_PHYSICS_BOX2D_DETECT void ColliderBody::setColliderFilter(ColliderFilter *filter)
CC_SAFE_DELETE(_filter); {
#endif *_filter = *filter;
}
ColliderFilter *ColliderBody::getColliderFilter()
{
return _filter;
} }
@ -106,6 +144,7 @@ ColliderDetector *ColliderDetector::create(Bone *bone)
ColliderDetector::ColliderDetector() ColliderDetector::ColliderDetector()
: _colliderBodyList(NULL) : _colliderBodyList(NULL)
, _filter(NULL)
, _active(false) , _active(false)
{ {
_body = NULL; _body = NULL;
@ -115,6 +154,7 @@ ColliderDetector::~ColliderDetector()
{ {
_colliderBodyList->removeAllObjects(); _colliderBodyList->removeAllObjects();
CC_SAFE_DELETE(_colliderBodyList); CC_SAFE_DELETE(_colliderBodyList);
CC_SAFE_DELETE(_filter);
} }
bool ColliderDetector::init() bool ColliderDetector::init()
@ -123,6 +163,8 @@ bool ColliderDetector::init()
CCASSERT(_colliderBodyList, "create _colliderBodyList failed!"); CCASSERT(_colliderBodyList, "create _colliderBodyList failed!");
_colliderBodyList->retain(); _colliderBodyList->retain();
_filter = new ColliderFilter();
return true; return true;
} }
@ -206,9 +248,6 @@ void ColliderDetector::setActive(bool active)
ColliderBody *colliderBody = (ColliderBody *)object; ColliderBody *colliderBody = (ColliderBody *)object;
b2Fixture *fixture = colliderBody->getB2Fixture(); b2Fixture *fixture = colliderBody->getB2Fixture();
b2Filter *filter = colliderBody->getB2Filter();
*filter = fixture->GetFilterData();
_body->DestroyFixture(fixture); _body->DestroyFixture(fixture);
colliderBody->setB2Fixture(NULL); colliderBody->setB2Fixture(NULL);
} }
@ -256,6 +295,34 @@ Array *ColliderDetector::getColliderBodyList()
return _colliderBodyList; return _colliderBodyList;
} }
void ColliderDetector::setColliderFilter(ColliderFilter *filter)
{
*_filter = *filter;
Object *object = NULL;
CCARRAY_FOREACH(_colliderBodyList, object)
{
ColliderBody *colliderBody = (ColliderBody *)object;
colliderBody->setColliderFilter(filter);
#if ENABLE_PHYSICS_BOX2D_DETECT
if (colliderBody->getB2Fixture())
{
colliderBody->getColliderFilter()->updateShape(colliderBody->getB2Fixture());
}
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
if (colliderBody->getShape())
{
colliderBody->getColliderFilter()->updateShape(colliderBody->getShape());
}
#endif
}
}
ColliderFilter *ColliderDetector::getColliderFilter()
{
return _filter;
}
Point helpPoint; Point helpPoint;
@ -378,15 +445,7 @@ void ColliderDetector::setBody(b2Body *pBody)
} }
colliderBody->setB2Fixture(fixture); colliderBody->setB2Fixture(fixture);
if (colliderBody->getB2Filter() == NULL) colliderBody->getColliderFilter()->updateShape(fixture);
{
b2Filter *filter = new b2Filter;
colliderBody->setB2Filter(filter);
}
else
{
fixture->SetFilterData(*colliderBody->getB2Filter());
}
} }
} }
@ -420,9 +479,14 @@ void ColliderDetector::setBody(cpBody *pBody)
shape->sensor = true; shape->sensor = true;
shape->data = _bone; shape->data = _bone;
if (_active)
{
cpSpaceAddShape(_body->space_private, shape); cpSpaceAddShape(_body->space_private, shape);
}
colliderBody->setShape(shape); colliderBody->setShape(shape);
colliderBody->getColliderFilter()->updateShape(shape);
delete []verts; delete []verts;
} }

View File

@ -33,24 +33,48 @@ THE SOFTWARE.
#endif #endif
#if ENABLE_PHYSICS_CHIPMUNK_DETECT
#include "chipmunk.h"
struct cpBody;
struct cpShape;
#elif ENABLE_PHYSICS_BOX2D_DETECT
class b2Body; class b2Body;
class b2Fixture; class b2Fixture;
struct b2Filter; struct b2Filter;
#endif
struct cpBody;
struct cpShape;
namespace cocostudio { namespace cocostudio {
class Bone; class Bone;
class ColliderFilter
{
public:
~ColliderFilter() { }
#if ENABLE_PHYSICS_BOX2D_DETECT
public:
ColliderFilter(unsigned short categoryBits = 0x0001, unsigned short maskBits = 0xFFFF, signed short groupIndex = 0);
void updateShape(b2Fixture *fixture);
protected:
CC_SYNTHESIZE(unsigned short, _categoryBits, CategoryBits);
CC_SYNTHESIZE(unsigned short, _maskBits, MaskBits);
CC_SYNTHESIZE(signed short, _groupIndex, GroupIndex);
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
public:
ColliderFilter(cpCollisionType collisionType = 0, cpGroup group = 0);
void updateShape(cpShape *shape);
protected:
CC_SYNTHESIZE(cpCollisionType, _collisionType, CollisionType);
CC_SYNTHESIZE(cpGroup, _group, Group);
#endif
};
class ColliderBody : public cocos2d::Object class ColliderBody : public cocos2d::Object
{ {
public: public:
#if ENABLE_PHYSICS_BOX2D_DETECT #if ENABLE_PHYSICS_BOX2D_DETECT
CC_SYNTHESIZE(b2Fixture *, _fixture, B2Fixture) CC_SYNTHESIZE(b2Fixture *, _fixture, B2Fixture)
CC_SYNTHESIZE(b2Filter *, _filter, B2Filter)
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT #elif ENABLE_PHYSICS_CHIPMUNK_DETECT
CC_SYNTHESIZE(cpShape *, _shape, Shape) CC_SYNTHESIZE(cpShape *, _shape, Shape)
#endif #endif
@ -59,12 +83,13 @@ public:
ColliderBody(ContourData *contourData); ColliderBody(ContourData *contourData);
~ColliderBody(); ~ColliderBody();
inline ContourData *getContourData() inline ContourData *getContourData() { return _contourData; }
{
return _contourData; void setColliderFilter(ColliderFilter *filter);
} ColliderFilter *getColliderFilter();
private: private:
ContourData *_contourData; ContourData *_contourData;
ColliderFilter *_filter;
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX #if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
CC_SYNTHESIZE_READONLY(CCArray *, _calculatedVertexList, CalculatedVertexList); CC_SYNTHESIZE_READONLY(CCArray *, _calculatedVertexList, CalculatedVertexList);
@ -106,8 +131,12 @@ public:
cocos2d::Array *getColliderBodyList(); cocos2d::Array *getColliderBodyList();
virtual void setColliderFilter(ColliderFilter *filter);
virtual ColliderFilter *getColliderFilter();
protected: protected:
cocos2d::Array *_colliderBodyList; cocos2d::Array *_colliderBodyList;
ColliderFilter *_filter;
CC_SYNTHESIZE(Bone *, _bone, Bone); CC_SYNTHESIZE(Bone *, _bone, Bone);
#if ENABLE_PHYSICS_BOX2D_DETECT #if ENABLE_PHYSICS_BOX2D_DETECT

View File

@ -1008,13 +1008,7 @@ void TestColliderDetector::initWorld()
cpSpaceAddBody(space, body); cpSpaceAddBody(space, body);
armature2->setBody(body); armature2->setBody(body);
shape = armature2->getShapeList(); armature2->setColliderFilter(&ColliderFilter(eEnemyTag));
while(shape)
{
cpShape *next = shape->next_private;
shape->collision_type = eEnemyTag;
shape = next;
}
cpSpaceAddCollisionHandler(space, eEnemyTag, eBulletTag, beginHit, NULL, NULL, endHit, NULL); cpSpaceAddCollisionHandler(space, eEnemyTag, eBulletTag, beginHit, NULL, NULL, endHit, NULL);
} }