使用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文件加载正确的body

45 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         //遍历文件中的所有body

52         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                 else

82                 {

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     //得到当前点下方的物理shapes

109     auto scene = Director::getInstance()->getRunningScene();

110     auto arr = scene->getPhysicsWorld()->getShapes(location);

111 

112     //遍历当前点击到的所有shapes, 看看有没有我们的2dx!

113     for (auto& obj : arr)

114     {

115         //find it

116         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     else

136     {

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 #endif

160 

161     Director::getInstance()->end();

162 

163 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

164     exit(0);

165 #endif

166 }

 

 

你可能感兴趣的:(editor)