创建一个空工程
/create_project.py -project phyTest -package cn.sollyu.phytest -language cpp
复制我的上一篇文章代码,分别保存下来。(支持Cocos2d-x 2.0以上)
讲代码添加到你的工程里
使用PhysicsEdit创建一个plist文件。
将plist导入你的工程中
修改代码如下.h
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "Box2D/Box2D.h" #include "PhysicsEditor/GB2ShapeCache-x.h" class HelloWorld : public cocos2d::CCLayer { private: b2World* world; b2Body *body; cocos2d::CCSprite * pTest; bool MyTouchState; public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); #pragma mark - overview function virtual void tick(float dt); virtual void didAccelerate(cocos2d::CCAcceleration* pAccelerationValue); virtual void draw(); virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); virtual void ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent); #pragma mark - custom function void addNewSpriteWithCoords(cocos2d::CCSprite* pSprite, std::string szName); #pragma mark - key event // a selector callback void menuCloseCallback(CCObject* pSender); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); }; #endif // __HELLOWORLD_SCENE_H__
cpp文件
#include "HelloWorldScene.h" USING_NS_CC; CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize screenSize = CCDirector::sharedDirector()->getWinSize(); this->setTouchEnabled( true ); this->setAccelerometerEnabled(true); // Load pic CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("plist/background.plist", "plist/background.png"); CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("plist/Role1.plist", "plist/Role1.png"); // load box2d GB2ShapeCache::sharedGB2ShapeCache()->addShapesWithFile("Physics/test.plist"); // add a "close" icon to exit the progress. it's an autorelease object CCMenu* pMenu = CCMenu::create(); CCMenuItemImage *pCloseItem = CCMenuItemImage::create("CloseNormal.png","CloseSelected.png",this,menu_selector(HelloWorld::menuCloseCallback)); pCloseItem->setPosition(ccp(screenSize.width - pCloseItem->getContentSize().width/2 , pCloseItem->getContentSize().height/2)); pMenu->setPosition(CCPointZero); pMenu->addChild(pCloseItem); this->addChild(pMenu, 1); const char* szFileName = "角色1_04.png"; pTest = CCSprite::createWithSpriteFrameName(szFileName); pTest->setPosition(ccp(screenSize.width/2 , screenSize.height/2)); this->addChild(pTest,1); CCSprite* pSprite = CCSprite::createWithSpriteFrameName("BirdTaleBackground-hd_r1_c2_s1.png"); pSprite->setPosition(ccp(screenSize.width/2 , screenSize.height/2 )); this->addChild(pSprite, 0); CCLabelTTF *label = CCLabelTTF::create("Tap screen", "Marker Felt", 32); label->setColor( ccc3(0,0,255) ); label->setPosition( CCPointMake( screenSize.width/2, screenSize.height-50) ); this->addChild(label, 1); //-------------------------------------------------------------------------- // init box2d world //-------------------------------------------------------------------------- // Define the gravity vector. b2Vec2 gravity; gravity.Set(0.0f, -10.0f); // Do we want to let bodies sleep? bool doSleep = true; // Construct a world object, which will hold and simulate the rigid bodies. world = new b2World(gravity); world->SetAllowSleeping(doSleep); world->SetContinuousPhysics(true); b2BodyDef groundBodyDef; groundBodyDef.position.Set(screenSize.width/2/PTM_RATIO, screenSize.height/2/PTM_RATIO); // bottom-left corner // Call the body factory which allocates memory for the ground body // from a pool and creates the ground box shape (also from a pool). // The body is also added to the world. b2Body* groundBody = world->CreateBody(&groundBodyDef); // Define the ground box shape. b2PolygonShape groundBox; // bottom groundBox.SetAsBox(screenSize.width/2/PTM_RATIO, 0, b2Vec2(0, -screenSize.height/2/PTM_RATIO), 0); groundBody->CreateFixture(&groundBox, 0); // top groundBox.SetAsBox(screenSize.width/2/PTM_RATIO, 0, b2Vec2(0, screenSize.height/2/PTM_RATIO), 0); groundBody->CreateFixture(&groundBox, 0); // left groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(-screenSize.width/2/PTM_RATIO, 0), 0); groundBody->CreateFixture(&groundBox, 0); // right groundBox.SetAsBox(0, screenSize.height/2/PTM_RATIO, b2Vec2(screenSize.width/2/PTM_RATIO, 0), 0); groundBody->CreateFixture(&groundBox, 0); //-------------------------------------------------------------------------- // add body //-------------------------------------------------------------------------- b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(pTest->getPositionX()/PTM_RATIO,pTest->getPositionY()/PTM_RATIO); bodyDef.userData = pTest; body = world->CreateBody(&bodyDef); GB2ShapeCache::sharedGB2ShapeCache()->addFixturesToBody(body, "角色1_04"); pTest->setAnchorPoint(GB2ShapeCache::sharedGB2ShapeCache()->anchorPointForShape("角色1_04")); // addNewSpriteWithCoords(pTest, "角色1_04" ); schedule( schedule_selector(HelloWorld::tick) ); return true; } void HelloWorld::menuCloseCallback(CCObject* pSender) { CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } void HelloWorld::addNewSpriteWithCoords(cocos2d::CCSprite* pSprite, std::string szName) { b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position.Set(pSprite->getPositionX() /PTM_RATIO, pSprite->getPositionY()/PTM_RATIO); bodyDef.userData = pSprite; b2Body *body = world->CreateBody(&bodyDef); // add the fixture definitions to the body GB2ShapeCache::sharedGB2ShapeCache()->addFixturesToBody(body, szName); pSprite->setAnchorPoint(GB2ShapeCache::sharedGB2ShapeCache()->anchorPointForShape(szName)); } void HelloWorld::tick(float dt) { //It is recommended that a fixed time step is used with Box2D for stability //of the simulation, however, we are using a variable time step here. //You need to make an informed choice, the following URL is useful //http://gafferongames.com/game-physics/fix-your-timestep/ if (MyTouchState) { b2Vec2 MyBirdLinearVelocity = body->GetLinearVelocity(); MyBirdLinearVelocity.y += 0.4; body->SetLinearVelocity(MyBirdLinearVelocity); } int velocityIterations = 8; int positionIterations = 10; // Instruct the world to perform a single step of simulation. It is // generally best to keep the time step and iterations fixed. world->Step(dt, velocityIterations, positionIterations); pTest->setPosition(ccp(body->GetPosition().x * PTM_RATIO,body->GetPosition().y * PTM_RATIO)); pTest->setRotation(-1 * CC_RADIANS_TO_DEGREES(body->GetAngle())); //Iterate over the bodies in the physics world // for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) // { // if (b->GetUserData() != NULL) { // //Synchronize the AtlasSprites position and rotation with the corresponding body // 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::didAccelerate(CCAcceleration* pAccelerationValue) { b2Vec2 gravity(pAccelerationValue->x*22, pAccelerationValue->y*22); world->SetGravity(gravity); } void HelloWorld::draw() { CCLayer::draw(); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position ); kmGLPushMatrix(); world->DrawDebugData(); kmGLPopMatrix(); CHECK_GL_ERROR_DEBUG(); } void HelloWorld::ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) { MyTouchState = true; } void HelloWorld::ccTouchesEnded(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent) { MyTouchState = false; }
编译下。看下效果吧。