cocos2dx 3.x 物理引擎学习笔记

来源:互联网 发布:shopnc app源码 编辑:程序博客网 时间:2024/06/03 02:36

cocos2dx从3.0开始自己封装了物理引擎,当然是基于chipmunk。相对box2d来讲,chipmunk更轻量。


下面直接上一些运用的规则:

1. 建立物理世界

Scene*HelloWorld::createScene()

{

    auto scene =Scene::createWithPhysics();

    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

    auto layer =HelloWorld::create();

    scene->addChild(layer);

    return scene;

}


与普通的Scene创建方式不同的是,物理世界调用了Scene的createWithPhysics()方法,其他一样。

为了调试方便,可以给物理世界的刚体开启红边,这样就能直观的看出刚体了。


2.建立边界

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

    auto body =PhysicsBody::createEdgeBox( visibleSize,PHYSICSBODY_MATERIAL_DEFAULT,3);

   auto edgeShape =Node::create();

    edgeShape->setPhysicsBody( body);

    edgeShape->setPosition( visibleSize.width /2, visibleSize.height /2);

   addChild( edgeShape);


一般在Scene的init方法里创建物理世界的边界,方法是先调用PhysicsBody::createEdgeBox()创建一个边界刚体,然后再创建一个空的Node,将两个绑定在一起放在Scene中。

这个逻辑我觉得很奇怪,为什么不在第一步创造物理世界的时候指定边界尼?


3.接下来就是创造你需要的刚体了。

一般都是创建好刚体,然后和精灵绑定。为了更符合精灵的形状以便于做碰撞检测,我们可以使用一些物理编辑器。

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

   auto box =PhysicsBody::createBox( sprite->getContentSize());

    sprite->setPhysicsBody(box);

    addChild(sprite);

这一段绑定刚体的代码还是很符合正常人逻辑的。我们也可以设置好多刚体的属性,例如重力等。


4.刚体的三个掩码,都是32位:

categoryBitmask:  定义了分类,只要and操作后非0就可以触发碰撞,默认全打开
contactTestBitmask:定义了是否触发回调函数,默认关掉
collisionBitmask:定义了发生碰撞后是否继续作用物理效果,如果不作用就会穿过去,作用就会摊开,默认全打开


这三个掩码用来定义刚体,方便做碰撞检测。比如说,你肯定不希望英雄和自己发出的子弹做出碰撞检测吧,那就用这三个掩码来定义你的英雄和子弹。

我在实测的时候发现没定义的情况下有问题:只给一个刚体定义了contactTestBitmask,其他没变。按道理来讲,这个时候两个刚体是能碰撞但是不会触发回调的。因为categoryBitmask全打开会碰撞,而一个contactTestBitmask是关掉的,也就是说这个关掉的contactTestBitmask和另一个定义的contactTestBitmask进行and操作后肯定还是0,所以不会触发回调。但是实际情况却是触发回调了。所以使用的时候建议定义下三个掩码。


5.碰撞检测:

    auto contactListener=EventListenerPhysicsContact::create();

    contactListener->onContactBegin =CC_CALLBACK_1(HelloWorld::callback,this);

    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,this);


    boolHelloWorld::callback(constPhysicsContact& contact)

    {

        log("%d == a", contact.getShapeA()->getBody()->getContactTestBitmask());

        log("%d == b", contact.getShapeB()->getBody()->getContactTestBitmask());

        return true;

    }


获得碰撞刚体的代码其实也挺奇葩的:contact.getShapeA()->getBody()和contact.getShapeB()->getBody()。但是细细一想好像也没什么好的办法来获取发生碰撞的刚体。

好了,下一步等有空测试了运动后,再更新吧。






0 0
原创粉丝点击