VertexHelper工具,另一个是windows系统下使用的PhysicsEditor工具,我们这里就来讲讲PhysicsEditor工具导出的pList文件在Cococs2d-x中的使用方法。
注意:目前最新版本的PhysicsEditor工具的安装目录下面的Demo里面的GB2ShapeCache-x解析类已经不支持Cocos2d-x 2.x版本,但是我们可以在它原来的基础上进行修改,修改后的GB2ShapeCache-x解析类经过测试,对Cocos2d-x 2.x已经全部支持。下面给出修改后的GB2ShapeCache-x解析类文件:
#ifndef GB2ShapeCache_x_h#define GB2ShapeCache_x_h #include "cocos2d.h"#include <map>class BodyDef;class b2Body;NS_CC_BEGINclass GB2ShapeCache {public: static GB2ShapeCache* sharedGB2ShapeCache(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; } ~GB2ShapeCache() {} private: std::map<std::string,BodyDef *> shapeObjects; GB2ShapeCache(voID) {} float ptmRatio;};NS_CC_END#endif
#include "GB2ShapeCache-x.h"#include "Box2D/Box2D.h"#include "cocoa/CCNS.h"using namespace cocos2d;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 GB2ShapeCache *_sharedGB2ShapeCache = NulL;GB2ShapeCache* GB2ShapeCache::sharedGB2ShapeCache(voID){ if (!_sharedGB2ShapeCache) { _sharedGB2ShapeCache = new GB2ShapeCache(); _sharedGB2ShapeCache->init(); } return _sharedGB2ShapeCache;}bool GB2ShapeCache::init(){ return true;}voID GB2ShapeCache::reset(){ std::map<std::string,BodyDef *>::iterator iter; for (iter = shapeObjects.begin(); iter != shapeObjects.end(); ++iter) { delete iter->second; } shapeObjects.clear();}voID GB2ShapeCache::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 GB2ShapeCache::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;}typedef CCDictionary ObjectDict;voID GB2ShapeCache::addShapesWithfile(const std::string &pList){ string fullname = CCfileUtils::sharedfileUtils()->fullPathForfilename(pList.c_str()); CCDictionary* dict = CCDictionary::createWithContentsOffile(fullname.c_str()); cclOG(fullname.c_str()); 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; CCObject* pObject; CCAssert(polygonsArray->count(),"polygonsArray = 0!"); CCARRAY_FOREACH(polygonArray,pObject) { CCPoint offset = CCPointFromString(((CCString *)pObject)->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"); } } }}
针对PhysicsEditor工具的使用,很简单,可以自己查找资料,这里就不再累述,我们把导出来的pList文件拷贝到Resource目录下就可以了,下面给出使用代码:
#ifndef __HELLO_WORLD_H__#define __HELLO_WORLD_H__#include "cocos2d.h"#include "cocos-ext.h"#include "Box2D/Box2D.h"USING_NS_CC;USING_NS_CC_EXT;class HelloWorld : public cocos2d::cclayer {public: HelloWorld(); virtual ~HelloWorld(); static cocos2d::CCScene* scene(); virtual voID onEnter(); virtual voID onExit(); virtual bool cctouchBegan(CCtouch *ptouch,CCEvent *pEvent); virtual voID cctouchended(CCtouch *ptouch,CCEvent *pEvent); virtual bool init(); virtual voID update(float dt); CREATE_FUNC(HelloWorld);private: b2World* world;private: voID addNewSpriteWithCoords(cocos2d::CCPoint p);};#endif
//// HelloWorldScene.cpp// Demo//// Created by Andreas L枚w on 11.01.12.// copyright codeanDWeb.de 2012. All rights reserved.//#include "HelloWorldScene.h"#include "SimpleAudioEngine.h"#include "GB2ShapeCache-x.h"#define PTM_RATIO 30HelloWorld::HelloWorld(){}HelloWorld::~HelloWorld(){ if (world) { delete world; world = NulL; }}bool HelloWorld::init(){ if (!cclayer::init()) { return false; } // 载入物理形状 GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithfile("Box2D.pList"); // 开启多点触控 //this->settouchEnabled(true); // 开启重力加速 //this->setAccelerometerEnabled(true); CCSize winSize = CCDirector::sharedDirector()->getWinSize(); // 定义重力方向 b2Vec2 gravity; gravity.Set(0.0f,-10.0f); // 刚体是否睡眠 bool doSleep = true; bool continuous = true; world = new b2World(gravity); world->SetAllowSleePing(doSleep); world->SetContinuousPhysics(continuous); b2BodyDef groundBodyDef; groundBodyDef.position.Set(winSize.wIDth / 2 / PTM_RATIO,winSize.height / 2 / PTM_RATIO); b2Body* groundBody = world->CreateBody(&groundBodyDef); // 定义一个地面盒形状 b2polygonShape groundBox; groundBox.SetAsBox(winSize.wIDth / 2 / PTM_RATIO,b2Vec2(0,-winSize.height / 2 / PTM_RATIO),0); b2FixtureDef fixtureDef; fixtureDef.shape = &groundBox; fixtureDef.density = 1; //密度 fixtureDef.friction = 0.5f; //摩擦因数 fixtureDef.restitution = 0.4f; //d性因数 // 底部 groundBody->CreateFixture(&fixtureDef); // 顶部 groundBox.SetAsBox(winSize.wIDth / 2 / PTM_RATIO,winSize.height / 2 / PTM_RATIO),0); groundBody->CreateFixture(&groundBox,0); // 左边 groundBox.SetAsBox(0,winSize.height / 2 / PTM_RATIO,b2Vec2(-winSize.wIDth / 2 / PTM_RATIO,0),0); // 右边 groundBox.SetAsBox(0,b2Vec2(winSize.wIDth / 2 / PTM_RATIO,0); // 设置精灵 cclabelTTF *label = cclabelTTF::create("屏幕顶端","Arial",32); this->addChild(label,0); label->setcolor(ccc3(0,255)); label->setposition(CCPointMake(winSize.wIDth / 2,winSize.height - 50)); this->addNewSpriteWithCoords(CCPointMake(winSize.wIDth / 2,winSize.height / 2)); this->scheduleUpdate(); return true;}string names[] = { "BoxA" /*"hotdog","drink","icecream","icecream2","icecream3","hamburger","orange"*/};voID HelloWorld::addNewSpriteWithCoords(CCPoint p){ string name = names[0];//names[rand() % 7]; cclOG("name:%s",name.c_str()); CCSprite *sprite = CCSprite::create((name + ".png").c_str()); sprite->setposition(p); this->addChild(sprite); b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(p.x / PTM_RATIO,p.y / PTM_RATIO); bodyDef.userData = sprite; b2Body *body = world->CreateBody(&bodyDef); // 刚体添加夹具 GB2ShapeCache::sharedGB2ShapeCache()->addFixturesToBody(body,name.c_str()); sprite->setAnchorPoint(GB2ShapeCache::sharedGB2ShapeCache()->anchorPointForShape(name.c_str()));}voID HelloWorld::update(float dt){ int veLocityIterations = 8; int positionIterations = 3; world->Step(dt,veLocityIterations,positionIterations); for (b2Body* b = world->GetbodyList(); b; b = b->GetNext()) { if (b->GetUserData() != NulL) { CCSprite* myActor = (CCSprite*)b->GetUserData(); myActor->setposition(CCPointMake(b->Getposition().x * PTM_RATIO,b->Getposition().y * PTM_RATIO)); myActor->setRotation(-1 * CC_radians_TO_degrees(b->GetAngle())); } }}voID HelloWorld::onEnter(){ CCDirector::sharedDirector()->gettouchdispatcher()->addTargetedDelegate(this,-128,true); cclayer::onEnter();}voID HelloWorld::onExit(){ CCDirector::sharedDirector()->gettouchdispatcher()->removeDelegate(this); cclayer::onExit();}bool HelloWorld::cctouchBegan(CCtouch *ptouch,CCEvent *pEvent){ return true;}voID HelloWorld::cctouchended(CCtouch *ptouch,CCEvent *pEvent){ CCPoint pt = ptouch->getLocation(); this->addNewSpriteWithCoords(pt);}//voID HelloWorld::cctouchesBegan(CCSet *ptouches,CCEvent *pEvent)//{// cclOG("HelloWorld::cctouchesBegan");// CCSetIterator it;// CCtouch *touch;//// for (it = ptouches->begin(); it != ptouches->end(); it++)// {// touch = (CCtouch*)(*it);//// if (!touch)// break;//// CCPoint location = touch->getLocation();// this->addNewSpriteWithCoords(location);// }//}CCScene* HelloWorld::scene(){ CCScene *scene = CCScene::create(); HelloWorld *layer = HelloWorld::create(); scene->addChild(layer); return scene;}总结
以上是内存溢出为你收集整理的Cocos2d-x_Box2D刚体使用PhysicsEditor工具生成形状全部内容,希望文章能够帮你解决Cocos2d-x_Box2D刚体使用PhysicsEditor工具生成形状所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)