如何使用box2d做碰撞检测

cocos2dx3.0+vs2012编译通过。

主要是通过body->SetTransform来设置body的位置和角度,然后自己写个ContactListener来监听碰撞事件

源代码下载

#include "HelloWorldScene.h"

#include "VisibleRect.h"

#include "GLES-Render.h"

#include "cocos-ext.h"



USING_NS_CC;

USING_NS_CC_EXT;



#define PTM_RATIO 32



Scene* HelloWorld::createScene()

{

    // 'scene' is an autorelease object

    auto scene = Scene::create();

    

    // 'layer' is an autorelease object

    auto 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 ( !Layer::init() )

    {

        return false;

    }

    setTouchEnabled( true );

    Size visibleSize = Director::getInstance()->getVisibleSize();

    Point origin = Director::getInstance()->getVisibleOrigin();



    /////////////////////////////

    // 2. add a menu item with "X" image, which is clicked to quit the program

    //    you may modify it.



    // add a "close" icon to exit the progress. it's an autorelease object

    auto closeItem = MenuItemImage::create(

                                           "CloseNormal.png",

                                           "CloseSelected.png",

                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

    

    closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,

                                origin.y + closeItem->getContentSize().height/2));



    // create menu, it's an autorelease object

    auto menu = Menu::create(closeItem, NULL);

    menu->setPosition(Point::ZERO);

    this->addChild(menu, 1);



    /////////////////////////////

    // 3. add your codes below...



    // add a label shows "Hello World"

    // create and initialize a label

    

    auto label = LabelTTF::create("Hello World", "Arial", 24);

    

    // position the label on the center of the screen

    label->setPosition(Point(origin.x + visibleSize.width/2,

                            origin.y + visibleSize.height - label->getContentSize().height));



    // add the label as a child to this layer

    this->addChild(label, 1);



    // add "HelloWorld" splash screen"

    auto sprite = Sprite::create("HelloWorld.png");



    // position the sprite on the center of the screen

    sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));



    // add the sprite as a child to this layer

    //this->addChild(sprite, 0);

    

    initPhysics();



    Point p(200,200);

    b2BodyDef bodyDef;

    bodyDef.type = b2_dynamicBody;

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



    body = world->CreateBody(&bodyDef);

    

    // Define another box shape for our dynamic body.

    b2PolygonShape dynamicBox;

    dynamicBox.SetAsBox(.5f, .5f);//These are mid points for our 1m box

    

    // Define the dynamic body fixture.

    b2FixtureDef fixtureDef;

    fixtureDef.shape = &dynamicBox;    

    fixtureDef.density = 1.0f;

    fixtureDef.friction = 0.3f;

    body->CreateFixture(&fixtureDef);    



    scheduleUpdate();



    //UILayer* pUiLayer = UILayer::create();

    //addChild(pUiLayer);

        

    //Layout* pWidget = dynamic_cast<Layout*>(CCUIHELPER->createWidgetFromJsonFile("cocoStudio/DemoShop.ExportJson"));

    //pUiLayer->addWidget(pWidget);







    return true;

}





void HelloWorld::menuCloseCallback(Object* pSender)

{

    Director::getInstance()->end();



#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

    exit(0);

#endif

}



void HelloWorld::initPhysics()

{

    b2Vec2 gravity;

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

    world = new b2World(gravity);



    // Do we want to let bodies sleep?

    world->SetAllowSleeping(true);



    world->SetContinuousPhysics(true);



     _debugDraw = new GLESDebugDraw( PTM_RATIO );

     world->SetDebugDraw(_debugDraw);



    uint32 flags = 0;

    flags += b2Draw::e_shapeBit;

            flags += b2Draw::e_jointBit;

            flags += b2Draw::e_aabbBit;

           flags += b2Draw::e_pairBit;

            flags += b2Draw::e_centerOfMassBit;

    _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(VisibleRect::leftBottom().x/PTM_RATIO,VisibleRect::leftBottom().y/PTM_RATIO), b2Vec2(VisibleRect::rightBottom().x/PTM_RATIO,VisibleRect::rightBottom().y/PTM_RATIO));

    groundBody->CreateFixture(&groundBox,0);



    // top

    groundBox.Set(b2Vec2(VisibleRect::leftTop().x/PTM_RATIO,VisibleRect::leftTop().y/PTM_RATIO), b2Vec2(VisibleRect::rightTop().x/PTM_RATIO,VisibleRect::rightTop().y/PTM_RATIO));

    groundBody->CreateFixture(&groundBox,0);



    // left

    groundBox.Set(b2Vec2(VisibleRect::leftTop().x/PTM_RATIO,VisibleRect::leftTop().y/PTM_RATIO), b2Vec2(VisibleRect::leftBottom().x/PTM_RATIO,VisibleRect::leftBottom().y/PTM_RATIO));

    groundBody->CreateFixture(&groundBox,0);



    // right

    groundBox.Set(b2Vec2(VisibleRect::rightBottom().x/PTM_RATIO,VisibleRect::rightBottom().y/PTM_RATIO), b2Vec2(VisibleRect::rightTop().x/PTM_RATIO,VisibleRect::rightTop().y/PTM_RATIO));

    groundBody->CreateFixture(&groundBox,0);



    class TestListener : public b2ContactListener

    {

        virtual void BeginContact(b2Contact* contact) 

        {

            //contact->GetFixtureA();

            //contact->GetFixtureB();

        }

        virtual void EndContact(b2Contact* contact) 

        { 

            //contact->GetFixtureA();

            //contact->GetFixtureB();

        }

    };

    pListener = new TestListener(); //don't forget to delete it

    world->SetContactListener(pListener);



    //groundBody->SetTransform

}



void HelloWorld::draw()

{

    //

    // IMPORTANT:

    // This is only for debug purposes

    // It is recommend to disable it

    //

    CCLayer::draw();





    GL::enableVertexAttribs( cocos2d::GL::VERTEX_ATTRIB_FLAG_POSITION );



    kmGLPushMatrix();



    world->DrawDebugData();



    kmGLPopMatrix();



}



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

}





void HelloWorld::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)

{

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

    

    for (auto& touch : touches)

    {

        if(!touch)

            break;



        auto location = touch->getLocation();

        body->SetTransform(b2Vec2(location.x/PTM_RATIO,location.y/PTM_RATIO),0);

        body->SetAwake(true);//防止静止之后就再也不动了

        //addNewSpriteAtPosition( location );

    }

    

}

 

你可能感兴趣的:(box2D)