给Qt装上物理引擎Box2D
2010-04-14 13:54
435 查看
前段时间在
CuteQt
上看到一篇
Qt+Box2D
的文章,又去
QtLab
看了下原文,感觉挺有意思的,就动手试了一下。
Box2D
的
1.0
版就之前的版本小小的改动了下
API
,那么下面,就让我简单的介绍下如何用
Box2D
在
Qt
上开发吧。
在这里,你可以找到:
Box2D 1.0
版在
Qt
中的使用简介
Box2D
和
Qt
是怎样联系到一起的
一些常见问题
Q&A
不同于之前网上的相关文章,我将用下面一个小
demo
来描述建立
Qt+Box2D
的过程,编译和使用的问题请看后面的
Q&A
Demo
描述:
我将用
Qt Graphics View Framework
模拟一个手机重力感应程序,这里并没有使用到重力感应相关的
API
,只是模拟一种手机转动时,重力感应的效果
图片中的手机外壳并不是模拟器,而是用贴图做的外壳效果,当通过程序转动手机时,里面的
item
会在模拟重力的作用下运动。而转动手机是通过
QgraphicsView
的
rotate
方法,且渲染开销较大。
一、
Box2D 1.0
版在
Qt
中的使用简介
1.0
版的
Box2D
在构建基础物理世界的方法上做了些许改变,下面根据常规的思路像大家介绍:
1.
创建一个用于
Box2D
仿真的世界,在
Box2D
里叫
b2World.
创建他需要定义重力,和另外一个用于模拟的
flag
。
// Define world, gravity
b2Vec2 gravity(0.0f,-10.0f);
bool doSleep = false;
world = new b2World(gravity, doSleep);
doSleep
的意思是,当所有仿真的物体(
body
)静止或离开
world
后,是否停
止对其的仿真。在这个
Demo
里,将其设为
false
,即物体静止后仍然仿真。
不然当物体静止后它就不会再动了。
关于
b2World
的创建,与前面版本不同的是,它不用自己定义
world
的大小
2.
构建各种
body
,包括
demo
里的各类图形
item
和将这些
item
框在手机屏幕内的对象
创建
body
需要先定义好另外三个用来描述或表示
body
性质的对象,
b2BodyDef
和
b2XXXShape
及
b2Fixture
(
XXX=Polygon
、
Circle
等在
Box2D
中定义的形状)
//upperBarBody
b2BodyDef upperBarBodyDef;
upperBarBodyDef.position.Set(93.0f, -0.5f);
b2Body *upperBarBody = world->CreateBody(&upperBarBodyDef);
b2PolygonShape upperBarBox;
upperBarBox.SetAsBox(93.0f, 0.5f);
upperBarBody->CreateFixture(&upperBarBox,0); //set density to zero for static
//body
以上是
static
的
body
,即静止的物体。下面是
dynamic
物体的定义:
// Create body with start-up position and rotation.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
//Take Care
bodyDef.position.Set(x(), -y());
bodyDef.angle = -(rotation() * (2 * PI)) / 360.0;
_body = _world->CreateBody(&bodyDef);
/*
const QPolygonF &poly = polygon();
int count = poly.size();
b2Vec2 vertices[count];
for (int i = 0; i < count; ++i) {
const QPointF &p = poly.at(i);
vertices[i].Set(p.x(), -p.y());
}*/
//
这里将与
Qt
交互的代码注释掉,用一般的构建方法
b2PolygonShape dynamicBox;
dynamicBox. SetAsBox(93.0f, 0.5f);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 600.0f; //wood 600kg/m^2
fixtureDef.friction = 0.5f;
fixtureDef.restitution = 0.5f; //0.0f~1.0f
_body->CreateFixture(&fixtureDef);
从上面的代码可以看出
static
和
dynamic
的物体,在对
b2Fixture
的要求上有所不同,而
Fixture
可以理解为物体附属的性质,比如:重力,摩擦力还有反弹力等
3.
进行仿真
上面的代码并没有开始仿真我们所建立的物理世界,只是定义好了世界里的对象,下面的代码告诉引擎,该怎样去模拟
world->Step(1.0f/30.0f, 10, 10);
…..
b2Vec2 position = _body->GetPosition();
float32 angle = _body->GetAngle();
以上只是关键的代码片段,
Step
是仿真的定义,
Step
第一个参数是每次仿真的时间间隔,后面两个参数,一个是速度增量,一个是位移增量。详细的介绍和使用注意最好还是看下
Box2D
的手册,涉及到一些物理知识。
后面的代码是处理每次仿真的函数里的,在
Qt
中,可以通过
QTimerEvent
或
QTimer
来处理每一步(
step
)的仿真,得到物体的位置和旋转,在通过
Qt
反映出来。
二、
Box2D
和
Qt
是怎样联系到一起的
前面基本上在说如何使用
Box2D
,下面介绍怎样在
Qt
中用。在
Qt
中
Box2D
只用作物理引擎,而真正的绘图还是交给
Qt
来做。还记得前面定义
body
时使用的
b2XXXShape
吗,关键就在这儿。
以
Polygon
图形为例,需要我们继承
QGraphicsPolygonItem
,在其中
const QPolygonF &poly = polygon();
int count = poly.size();
b2Vec2 vertices[count];
for (int i = 0; i < count; ++i) {
const QPointF &p = poly.at(i);
vertices[i].Set(p.x(), -p.y());
}
b2PolygonShape dynamicBox;
dynamicBox.Set(vertices, count);
而对于其他形状的物体,如
Circle
,
Rectangle
都可以找到对应的
Qt Graphics Item
。像比较复杂的图形,只要知道怎样得到
painterPath
,就可以做相应的处理,通过
vertice
定义我们的
Box2D body
三、
一些常见问题
Q&A
及时更新
CuteQt
上看到一篇
Qt+Box2D
的文章,又去
QtLab
看了下原文,感觉挺有意思的,就动手试了一下。
Box2D
的
1.0
版就之前的版本小小的改动了下
API
,那么下面,就让我简单的介绍下如何用
Box2D
在
Qt
上开发吧。
在这里,你可以找到:
Box2D 1.0
版在
Qt
中的使用简介
Box2D
和
Qt
是怎样联系到一起的
一些常见问题
Q&A
不同于之前网上的相关文章,我将用下面一个小
demo
来描述建立
Qt+Box2D
的过程,编译和使用的问题请看后面的
Q&A
Demo
描述:
我将用
Qt Graphics View Framework
模拟一个手机重力感应程序,这里并没有使用到重力感应相关的
API
,只是模拟一种手机转动时,重力感应的效果
图片中的手机外壳并不是模拟器,而是用贴图做的外壳效果,当通过程序转动手机时,里面的
item
会在模拟重力的作用下运动。而转动手机是通过
QgraphicsView
的
rotate
方法,且渲染开销较大。
一、
Box2D 1.0
版在
Qt
中的使用简介
1.0
版的
Box2D
在构建基础物理世界的方法上做了些许改变,下面根据常规的思路像大家介绍:
1.
创建一个用于
Box2D
仿真的世界,在
Box2D
里叫
b2World.
创建他需要定义重力,和另外一个用于模拟的
flag
。
// Define world, gravity
b2Vec2 gravity(0.0f,-10.0f);
bool doSleep = false;
world = new b2World(gravity, doSleep);
doSleep
的意思是,当所有仿真的物体(
body
)静止或离开
world
后,是否停
止对其的仿真。在这个
Demo
里,将其设为
false
,即物体静止后仍然仿真。
不然当物体静止后它就不会再动了。
关于
b2World
的创建,与前面版本不同的是,它不用自己定义
world
的大小
2.
构建各种
body
,包括
demo
里的各类图形
item
和将这些
item
框在手机屏幕内的对象
创建
body
需要先定义好另外三个用来描述或表示
body
性质的对象,
b2BodyDef
和
b2XXXShape
及
b2Fixture
(
XXX=Polygon
、
Circle
等在
Box2D
中定义的形状)
//upperBarBody
b2BodyDef upperBarBodyDef;
upperBarBodyDef.position.Set(93.0f, -0.5f);
b2Body *upperBarBody = world->CreateBody(&upperBarBodyDef);
b2PolygonShape upperBarBox;
upperBarBox.SetAsBox(93.0f, 0.5f);
upperBarBody->CreateFixture(&upperBarBox,0); //set density to zero for static
//body
以上是
static
的
body
,即静止的物体。下面是
dynamic
物体的定义:
// Create body with start-up position and rotation.
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
//Take Care
bodyDef.position.Set(x(), -y());
bodyDef.angle = -(rotation() * (2 * PI)) / 360.0;
_body = _world->CreateBody(&bodyDef);
/*
const QPolygonF &poly = polygon();
int count = poly.size();
b2Vec2 vertices[count];
for (int i = 0; i < count; ++i) {
const QPointF &p = poly.at(i);
vertices[i].Set(p.x(), -p.y());
}*/
//
这里将与
Qt
交互的代码注释掉,用一般的构建方法
b2PolygonShape dynamicBox;
dynamicBox. SetAsBox(93.0f, 0.5f);
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;
fixtureDef.density = 600.0f; //wood 600kg/m^2
fixtureDef.friction = 0.5f;
fixtureDef.restitution = 0.5f; //0.0f~1.0f
_body->CreateFixture(&fixtureDef);
从上面的代码可以看出
static
和
dynamic
的物体,在对
b2Fixture
的要求上有所不同,而
Fixture
可以理解为物体附属的性质,比如:重力,摩擦力还有反弹力等
3.
进行仿真
上面的代码并没有开始仿真我们所建立的物理世界,只是定义好了世界里的对象,下面的代码告诉引擎,该怎样去模拟
world->Step(1.0f/30.0f, 10, 10);
…..
b2Vec2 position = _body->GetPosition();
float32 angle = _body->GetAngle();
以上只是关键的代码片段,
Step
是仿真的定义,
Step
第一个参数是每次仿真的时间间隔,后面两个参数,一个是速度增量,一个是位移增量。详细的介绍和使用注意最好还是看下
Box2D
的手册,涉及到一些物理知识。
后面的代码是处理每次仿真的函数里的,在
Qt
中,可以通过
QTimerEvent
或
QTimer
来处理每一步(
step
)的仿真,得到物体的位置和旋转,在通过
Qt
反映出来。
二、
Box2D
和
Qt
是怎样联系到一起的
前面基本上在说如何使用
Box2D
,下面介绍怎样在
Qt
中用。在
Qt
中
Box2D
只用作物理引擎,而真正的绘图还是交给
Qt
来做。还记得前面定义
body
时使用的
b2XXXShape
吗,关键就在这儿。
以
Polygon
图形为例,需要我们继承
QGraphicsPolygonItem
,在其中
const QPolygonF &poly = polygon();
int count = poly.size();
b2Vec2 vertices[count];
for (int i = 0; i < count; ++i) {
const QPointF &p = poly.at(i);
vertices[i].Set(p.x(), -p.y());
}
b2PolygonShape dynamicBox;
dynamicBox.Set(vertices, count);
而对于其他形状的物体,如
Circle
,
Rectangle
都可以找到对应的
Qt Graphics Item
。像比较复杂的图形,只要知道怎样得到
painterPath
,就可以做相应的处理,通过
vertice
定义我们的
Box2D body
三、
一些常见问题
Q&A
及时更新
相关文章推荐
- Box2D:给你的Qt程序加上物理引擎(包含windows+linux版)
- Box2D:给你的Qt程序加上物理引擎
- cocos2dx-3.x 修改默认物理引擎为Box2D
- cocos2d-x初探学习笔记--物理引擎box2d(1)
- 物理引擎比较:Box2D 对比 Chipmunk
- cocos2d学习笔记(七)物理引擎box2d之一
- HTML5之2D物理引擎 Box2D for javascript Games 系列 第二部分
- /LGC物理引擎/Android port of Box2d
- flash与物理引擎:QuickBox2D
- HTML5游戏开发开源库件lufylegend1.4.0发布,新增物理引擎Box2dWeb封装和缓动类TweenLite
- 基于HTML5的WebGL结合Box2DJS物理引擎应用
- 《割绳子》《蜡笔物理学》《Contre Jour》《顽皮鳄鱼爱洗澡》等游戏用Box2D引擎实现物理部分的方法(转)
- 基于HTML5的WebGL结合Box2DJS物理引擎应用
- cocos2d-x 物理引擎Box2D
- cocos2dx-3.0 中的物理引擎Box2D使用(三)
- cocos2d-x Tests讲解四:box2dTest(物理引擎)
- cocos2d-x之物理引擎box2d(1)
- 物理引擎Box2D-- 愤怒的小鸟
- Android 2D物理引擎Box2d的使用示例
- Box2d 物理引擎