Box2d 学习 1. Testbed 项目: Testbed 是 Box2d 源码里包含的一个例子程序。Testbed 封装了界面显示、游戏循环等部分的代码。添加新的例子的时候,只需要关注与 Box 有关的部分,运行时候的效果会自动绘制到界面上。 添加新例子的方法: 1. 创建一个 Test 类的子类; 2. 把这个子类的类名和 Create 函数放到 TestEntries.cpp 的 g_testEntries[] 数组中; 3. 在构造函数中创建 b2Body 等对象,完成 b2World 的创建工作; 4. 复写 Keyboard 函数,监听键盘事件; class FooTest : public Test { public: FooTest() { // 创建 body, Fixture 等 b2BodyDef myBodyDef; myBodyDef.type = b2_dynamicBody; myBodyDef.position.Set(10, 10); m_body = m_world->CreateBody(&myBodyDef); b2PolygonShape polygonShape; polygonShape.SetAsBox(1, 1); b2FixtureDef myFixtureDef; myFixtureDef.shape = &polygonShape; myFixtureDef.density = 1; m_body->CreateFixture(&myFixtureDef); } void Keyboard(unsigned char key) { // 键盘事件 switch(key) { case 'w': m_body->ApplyLinearImpulse(b2Vec2(0,50), m_body->GetWorldCenter(), true); break; default: Test::Keyboard(key); } } void Step(Settings* settings) { // 不知道干啥用 Test::Step(settings); } static Test* Create() { return new FooTest; } private: b2Body* m_body; }; 2. Body: Box2d 中的 Body 没有形状大小,不能碰撞,只具备质量(由 Fixture 的 shape 和 density 决定)、速度、位置这几个基本属性; Body 可以接收力和冲量的作用; 可以附着 Fixture ,附着后才具备形状大小,可以碰撞反弹 Body 有 3 种: static: 没有速度,不接受力和冲量的作用; dynamic: 有速度,可以接受力和冲量的作用; kinematic: 有速度,不接受力和冲量的作用。与 dynamic 碰撞不会改变原速度,与 static 碰撞不会有反应 创建 Body: b2BodyDef myBodyDef; myBodyDef.type = b2_dynamicBody; myBodyDef.position.Set(0, 20); m_body = m_world->CreateBody(&myBodyDef); 3. Fixture: Fixture 描述了物体的 形状、密度、弹性、摩擦因数; 两个物体发生碰撞时的反应由其 Fixture 决定; 一个 Body 可以有多个 Fixture ,Body 的重心受多个 Fixture 的影响; Fixture 中的 shape、destiny 等都是以标准单位 米、千克每平方来作为单位的,设定的时候可以参考实际的情形; Fixture 有四种 shape : b2PolygonShape: 多边形 b2CircleShape: 圆形 b2EdgeShape: 线 b2ChainShape: 链(几条线连在一起) Friction 摩擦因数: friction 值的范围为 0 到 1,为 0 表示完全没有摩擦,为 1 并不意味着不存在滑动; 当两个物体发生摩擦时,摩擦的大小取决于比较小的 friction Restitution 弹性: restitution 值的范围为 0 到 1, 为 0 表示完全没有弹性,碰撞时所有的能量将全部被反弹回去; 当两个物体发生碰撞时,碰撞的结果取决于比较大的 restitution 创建 Friction: b2PolygonShape polygonShape; polygonShape.SetAsBox(1,1); b2FixtureDef myFixtureDef; myFixtureDef.shape = &polygonShape; myFixtureDef.density = 1; myFixtureDef.friction = 0; // 摩擦因数为 0 myFixtureDef.restitution = 1; // 弹性因数为 1 m_body->CreateFixture(&myFixtureDef);