PhysicsEditor是一款box2d形状生成器,只需点点鼠标即可生成plist图形文件,还有很有特色的魔术棒工具,可自动完成标记定点和分隔polygon的过程。可以直接在cocos2dx中使用。
如图所示:可以对边缘进行不规则图形的选取
官方提供了Cocos2dx的第三方库,但是采用的是2.x的接口,3.x下面依然是可以使用的,不过在这添加了采用3.x接口封装的方法
void GB2ShapeCache::addShapesWithV3(const std::string &plist) {
//const char *fullName = CCFileUtils::sharedFileUtils()->fullPathForFilename(plist.c_str()).c_str();
auto dict = FileUtils::getInstance()->getValueMapFromFile(plist);
//基础属性
auto metadataDict = dict["metadata"].asValueMap();
auto format = metadataDict["format"].asInt();
ptmRatio = metadataDict["ptm_ratio"].asFloat();
//body属性]
b2Vec2 vertices[b2_maxPolygonVertices];
std::string bodyName;
auto bodyDict = dict["bodies"].asValueMap();
for (auto obj : bodyDict) {
bodyName = obj.first;
auto bodyData = bodyDict[bodyName].asValueMap();
BodyDef *bodyDef = new BodyDef();
bodyDef->anchorPoint = PointFromString(bodyData["anchorpoint"].asString());
auto fixtureList = bodyData["fixtures"].asValueVector();
FixtureDef **nextFixtureDef = &(bodyDef->fixtures);
for (auto fixture : fixtureList) {
b2FixtureDef basicData;
ValueMap vecmap = fixture.asValueMap();
basicData.density = vecmap["density"].asFloat();
basicData.friction = vecmap["friction"].asFloat();
basicData.restitution = vecmap["restitution"].asFloat();
basicData.filter.categoryBits = vecmap["filter_categoryBits"].asInt();
basicData.filter.groupIndex = vecmap["filter_groupIndex"].asInt();
basicData.filter.maskBits = vecmap["filter_maskBits"].asFloat();
basicData.isSensor = vecmap["isSensor"].asBool();
std::string cb = vecmap["userdataCbValue"].asString();
int callbackData = 0;
if (cb.compare("") == 0) {
callbackData = std::atoi(cb.c_str());
}
std::string fixtureType = vecmap["fixture_type"].asString();
if (fixtureType == "POLYGON") {
auto vec2Aarry = vecmap["polygons"].asValueVector();
for (auto vec : vec2Aarry) {
FixtureDef *fix = new FixtureDef();
fix->fixture = basicData; // copy basic data
fix->callbackData = callbackData;
b2PolygonShape *polyshape = new b2PolygonShape();
int vindex = 0;
auto posArray = vec.asValueVector();
for (auto pos : posArray) {
Vec2 offset = PointFromString(pos.asString());
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;
auto circleData = vecmap["circle"].asValueMap();
b2CircleShape *circleShape = new b2CircleShape();
circleShape->m_radius = circleData["radius"].asFloat() / ptmRatio;
Vec2 p = PointFromString(circleData["position"].asString());
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");
}
}
// add the body element to the hash
shapeObjects[bodyName] = bodyDef;
}
1、使用方法
// Load shapes,传入PE工具生产的plist文件,一个具有不规则形状的物理碰撞就实现了
GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithV3("sharp.plist");
2、下载地址