开始按步骤走:
1、首先包含头文件,我自己写了几个宏#include "Box2D/Box2D.h"
//将cocos2dx中的像素转成米
#define BOX2D_PX_TO_M(px) px/32.0
//根据box2d中的刚体,获取他对应于cocos2dx中的旋转角度
#define BOX2D_GET_RORATION_BY_BODY(body) CC_RADIANS_TO_DEGREES(body->GetAngle())*-1
//根据box2d中的刚体,获取他对应于cocos2dx中的位置
#define BOX2D_GET_POSITION_BY_BODY(body) Vec2(body->GetPosition().x*32.0,body->GetPosition().y*32.0)
2、创建世界
b2Vec2 g(0,0);//定义重力
_world = new b2World(g);
_world -> SetAllowSleeping(true);//允许休眠(不运动的物体,不对其进行计算),开启这个会提高性能
_world -> SetContinuousPhysics(true);//避免高速运动在系统还没执行检测时就已经穿透了,开启这个会降低性能
这里还可以给世界设置监听,具体后面说
3、创建刚体
创建刚体分两步
1、先规定刚体的基本属性:起点,哪种类型的刚体,userData,速度,旋转.... ----------b2BodyDef
2、设置刚体的物理属性:密度,恢复,摩擦,是否是传感器,刚体的外边框,碰撞筛选 ----------b2FixtureDef、Shape(b2EdgeShape、b2CircleShape、b2PolygonShape)
//------------------------------基本属性------------------------------//
b2BodyDef bodydef;
//设置刚体的起点
bodydef.position.Set(BOX2D_PX_TO_M(x),BOX2D_PX_TO_M(y)); //像素转成米
bodydef.type = b2BodyType::b2_dynamicBody;
/*
b2_staticBody = 0 没有质量,没有速度,不受动力影响,碰撞也不会弹开
b2_kinematicBody 没有质量 但可以设置速度
b2_dynamicBody 动态的刚体
*/
bodydef.userData = userdata; //在刚体中存储一份精灵的指针,以便在刚体运动那个是能够找到和他绑定的精灵
auto body = _world->CreateBody(&bodydef);
//------------------------------物理属性------------------------------//
//设置刚体的框架
b2FixtureDef def;
def.density = 1.0f;//密度
def.restitution = 0.5f;//恢复
def.friction = 0.5f;//摩擦
//def.isSensor = true;//传感器 --会产生碰撞信息,但是本身并不与其他刚体发生具体碰撞
//创建矩形
//b2PolygonShape shape;
//shape.SetAsBox(PXTOM(20), PXTOM(20));//半宽半高(图片宽高为40)
//创建三角
//b2PolygonShape shape;
//b2Vec2 bv[3] = {b2Vec2(-20/32.0, 0),b2Vec2(20/32.0, 0),b2Vec2(0, 40/32.0)};
//shape1.Set(bv, 3);
//创建圆
b2CircleShape shape;
shape.m_radius = BOX2D_PX_TO_M(20);//半径
def.shape = &shape;
/*
def.filter.groupIndex = 0;//组号
def.filter.categoryBits = 1;//类别
def.filter.maskBits = 2;//掩码
1、如果组号相同,都是正数 发生碰撞
2、如果组号相同,都是负数 不发生碰撞
3、如果组号不相同或组号都为0 --看 类别与掩码
*/
/*
如果组号不相同或组号都为0,两个刚体是否碰撞,说明如下:
(1)A B 两刚体:A的类别为1、掩码为3,B的类别为1、掩码为2
a = A.categoryBits & B.maskBits 001&010 = 000
b = B.categoryBits & A.maskBits 001&011 = 001
如果 a与b都不为0则发生碰撞
*/
body -> CreateFixture(&def);
4、关节
关节有很多类型:距离关节、旋转关节、焊接关节、鼠标关节、移动关节、滑轮环节、齿轮关节、线性关节
关节和刚体一样都由世界来创建,已距离关节为例
//距离关节(硬)
b2DistanceJointDef jointdef;
jointdef.Initialize(bodyA, bodyB, b2Vec2(0.5, 0.5), b2Vec2(0.5, 0.5));
jointdef.collideConnected = true;
//软
jointdef.frequencyHz = 4.0f;
jointdef.dampingRatio = 0.5f;
_world->CreateJoint(&jointdef);
每个关节都由一个对应的b2JointDef结构体,设置好里面的属性,然后通过世界把刚体连接上就好了
5、监听
b2ContactFilter
自己新建个类继承自b2ContactFilter,实现里面的
bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB);方法,两个刚体即将碰撞前会调用这个方法,返回true代表进行碰撞,返回false代表不进行碰撞。注意如果设置了类别和掩码,并打算让它正常生效,则需要在方法内最开始加上
if(!b2ContactFilter::ShouldCollide(fixtureA,fixtureB)){
return false;
}
b2ContactListener
也是自己新建个类继承自b2ContactListener,实现4各方法
//开始接触
void BeginContact(b2Contact* contact);
//结束接触
void EndContact(b2Contact* contact);
//持续接触(1)求解前
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
//持续接触(2)求解后
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
持续接触的两个方法会被调用多次,求解前和求解后是什么意思,大家创建几个刚体测试测试就大概了解了
其他的监听类我目前还没用过,等以后用上了再说
box2d的东西就先说这么多