cocos2d-x box2d 示例

*****HelloWorld.h

//

//  HelloWorldScene.h

//  B2Ball

//

//  Created by 怀义 on 4/2/13.

//  Copyright __MyCompanyName__ 2013. All rights reserved.

//

#ifndef __HELLO_WORLD_H__

#define __HELLO_WORLD_H__


// When you import this file, you import all the cocos2d classes

#include "cocos2d.h"

#include "Box2D.h"


using namespace cocos2d;


class HelloWorld : public cocos2d::CCLayerColor {

public:

    ~HelloWorld();

    HelloWorld();

    

    // returns a Scene that contains the HelloWorld as the only child

    static cocos2d::CCScene* scene();

    

    void initPhysics();

    // adds a new sprite at a given coordinate

    void addNewSpriteAtPosition(cocos2d::CCPoint p);


    virtual void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);

    void update(float dt);

    

private:

    b2World* world;

    cocos2d::CCTexture2D* m_pSpriteTexture; // weak ref

    b2Body *_body;

    CCSprite *_ball;

};


#endif // __HELLO_WORLD_H__



*****HelloWorld.cpp

//

//  HelloWorldScene.cpp

//  B2Ball

//

//  Created by 怀义 on 4/2/13.

//  Copyright __MyCompanyName__ 2013. All rights reserved.

//

#include "HelloWorldScene.h"

#include "SimpleAudioEngine.h"


using namespace cocos2d;

using namespace CocosDenshion;


#define PTM_RATIO 32


enum {

    kTagParentNode = 1,

};



HelloWorld::HelloWorld()

{

    if(!CCLayerColor::initWithColor(ccc4(255, 255, 255, 255))){

        return;

    }

    

    setTouchEnabled( true );

    setAccelerometerEnabled( true );


    CCSize s = CCDirector::sharedDirector()->getWinSize();

    // init physics

    this->initPhysics();


    addNewSpriteAtPosition(ccp(s.width/2, s.height/2));


    CCLabelTTF *label = CCLabelTTF::create("Tap screen", "Marker Felt", 32);

    addChild(label, 0);

    label->setColor(ccc3(0,0,255));

    label->setPosition(ccp( s.width/2, s.height-50));    

    scheduleUpdate();

}


HelloWorld::~HelloWorld()

{

    delete world;

    world = NULL;

    

    //delete m_debugDraw;

}


void HelloWorld::initPhysics()

{


    CCSize s = CCDirector::sharedDirector()->getWinSize();


    b2Vec2 gravity;

    gravity.Set(0.0f, -30.0f);

    world = new b2World(gravity);


    // Do we want to let bodies sleep?

    world->SetAllowSleeping(true);


    world->SetContinuousPhysics(true);


    uint32 flags = 0;

    flags += b2Draw::e_shapeBit;

    //        flags += b2Draw::e_jointBit;

    //        flags += b2Draw::e_aabbBit;

    //        flags += b2Draw::e_pairBit;

    //        flags += b2Draw::e_centerOfMassBit;

    //m_debugDraw->SetFlags(flags);



    // Define the ground body.

    b2BodyDef groundBodyDef;

    groundBodyDef.position.Set(0, 0); // 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.

    b2EdgeShape groundBox;


    // bottom


    groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));

    groundBody->CreateFixture(&groundBox,0);


    // top

    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));

    groundBody->CreateFixture(&groundBox,0);


    // left

    groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));

    groundBody->CreateFixture(&groundBox,0);


    // right

    groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));

    groundBody->CreateFixture(&groundBox,0);

}


void HelloWorld::addNewSpriteAtPosition(CCPoint p)

{

    CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);

    _ball = CCSprite::create("Icon.png");

    this->addChild(_ball);

    _ball->setPosition( CCPointMake( p.x, p.y) );

        

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();

    

        b2BodyDef ballBodyDef;

        ballBodyDef.type = b2_dynamicBody;

        ballBodyDef.position.Set(p.x / PTM_RATIO, p.y / PTM_RATIO);

        ballBodyDef.userData = _ball;

        _body = world->CreateBody(&ballBodyDef);

        

        b2CircleShape circle;

        circle.m_radius = 26.0 / PTM_RATIO;

        

        b2FixtureDef ballShapeDef;

        ballShapeDef.shape = &circle;

        ballShapeDef.density = 1.0f;

        ballShapeDef.friction = 0.2f;

        ballShapeDef.restitution = 0.8f;

        _body->CreateFixture(&ballShapeDef);

//    _body->ApplyForceToCenter(b2Vec2(-1000, -1000));

    _body->ApplyForce(b2Vec2(1000, 1000), _body->GetWorldCenter());

}



void HelloWorld::update(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/

    

    int velocityIterations = 8;

    int positionIterations = 1;

    

    // 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);

    

    //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::ccTouchesEnded(CCSet* touches, CCEvent* event)

{

    //Add a new body/atlas sprite at the touched location

    CCSetIterator it;

    CCTouch* touch;

    

    for( it = touches->begin(); it != touches->end(); it++) 

    {

        touch = (CCTouch*)(*it);

        

        if(!touch)

            break;

        

        CCPoint location = touch->getLocationInView();

        

        location = CCDirector::sharedDirector()->convertToGL(location);

        

        addNewSpriteAtPosition( location );

    }

}


CCScene* HelloWorld::scene()

{

    // 'scene' is an autorelease object

    CCScene *scene = CCScene::create();

    

    // add layer as a child to scene

    CCLayer* layer = new HelloWorld();

    scene->addChild(layer);

    layer->release();

    

    return scene;

}

你可能感兴趣的:(cocos2d-x box2d 示例)