第一步:首先创建初始化物理场景,scene自带了创建物理场景:Scene::initWithPhysics()
初始化物理场景之后,最好开启测Debug模式,以便在运行中实时检测:
this->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
之后还可以为物理常见设置相应的属性,详情见PhysicsWorld文档。
例如:设置重力:setGravity(const Vect& gravity);
设置速度:void setSpeed(float speed)
第二步:给物理世界添加刚体,在设置刚体的时候,刚体要依附于一个节点,即将刚体添加到一个节点内才会有效
PhysicsBody *body = PhysicsBody::create();
body->addShape(PhysicsShapeCircle::create(BIRD_RADIUS));
body->setDynamic(true);
body->setLinearDamping(0.0f);
body->setGravityEnable(false);
body->setCategoryBitmask(1);
body->setCollisionBitmask(1);
body->setContactTestBitmask(1);
this->bird->setPhysicsBody(body);//bird是Sprite也是Node,可以将其添加到其中
特别要注意的是,设置刚体之后一定要设置如下三个属性,要不然在进行碰撞检测的时候会没有反应
/**
* A mask that defines which categories this physics body belongs to.
* Every physics body in a scene can be assigned to up to 32 different categories, each corresponding to a bit in the bit mask. You define the mask values used in your game. In conjunction with the collisionBitMask and contactTestBitMask properties, you define which physics bodies interact with each other and when your game is notified of these interactions.
* The default value is 0xFFFFFFFF (all bits set).
*/
body->setCategoryBitmask(1);
/**
* A mask that defines which categories of physics bodies can collide with this physics body.
* When two physics bodies contact each other, a collision may occur. This body’s collision mask is compared to the other body’s category mask by performing a logical AND operation. If the result is a non-zero value, then this body is affected by the collision. Each body independently chooses whether it wants to be affected by the other body. For example, you might use this to avoid collision calculations that would make negligible changes to a body’s velocity.
* The default value is 0xFFFFFFFF (all bits set).
*/
body->setCollisionBitmask(1);
/**
* A mask that defines which categories of bodies cause intersection notifications with this physics body.
* When two bodies share the same space, each body’s category mask is tested against the other body’s contact mask by performing a logical AND operation. If either comparison results in a non-zero value, an PhysicsContact object is created and passed to the physics world’s delegate. For best performance, only set bits in the contacts mask for interactions you are interested in.
* The default value is 0x00000000 (all bits cleared).
*/
body->setContactTestBitmask(1);
这三个是按位与的,还是设置成1吧。第三步:碰撞检测事件添加,有如下几个方法
/*
* @brief it will called at two shapes start to contact, and only call it once.
*/
std::function<bool(PhysicsContact& contact)> onContactBegin;
/*
* @brief Two shapes are touching during this step. Return false from the callback to make world ignore the collision this step or true to process it normally. Additionally, you may override collision values, restitution, or surface velocity values.
*/
std::function<bool(PhysicsContact& contact, PhysicsContactPreSolve& solve)> onContactPreSolve;
/*
* @brief Two shapes are touching and their collision response has been processed. You can retrieve the collision impulse or kinetic energy at this time if you want to use it to calculate sound volumes or damage amounts. See cpArbiter for more info
*/
std::function<void(PhysicsContact& contact, const PhysicsContactPostSolve& solve)> onContactPostSolve;
/*
* @brief it will called at two shapes separated, and only call it once.
* onContactBegin and onContactSeperate will called in pairs.
*/
std::function<void(PhysicsContact& contact)> onContactSeperate;
首先,在头文件中复写bool onContactBegin(PhysicsContact& contact);
此下为事件监听:
auto contactListener = EventListenerPhysicsContact::create();
contactListener->setEnabled(true);
contactListener->onContactBegin = CC_CALLBACK_1(GameLayer::onContactBegin, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
事件监听的回调函数:
bool GameLayer::onContactBegin(PhysicsContact& contact) {
//要执行的方法
return true;
}
参考:http://cn.cocos2d-x.org/tutorial/show?id=1246