玩转cocos2d-x(二)支持PhysicsEditor

来源:互联网 发布:科比各项数据排名 编辑:程序博客网 时间:2024/04/30 11:39

PhysicsEditor 是一个针对2D物理引擎的碰撞外形描点工具。(关于这个描述,听起来比较拗口,具体的可以参考官网)

这个工具是收费的,可支持windows,mac osx。同类的工具免费的有VertexHelper。

可从github上clone,通过xcode  build后将product目录下的app文件拖到Application目录安装使用。

github地址:https://github.com/jfahrenkrug/VertexHelper.git

相比较来说PhysicsEditor有几个优点:

1、支持windows平台

2、可到处plist文件,在构建shape的时候减少人肉复制顶点坐标的时间,提升效率;同时保证代码的整洁。

3、官网提供了对cocos2d-x的支持 PyhsicsEditor对cocos2d-x的官方支持

但悲催的是官网的支持使用的是cocos2d-x 1.x版本的,而现在cocos2d-x已更新到2.x了,已有很多接口变动了。

具体可以看cocos2d-x 官网wiki http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Cocos2d-x_v20_migration_guide

针对cocos2d-x 2.x版本的接口改动,对PhysicsEditor的官方支持做了一些修改:

1、将类名前缀修改为CC

2、将1.x版本的CCDictionary,CCMutableArray 的接口调整为 2.x的CCDictionary,CCArray的接口

3、更新CCFileUtils的接口使用

4、调整原来的添加bodyDef到 map中的代码位置调整(减少不必要的循环操作)

下面贴出源码:

////  CCShapeCache.h//#ifndef __CCSHAPECACHE_H__#define __CCSHAPECACHE_H__#include "cocos2d.h"USING_NS_CC;class BodyDef;class b2Body;namespace cocos2d {class CCShapeCache : public CCObject{public:// Static interfacestatic CCShapeCache* sharedShapeCache(void);public:        bool init();        void addShapesWithFile(const std::string &plist);        void addFixturesToBody(b2Body *body, const std::string &shape);        cocos2d::CCPoint anchorPointForShape(const std::string &shape);        void reset();        float getPtmRatio() { return ptmRatio; }        ~CCShapeCache() {}private:std::map<std::string, BodyDef *> shapeObjects;        CCShapeCache(void) {}        float ptmRatio;};}#endif /* defined(__CCSHAPECACHE_H__) */

////  CCShapeCache.cpp////#include "CCShapeCache.h"#include "Box2D.h"#include "CCNS.h"class FixtureDef {public:    FixtureDef()    : next(NULL) {}        ~FixtureDef() {        delete next;        delete fixture.shape;    }        FixtureDef *next;    b2FixtureDef fixture;    int callbackData;};class BodyDef {public:BodyDef(): fixtures(NULL) {}~BodyDef() {if (fixtures)delete fixtures;}FixtureDef *fixtures;CCPoint anchorPoint;};static CCShapeCache *_sharedShapeCache = NULL;CCShapeCache* CCShapeCache::sharedShapeCache(void) {if (!_sharedShapeCache) {_sharedShapeCache = new CCShapeCache();        _sharedShapeCache->init();}return _sharedShapeCache;}bool CCShapeCache::init() {return true;}void CCShapeCache::reset() {std::map<std::string, BodyDef *>::iterator iter;for (iter = shapeObjects.begin() ; iter != shapeObjects.end() ; ++iter) {delete iter->second;}shapeObjects.clear();}void CCShapeCache::addFixturesToBody(b2Body *body, const std::string &shape) {std::map<std::string, BodyDef *>::iterator pos = shapeObjects.find(shape);assert(pos != shapeObjects.end());BodyDef *so = (*pos).second;    FixtureDef *fix = so->fixtures;    while (fix) {        body->CreateFixture(&fix->fixture);        fix = fix->next;    }}cocos2d::CCPoint CCShapeCache::anchorPointForShape(const std::string &shape) {std::map<std::string, BodyDef *>::iterator pos = shapeObjects.find(shape);assert(pos != shapeObjects.end());BodyDef *bd = (*pos).second;return bd->anchorPoint;}void CCShapeCache::addShapesWithFile(const std::string &plist){    const char* fullName = CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(plist.c_str());    CCDictionary* dict = CCDictionary::createWithContentsOfFile(fullName);        CCAssert(dict != NULL, "Shape-file not found"); // not triggered - cocos2dx delivers empty dict if non was found    CCAssert(dict->count() != 0, "plist file empty or not existing");        CCDictionary* metadataDict = (CCDictionary*)dict->objectForKey("metadata");    int format = metadataDict->valueForKey("format")->intValue();    ptmRatio = metadataDict->valueForKey("ptm_ratio")->floatValue();    CCAssert(format == 1, "Format not supported");        CCDictionary* bodyDict = (CCDictionary*)dict->objectForKey("bodies");    b2Vec2 vertices[b2_maxPolygonVertices];    CCLog("bodydict count %d ",bodyDict->count());        CCDictElement* pElement = NULL;    CCDICT_FOREACH(bodyDict, pElement)    {        CCDictionary* bodyData = (CCDictionary*)pElement->getObject();        CCLog("body key %s -> bodyData count %d",pElement->getStrKey(),bodyData->count());        BodyDef* bodyDef = new BodyDef();        shapeObjects[pElement->getStrKey()] = bodyDef;                CCLog("anchorpoint %s",bodyData->valueForKey("anchorpoint")->getCString());        bodyDef->anchorPoint = CCPointFromString(bodyData->valueForKey("anchorpoint")->getCString());                CCArray* fixtureList = (CCArray*)(bodyData->objectForKey("fixtures"));        FixtureDef **nextFixtureDef = &(bodyDef->fixtures);                CCObject* pObj = NULL;        CCARRAY_FOREACH(fixtureList, pObj)        {            b2FixtureDef basicData;            CCDictionary* fixtureData = (CCDictionary*)pObj;                        basicData.filter.categoryBits = fixtureData->valueForKey("filter_categoryBits")->intValue();            basicData.filter.maskBits = fixtureData->valueForKey("filter_maskBits")->intValue();            basicData.filter.groupIndex = fixtureData->valueForKey("filter_groupIndex")->intValue();            basicData.friction = fixtureData->valueForKey("friction")->floatValue();            basicData.density = fixtureData->valueForKey("density")->floatValue();            basicData.restitution = fixtureData->valueForKey("restitution")->floatValue();            basicData.isSensor = fixtureData->valueForKey("isSensor")->boolValue();                        int cb = fixtureData->valueForKey("userdataCbValue")->intValue();                        int callbackData = cb ? cb : 0;            std::string fixtureType = fixtureData->valueForKey("fixture_type")->m_sString;            if(fixtureType == "POLYGON")            {                CCArray* polygonsArray = (CCArray*)fixtureData->objectForKey("polygons");                CCObject* pObject;                CCARRAY_FOREACH(polygonsArray, pObject)                {                    FixtureDef *fix = new FixtureDef();                    fix->fixture = basicData; // copy basic data                    fix->callbackData = callbackData;                                        b2PolygonShape *polyshape = new b2PolygonShape();                    int vindex = 0;                                        CCArray* polygonArray = (CCArray*)pObject;                    assert(polygonsArray->count() <= b2_maxPolygonVertices);                                        CCObject* pPointObject;                    CCARRAY_FOREACH(polygonArray, pPointObject)                    {                        CCString* pointStr = (CCString*)pPointObject;                        CCPoint offset = CCPointFromString(pointStr->getCString());                        vertices[vindex].x = (offset.x / ptmRatio) ;                        vertices[vindex].y = (offset.y / ptmRatio) ;                        vindex++;                    }                                    polyshape->Set(vertices, vindex);                    fix->fixture.shape = polyshape;                    // create a list                    *nextFixtureDef = fix;                    nextFixtureDef = &(fix->next);                }            }            else if(fixtureType=="CIRCLE")            {                FixtureDef *fix = new FixtureDef();                fix->fixture = basicData; // copy basic data                fix->callbackData = callbackData;                                CCDictionary *circleData = (CCDictionary *)fixtureData->objectForKey("circle");                b2CircleShape *circleShape = new b2CircleShape();                                circleShape->m_radius = circleData->valueForKey("radius")->floatValue() / ptmRatio;CCPoint p = CCPointFromString(circleData->valueForKey("position")->getCString());                circleShape->m_p = b2Vec2(p.x / ptmRatio, p.y / ptmRatio);                fix->fixture.shape = circleShape;                // create a list                *nextFixtureDef = fix;                nextFixtureDef = &(fix->next);            }            else            {                CCAssert(0, "Unknown fixtureType");            }        }    }}


原创粉丝点击