下午学了一下box2d相关的内容,这里做个笔记。

1、创建头文件

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "GLES-Render.h"
USING_NS_CC;
class HelloWorld : public cocos2d::CCLayer
{
public:
   HelloWorld();
   ~HelloWorld();
                     
    static cocos2d::CCScene* scene();
    CCSize _screenSize;
    void initPhysics();
    virtual void draw();
    void update(float dt); 
    virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
    void addNewSpriteAtPosition(CCPoint p);
private:
    cocos2d::CCTexture2D* m_pSpriteTexture;
    b2World* world;
    GLESDebugDraw* m_debugDraw;
};
#endif // __HELLOWORLD_SCENE_H__


2、编写实现cpp

#include "HelloWorldScene.h"
#include "VisibleRect.h"
USING_NS_CC;
#define PTM_RATIO 32.0f
enum{
    kTagParentNode = 1
};
HelloWorld::HelloWorld():m_pSpriteTexture(NULL),world(NULL){
    _screenSize = CCDirector::sharedDirector()->getVisibleSize();
    setTouchEnabled(true);
    this->initPhysics();
    //使用批处理方式加载图片
    CCSpriteBatchNode *parent = CCSpriteBatchNode::create("blocks.png",100);
    m_pSpriteTexture = parent->getTexture();
    addChild(parent,0,kTagParentNode);
    //在中间添加一个精灵
    addNewSpriteAtPosition(ccp(_screenSize.width/2,_screenSize.height/2));
    scheduleUpdate();
}
HelloWorld::~HelloWorld(){
    delete world;
    world = NULL;
    delete m_debugDraw;
}
void HelloWorld::initPhysics(){
    b2Vec2 gravity;
    gravity.Set(0.0f,-10.0f);
    //创建世界
    world = new b2World(gravity);
    //允许睡眠
    world->SetAllowSleeping(true);
    world->SetContinuousPhysics(true);
    //创建GLESDebugDraw
     m_debugDraw = new GLESDebugDraw( PTM_RATIO );
     world->SetDebugDraw(m_debugDraw);
    uint32 flags = 0;
    flags += b2Draw::e_shapeBit;
    flags += b2Draw::e_jointBit;
     m_debugDraw->SetFlags(flags);
    //定义边框
    b2BodyDef groundBodyDef;
    groundBodyDef.position.Set(0,0);
    b2Body* groundBody = world->CreateBody(&groundBodyDef);
    //定义ground box shape
    b2EdgeShape groundBox;
    //bottom
    groundBox.Set(b2Vec2(0,0),
        b2Vec2(_screenSize.width/PTM_RATIO,0/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    //top
    groundBox.Set(b2Vec2(0,_screenSize.height/PTM_RATIO),
        b2Vec2(_screenSize.width/PTM_RATIO,_screenSize.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);
    //left
    groundBox.Set(b2Vec2(0,_screenSize.height/PTM_RATIO),
        b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);
    //right
    groundBox.Set(b2Vec2(_screenSize.width/PTM_RATIO,_screenSize.height/PTM_RATIO),
        b2Vec2(_screenSize.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);
}
void HelloWorld::draw(){
    CCLayer::draw();
         
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     //进行绘制
     world->DrawDebugData();
    // restore default GL states
    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
}
void HelloWorld::update(float dt){
    world->Step(dt,8,1);
    //同步精灵的物理动作
    for(b2Body* b = world->GetBodyList();b;b=b->GetNext()){
        if(b->GetUserData()!=NULL){
            CCSprite* sprite = (CCSprite*)b->GetUserData();
            sprite->setPosition(ccp(b->GetPosition().x * PTM_RATIO,b->GetPosition().y*PTM_RATIO));
            sprite->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle()));
        }
    }
}
CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
            
    // 'layer' is an autorelease object
    HelloWorld *layer = new HelloWorld();
    // add layer as a child to scene
    scene->addChild(layer);
    layer->release();
    // return the scene
    return scene;
}
/************************************************************************/
/* 触摸方法                                                                     */
/************************************************************************/
void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){
    CCSetIterator it;
    CCTouch* touch;
    for(it = pTouches->begin();it!=pTouches->end();it++){
        touch = (CCTouch*)(*it);
        if(!touch){
            break;
        }
        CCPoint location = touch->getLocation();
        //触摸后添加精灵
        addNewSpriteAtPosition(location);
    }
}
/************************************************************************/
/* 添加精灵                                                                     */
/************************************************************************/
void HelloWorld::addNewSpriteAtPosition(CCPoint p){
    CCLOG("Add sprite %0.2f x %02.f",p.x,p.y);
    CCNode* parent = this->getChildByTag(kTagParentNode);
    int idx=(CCRANDOM_0_1()>0.5f?0:1);
    int idy=(CCRANDOM_0_1()>0.5f?0:1);
    //随机创建精灵
    CCSprite* sprite = CCSprite::createWithTexture(m_pSpriteTexture,CCRectMake(32*idx,32*idy,32,32));
    sprite->setPosition(p);
    parent->addChild(sprite);
    //定义动态刚体
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(p.x/PTM_RATIO,p.y/PTM_RATIO);
    bodyDef.userData = sprite;
    //创建刚体
    b2Body* body = world->CreateBody(&bodyDef);
    //创建长方形
    b2PolygonShape dynamicBox;
    dynamicBox.SetAsBox(sprite->getContentSize().width/PTM_RATIO/2,sprite->getContentSize().width/PTM_RATIO/2);
    //定义夹角
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;
    fixtureDef.density = 1.0f; //密度
    fixtureDef.friction = 0.3f;//摩擦力
    body->CreateFixture(&fixtureDef);
         
}

素材来源与cocos2d-x自带demo

cocos2d-x之box2d使用笔记_第1张图片