Sollyu

  • 捐赠
  • 关于
  1. 首页
  2. 原创文章
  3. 正文

PhysicsEditor Cocos2d-x使用教程

2014年6月12日 7835点热度 0人点赞 2条评论

创建一个空工程

/create_project.py -project phyTest -package cn.sollyu.phytest -language cpp

复制我的上一篇文章代码,分别保存下来。(支持Cocos2d-x 2.0以上)

讲代码添加到你的工程里

enter image description here

使用PhysicsEdit创建一个plist文件。

enter image description here

将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;
}

编译下。看下效果吧。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: cocos2d-x
最后更新:2014年6月12日

sollyu

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2021 sollyu.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

苏ICP备15007531号