首页 > 代码库 > 使用Physics_Body_Editor获得json文件的类

使用Physics_Body_Editor获得json文件的类

 【转自】:http://www.cocoachina.com/bbs/read.php?tid=209290 

 

 工具介绍,json文件获得方法,请参考原帖

 

 MyBodyParser.h

 1 // 2 //  MyBodyParser.h 3 // 4 //  Created by Jason Xu. 5 // 6 // 7  8 #pragma once 9 10 #include <string>11 #include "cocos2d.h"12 USING_NS_CC;13 #include "json/document.h"14 15 class MyBodyParser {16     MyBodyParser(){}17     rapidjson::Document doc;18 public:19     static MyBodyParser* getInstance();20     bool parseJsonFile(const std::string& pFile);21     bool parse(unsigned char* buffer, long length);22     void clearCache();23     PhysicsBody* bodyFormJson(Node* pNode, const std::string& name);24 };

 MyBodyParser.cpp

 

 1 // 2 //  MyBodyParser.cpp 3 // 4 //  Created by Jason Xu. 5 // 6 // 7  8 #include "MyBodyParser.h" 9 10 MyBodyParser* MyBodyParser::getInstance()11 {12     static MyBodyParser* sg_ptr = nullptr;13     if (nullptr == sg_ptr)14     {15         sg_ptr = new MyBodyParser;16     }17     return sg_ptr;18 }19 20 bool MyBodyParser::parse(unsigned char *buffer, long length)21 {22     bool result = false;23     std::string js((const char*)buffer, length);24     doc.Parse<0>(js.c_str());25     if(!doc.HasParseError())26     {27         result = true;28     }29     return result;30 }31 32 void MyBodyParser::clearCache()33 {34     doc.SetNull();35 }36 37 bool MyBodyParser::parseJsonFile(const std::string& pFile)38 {39     auto content = FileUtils::getInstance()->getDataFromFile(pFile);40     bool result = parse(content.getBytes(), content.getSize());41     return result;42 }43 44 //从json文件加载正确的body45 PhysicsBody* MyBodyParser::bodyFormJson(cocos2d::Node *pNode, const std::string& name)46 {47     PhysicsBody* body = nullptr;48     rapidjson::Value &bodies = doc["rigidBodies"];49     if (bodies.IsArray())50     {51         //遍历文件中的所有body52         for (int i=0; i<bodies.Size(); ++i)53         {54             //找到了请求的那一个55             if (0 == strcmp(name.c_str(), bodies[i]["name"].GetString()))56             {57                 rapidjson::Value &bd = bodies[i];58                 if (bd.IsObject())59                 {60                     //创建一个PhysicsBody, 并且根据node的大小来设置61                     body = PhysicsBody::create();62                     float width = pNode->getContentSize().width;63                     float offx = - pNode->getAnchorPoint().x*pNode->getContentSize().width;64                     float offy = - pNode->getAnchorPoint().y*pNode->getContentSize().height;65 66                     Point origin( bd["origin"]["x"].GetDouble(), bd["origin"]["y"].GetDouble());67                     rapidjson::Value &polygons = bd["polygons"];68                     for (int i = 0; i<polygons.Size(); ++i)69                     {70                         int pcount = polygons[i].Size();71                         Point* points = new Point[pcount];72                         for (int pi = 0; pi<pcount; ++pi)73                         {74                             points[pi].x = offx + width * polygons[i][pcount-1-pi]["x"].GetDouble();75                             points[pi].y = offy + width * polygons[i][pcount-1-pi]["y"].GetDouble();76                         }77                         body->addShape(PhysicsShapePolygon::create(points, pcount, PHYSICSBODY_MATERIAL_DEFAULT));78                         delete [] points;79                     }80                 }81                 else82                 {83                     CCLOG("body: %s not found!", name.c_str());84                 }85                 break;86             }87         }88     }89     return body;90 }

 HelloWorldScene.cpp (测试cpp)

  1 #include "HelloWorldScene.h"  2 #include "MyBodyParser.h"  3 USING_NS_CC;  4   5 Scene* HelloWorld::createScene()  6 {  7     // ‘scene‘ is an autorelease object  8     auto scene = Scene::createWithPhysics();  9  10     //enable debug draw 11     scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); 12  13     // ‘layer‘ is an autorelease object 14     auto layer = HelloWorld::create(); 15  16     // add layer as a child to scene 17     scene->addChild(layer); 18  19     // return the scene 20     return scene; 21 } 22  23 // on "init" you need to initialize your instance 24 bool HelloWorld::init() 25 { 26     ////////////////////////////// 27     // 1. super init first 28     if ( !Layer::init() ) 29     { 30         return false; 31     } 32      33     Size visibleSize = Director::getInstance()->getVisibleSize(); 34     Point origin = Director::getInstance()->getVisibleOrigin(); 35  36     ///////////////////////////// 37     // 2. add a menu item with "X" image, which is clicked to quit the program 38     //    you may modify it. 39  40     // add a "close" icon to exit the progress. it‘s an autorelease object 41     auto closeItem = MenuItemImage::create( 42                                            "CloseNormal.png", 43                                            "CloseSelected.png", 44                                            CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); 45      46     closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , 47                                 origin.y + closeItem->getContentSize().height/2)); 48  49     // create menu, it‘s an autorelease object 50     auto menu = Menu::create(closeItem, NULL); 51     menu->setPosition(Point::ZERO); 52     this->addChild(menu, 1); 53  54     ///////////////////////////// 55     // 3. add your codes below... 56  57     // add a label shows "Hello World" 58     // create and initialize a label 59      60     auto label = LabelTTF::create("Physics Body Loader Demo", "Arial", 24); 61      62     // position the label on the center of the screen 63     label->setPosition(Point(origin.x + visibleSize.width/2, 64                             origin.y + visibleSize.height - label->getContentSize().height)); 65  66     // add the label as a child to this layer 67     this->addChild(label, 1); 68  69     status_label = LabelTTF::create("Touch anywhere!", "Arial", 36); 70     status_label->setPosition(Point(origin.x + visibleSize.width/2, 1.2*status_label->getContentSize().height)); 71     this->addChild(status_label); 72  73     // add "2dx.png" 74     sp_2dx = Sprite::create("2dx.png"); 75  76     // position the sprite on the center of the screen 77     sp_2dx->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); 78  79     //load 80     MyBodyParser::getInstance()->parseJsonFile("bodies.json"); 81  82     //bind physicsbody to sprite 83     auto _body = MyBodyParser::getInstance()->bodyFormJson(sp_2dx, "2dx"); 84     if (_body != nullptr) { 85         _body->setDynamic(false); //set it static body. 86         _body->setCollisionBitmask(0x000000); //don‘t collision with anybody. 87         sp_2dx->setPhysicsBody(_body); 88     } 89  90     // add the sprite as a child to this layer 91     this->addChild(sp_2dx, 0); 92  93     //add touchListener 94     auto touchListener = EventListenerTouchOneByOne::create(); 95     touchListener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); 96     touchListener->onTouchMoved = CC_CALLBACK_2(HelloWorld::onTouchMoved, this); 97     touchListener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this); 98     _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this); 99 100     return true;101 }102 103 Node* HelloWorld::nodeUnderTouch(cocos2d::Touch *touch)104 {105     Node* node = nullptr;106     //转换到layer内的坐标107     auto location = this->convertTouchToNodeSpace(touch);108     //得到当前点下方的物理shapes109     auto scene = Director::getInstance()->getRunningScene();110     auto arr = scene->getPhysicsWorld()->getShapes(location);111 112     //遍历当前点击到的所有shapes, 看看有没有我们的2dx!113     for (auto& obj : arr)114     {115         //find it116         if ( obj->getBody()->getNode() == sp_2dx)117         {118             node = obj->getBody()->getNode();119             break;120         }121     }122     return node;123 }124 125 bool HelloWorld::onTouchBegan(Touch* touch, Event* event)126 {127     auto current_node = nodeUnderTouch(touch);128 129     //get it!130     if (current_node == sp_2dx)131     {132         status_label->setColor(Color3B::GREEN);133         status_label->setString("Ohoo, U catch me!");134     }135     else136     {137         status_label->setColor(Color3B::RED);138         status_label->setString("Haha, touch outside!");139     }140 141     return true;142 }143 144 void HelloWorld::onTouchMoved(Touch* touch, Event* event)145 {146 }147 148 void HelloWorld::onTouchEnded(Touch* touch, Event* event)149 {150     status_label->setColor(Color3B::WHITE);151     status_label->setString("Touch anywhere!");152 }153 154 void HelloWorld::menuCloseCallback(Ref* pSender)155 {156 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)157     MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");158     return;159 #endif160 161     Director::getInstance()->end();162 163 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)164     exit(0);165 #endif166 }