1、 所需头文件
#include "Box2D/Box2D.h"
2、创建一个物理世界
每个box2d游戏都有一个物理世界,下面创建一个与场景一样大小的物理场景。在该物理场景中box2d绑定的物体将满足基本物理属性
bool HelloWorld::initPhysics() {
Size s = Director::getInstance()->getVisibleSize();
//重力参数
b2Vec2 gravity;
//重力,1个g
gravity.Set(0.0f, -9.8f);
//创建世界
world = new b2World(gravity);
//开启调试
openDebugDraw();
//允许物体是否休眠
world->SetAllowSleeping(true);
//开启连续物理测试
world->SetContinuousPhysics(true);
//地面物体定义
b2BodyDef groundBodyDef;
//左下角
groundBodyDef.position.Set(0, 0);
//创建地面物体
b2Body* groundBody = world->CreateBody(&groundBodyDef);
//定义一个有边的形状
b2EdgeShape groundBox;
//底部
groundBox.Set(b2Vec2(0, 0), b2Vec2(s.width / PTM_RATIO, 0));
//使用夹具固定形状到物体上
groundBody->CreateFixture(&groundBox, 0);
//顶部
groundBox.Set(b2Vec2(0, s.height / PTM_RATIO), b2Vec2(s.width / PTM_RATIO, s.height / PTM_RATIO));
groundBody->CreateFixture(&groundBox, 0);
//左边
groundBox.Set(b2Vec2(0, s.height / PTM_RATIO), b2Vec2(0, 0));
groundBody->CreateFixture(&groundBox, 0);
//右边
groundBox.Set(b2Vec2(s.width / PTM_RATIO, s.height / PTM_RATIO), b2Vec2(s.width / PTM_RATIO, 0));
groundBody->CreateFixture(&groundBox, 0);
return true;
}
3、创建物体
首先在场景中创建一个图片精灵,然后将图片绑定到物理body上,这样物体将具备物理属性
#define PTM_RATIO 32
auto sp = Sprite::create();
sp->setPosition(100, 100);
sp->setScale(0.3f);
this->addChild(sp, -1);
sp->initWithFile("aaa/wood.png");
sp->setRotation(rotate);
phyObjList.push_back(sp);
//物体定义
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(x / PTM_RATIO, y / PTM_RATIO);
b2Body *body = world->CreateBody(&bodyDef);
body->SetUserData(sp);
body->SetTransform(body->GetPosition(), CC_DEGREES_TO_RADIANS(sp->getRotation()));
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(sp->getContentSize().width * 0.3f / 2 / PTM_RATIO, sp->getContentSize().height * 0.3f / 2 / PTM_RATIO);
// 夹具定义
b2FixtureDef fixtureDef;
//设置夹具的形状
fixtureDef.shape = &dynamicBox;
//设置密度
fixtureDef.density = 1.0f;
//设置摩擦系数
fixtureDef.friction = 0.5f;
//使用夹具固定形状到物体上
body->CreateFixture(&fixtureDef);
4、注意事项
图片需要在update中同步图片的位置,box2d只负责计算,图片需要自己根据结果设置位置
void HelloWorld::update(float dt) {
float timeStep = 0.03f;
int32 velocityIterations = 8;
int32 positionIterations = 3;
//同步刷新显示的位置
world->Step(timeStep, velocityIterations, positionIterations);
for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
{
if (b->GetUserData() != nullptr) {
Sprite* sprite = (Sprite*)b->GetUserData();
sprite->setPosition(Vec2(b->GetPosition().x *
PTM_RATIO, b->GetPosition().y * PTM_RATIO));
sprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
}