cocos2d-x box2d 入门

个人原创,欢迎转载http://blog.csdn.net/dawn_moon/article/details/20466245

天天飞翔,物理特性用了box2d来做的。关于box2d的入门教程网上有很多,推荐官方手册,中文版,地址。我不再做重复介绍,稍微写点自己理解的东西。


cocos2d-x可以和box2d的C++版完美融合,集成起来很方便。

#include "Box2D.h"

包含进来就可以了。这里有个问题,cocos2d-x2.2.1版本NDK编译安卓版本的时候,需要改下, 不然找不到box2d的头文件。

#include "Box2D/Box2D.h"

开启box2d的debug渲染

一般为了方便调试box2d,会将物理世界的物体绘制出来,官方有debug draw,cocos2dx里面有个debug的工具类GLESDebugDraw,在test工程里面,文件名GLES-Render.h,加入进来。

步骤如下:

1。需要有个box2d的物理世界b2World,一个debug渲染器,GLESDebugDraw。demo如下:

//
//  TestBox.h
//  TestBox2d
//
//  Created by lerry on 14-3-4.
//  Copyright (c) 2014年 GoonearTechnology Co.,Ltd. All rights reserved.
//

#ifndef __TestBox2d__TestBox__
#define __TestBox2d__TestBox__

#include "cocos2d.h"
#include "Box2D.h"
#include "GLES-Render.h"

#define RATIO 96

class TestBox : public cocos2d::CCLayer
{
    cocos2d::CCSprite* role;
    b2World* mWorld;
    
    GLESDebugDraw* mDebugDraw;
    
    cocos2d::CCSize visualSize;
    
    
private:
    void draw();
    
    void drawBox();
    
public:
    
    ~TestBox();
    virtual void update(float dt);
    
    virtual bool init();
    
    virtual void onEnter();
    virtual void onExit();
    
    virtual bool ccTouchBegan(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    virtual void ccTouchMoved(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    virtual void ccTouchEnded(cocos2d::CCTouch* touch, cocos2d::CCEvent* event);
    
    void initWorld();
    
    void setDebug(bool isDebug);
    
    static cocos2d::CCScene* scene();
    
    CREATE_FUNC(TestBox);
    
    
};

#endif /* defined(__TestBox2d__TestBox__) */

2。构建世界,构建世界盒子,开启debug模式
void TestBox::initWorld()
{
    mWorld = new b2World(b2Vec2(0, -10));
    mWorld->SetAllowSleeping(true);
    mWorld->SetContinuousPhysics(true);
    
    setDebug(true);
}
3。如果开启debug模式,启用debug绘制

void TestBox::setDebug(bool isDebug)
{
    if (isDebug) {
        mDebugDraw = new GLESDebugDraw(RATIO);
        mWorld->SetDebugDraw(mDebugDraw);
        
        uint32 flags = 0;
        flags += b2Draw::e_shapeBit;
        flags += b2Draw::e_jointBit;
        flags += b2Draw::e_pairBit;
        flags += b2Draw::e_centerOfMassBit;
        mDebugDraw->SetFlags(flags);
        draw();
        
    }
}

void TestBox::draw()
{
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
    
    kmGLPushMatrix();
    
    mWorld->DrawDebugData();
    
    kmGLPopMatrix();
}
4.init里面初始化世界,调用update函数即可。

代码如下:

//
//  TestBox.cpp
//  TestBox2d
//
//  Created by lerry on 14-3-4.
//  Copyright (c) 2014年 GoonearTechnology Co.,Ltd. All rights reserved.
//

#include "TestBox.h"

USING_NS_CC;

TestBox::~TestBox()
{
    delete mWorld;
    mWorld = NULL;
    delete mDebugDraw;
    mDebugDraw = NULL;
}

CCScene* TestBox::scene()
{
    CCScene* s = CCScene::create();
    TestBox* test = TestBox::create();
    s->addChild(test);
    return s;
}

bool TestBox::init()
{
    if(!CCLayer::init())
    {
        return false;
    }
    
    visualSize = CCDirector::sharedDirector()->getVisibleSize();
    
    initWorld();
    
    drawBox();
    
    scheduleUpdate();
    return true;
}

void TestBox::update(float dt)
{
    int velocityIterat = 8;
    int positionIterat = 1;
    mWorld->Step(dt, velocityIterat, positionIterat);
    
    for(b2Body *b=mWorld->GetBodyList(); b; b=b->GetNext())
    {
        if(b->GetUserData()!=NULL)
        {
            CCSprite *sprite=(CCSprite*)b->GetUserData();
            
            sprite->setPosition(ccp(b->GetPosition().x*RATIO,b->GetPosition().y*RATIO));
            sprite->setRotation((-1)*CC_RADIANS_TO_DEGREES(b->GetAngle()));
        }
    }
}

void TestBox::drawBox()
{
    
    {   // 地板
        b2Body* ground = NULL;
        b2BodyDef bd;
        ground = mWorld->CreateBody(&bd);
        
        // 底边
        b2EdgeShape shape;
        shape.Set(b2Vec2(0.1f, 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, 0.1f));
        ground->CreateFixture(&shape, 0.0f);
        
        shape.Set(b2Vec2(0.1f, 0.1f), b2Vec2(0.1f, visualSize.height / RATIO - 0.1f));
        ground->CreateFixture(&shape, 0.0f);
        
        shape.Set(b2Vec2(0.1f, visualSize.height / RATIO - 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, visualSize.height / RATIO - 0.1f));
        ground->CreateFixture(&shape, 0.0f);
        
        shape.Set(b2Vec2(visualSize.width / RATIO - 0.1f, 0.1f), b2Vec2(visualSize.width / RATIO - 0.1f, visualSize.height / RATIO - 0.1f));
        ground->CreateFixture(&shape, 0.0f);
        
    }
    
    {
        role = CCSprite::create("poop_1.png");
        CCSize size = role->getContentSize();
        role->setPosition(ccp(visualSize.width / 2, visualSize.height / 2));
        
        b2BodyDef bodyDef;
        bodyDef.type = b2_dynamicBody;
        bodyDef.userData = role;
        bodyDef.position.Set(visualSize.width / 2 / RATIO, visualSize.height / 2 / RATIO);
        b2Body* body = mWorld->CreateBody(&bodyDef);
        
        
        b2PolygonShape shape;
        shape.SetAsBox(size.width / 2 / RATIO, size.height / 2 / RATIO);
        b2FixtureDef fixDef;
        fixDef.shape = &shape;
        body->CreateFixture(&fixDef);
        
        addChild(role);

        
    }

}

void TestBox::initWorld()
{
    mWorld = new b2World(b2Vec2(0, -10));
    mWorld->SetAllowSleeping(true);
    mWorld->SetContinuousPhysics(true);
    
    setDebug(true);
}

void TestBox::setDebug(bool isDebug)
{
    if (isDebug) {
        mDebugDraw = new GLESDebugDraw(RATIO);
        mWorld->SetDebugDraw(mDebugDraw);
        
        uint32 flags = 0;
        flags += b2Draw::e_shapeBit;
        flags += b2Draw::e_jointBit;
        flags += b2Draw::e_pairBit;
        flags += b2Draw::e_centerOfMassBit;
        mDebugDraw->SetFlags(flags);
        draw();
        
    }
}

void TestBox::draw()
{
    ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position );
    
    kmGLPushMatrix();
    
    mWorld->DrawDebugData();
    
    kmGLPopMatrix();
}

bool TestBox::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
    CCLog("touch");
    
    return true;
}

void TestBox::ccTouchMoved(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
    
}

void TestBox::ccTouchEnded(cocos2d::CCTouch *touch, cocos2d::CCEvent *event)
{
    
}

void TestBox::onEnter()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
    CCLayer::onEnter();
}

void TestBox::onExit()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->removeDelegate(this);
    CCLayer::onExit();
}

是不是感觉没什么注释啊,好的代码不需要注释 大笑

cocos2d-x box2d 入门_第1张图片

你可能感兴趣的:(cocos2d-x,游戏开发,天天飞翔)