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;
}
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
b2Body *Armature::getBody()
{

View File

@ -175,6 +175,8 @@ public:
virtual cocos2d::TextureAtlas *getTexureAtlasWithTexture(cocos2d::Texture2D *texture);
virtual void setColliderFilter(ColliderFilter *filter);
#if ENABLE_PHYSICS_BOX2D_DETECT
virtual b2Fixture *getShapeList();
#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 void setColliderFilter(ColliderFilter *filter);
virtual ColliderFilter *getColliderFilter();
public:
/*
* 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 {
#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
ColliderBody::ColliderBody(ContourData *contourData)
: _fixture(NULL)
, _filter(NULL)
, _contourData(contourData)
{
CC_SAFE_RETAIN(_contourData);
_filter = new ColliderFilter();
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
_calculatedVertexList = Array::create();
@ -57,6 +88,7 @@ ColliderBody::ColliderBody(ContourData *contourData)
, _contourData(contourData)
{
CC_SAFE_RETAIN(_contourData);
_filter = new ColliderFilter();
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
_calculatedVertexList = Array::create();
@ -68,14 +100,20 @@ ColliderBody::ColliderBody(ContourData *contourData)
ColliderBody::~ColliderBody()
{
CC_SAFE_RELEASE(_contourData);
CC_SAFE_DELETE(_filter);
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
CC_SAFE_RELEASE(_calculatedVertexList);
#endif
}
#if ENABLE_PHYSICS_BOX2D_DETECT
CC_SAFE_DELETE(_filter);
#endif
void ColliderBody::setColliderFilter(ColliderFilter *filter)
{
*_filter = *filter;
}
ColliderFilter *ColliderBody::getColliderFilter()
{
return _filter;
}
@ -106,6 +144,7 @@ ColliderDetector *ColliderDetector::create(Bone *bone)
ColliderDetector::ColliderDetector()
: _colliderBodyList(NULL)
, _filter(NULL)
, _active(false)
{
_body = NULL;
@ -115,6 +154,7 @@ ColliderDetector::~ColliderDetector()
{
_colliderBodyList->removeAllObjects();
CC_SAFE_DELETE(_colliderBodyList);
CC_SAFE_DELETE(_filter);
}
bool ColliderDetector::init()
@ -123,6 +163,8 @@ bool ColliderDetector::init()
CCASSERT(_colliderBodyList, "create _colliderBodyList failed!");
_colliderBodyList->retain();
_filter = new ColliderFilter();
return true;
}
@ -206,9 +248,6 @@ void ColliderDetector::setActive(bool active)
ColliderBody *colliderBody = (ColliderBody *)object;
b2Fixture *fixture = colliderBody->getB2Fixture();
b2Filter *filter = colliderBody->getB2Filter();
*filter = fixture->GetFilterData();
_body->DestroyFixture(fixture);
colliderBody->setB2Fixture(NULL);
}
@ -256,6 +295,34 @@ Array *ColliderDetector::getColliderBodyList()
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;
@ -378,15 +445,7 @@ void ColliderDetector::setBody(b2Body *pBody)
}
colliderBody->setB2Fixture(fixture);
if (colliderBody->getB2Filter() == NULL)
{
b2Filter *filter = new b2Filter;
colliderBody->setB2Filter(filter);
}
else
{
fixture->SetFilterData(*colliderBody->getB2Filter());
}
colliderBody->getColliderFilter()->updateShape(fixture);
}
}
@ -420,9 +479,14 @@ void ColliderDetector::setBody(cpBody *pBody)
shape->sensor = true;
shape->data = _bone;
if (_active)
{
cpSpaceAddShape(_body->space_private, shape);
}
colliderBody->setShape(shape);
colliderBody->getColliderFilter()->updateShape(shape);
delete []verts;
}

View File

@ -33,24 +33,48 @@ THE SOFTWARE.
#endif
#if ENABLE_PHYSICS_CHIPMUNK_DETECT
#include "chipmunk.h"
struct cpBody;
struct cpShape;
#elif ENABLE_PHYSICS_BOX2D_DETECT
class b2Body;
class b2Fixture;
struct b2Filter;
struct cpBody;
struct cpShape;
#endif
namespace cocostudio {
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
{
public:
#if ENABLE_PHYSICS_BOX2D_DETECT
CC_SYNTHESIZE(b2Fixture *, _fixture, B2Fixture)
CC_SYNTHESIZE(b2Filter *, _filter, B2Filter)
#elif ENABLE_PHYSICS_CHIPMUNK_DETECT
CC_SYNTHESIZE(cpShape *, _shape, Shape)
#endif
@ -59,12 +83,13 @@ public:
ColliderBody(ContourData *contourData);
~ColliderBody();
inline ContourData *getContourData()
{
return _contourData;
}
inline ContourData *getContourData() { return _contourData; }
void setColliderFilter(ColliderFilter *filter);
ColliderFilter *getColliderFilter();
private:
ContourData *_contourData;
ColliderFilter *_filter;
#if ENABLE_PHYSICS_SAVE_CALCULATED_VERTEX
CC_SYNTHESIZE_READONLY(CCArray *, _calculatedVertexList, CalculatedVertexList);
@ -106,8 +131,12 @@ public:
cocos2d::Array *getColliderBodyList();
virtual void setColliderFilter(ColliderFilter *filter);
virtual ColliderFilter *getColliderFilter();
protected:
cocos2d::Array *_colliderBodyList;
ColliderFilter *_filter;
CC_SYNTHESIZE(Bone *, _bone, Bone);
#if ENABLE_PHYSICS_BOX2D_DETECT

View File

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