zoukankan      html  css  js  c++  java
  • 如何使用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 );
        }
        
    }
  • 相关阅读:
    MyBatis框架Dao代理
    MyBatis对象分析及创建工具类
    搭建MyBatis开发环境及基本的CURD
    IDEA中配置Maven
    rpm 安装mysql8.0 ;安装deb
    SpringBoot 整合 xxl-job 指导手册
    设计模式(一) 单例设计模式
    SpringCloud (三) Eureka 注册中心
    SpringCloud (二) 注册中心理论
    SpringCloud (一) 微服务入门
  • 原文地址:https://www.cnblogs.com/mrblue/p/3408518.html
Copyright © 2011-2022 走看看