什么是PBox2D?
Box2D是一个用于模拟刚体物体运动的物理引擎,所谓的物理引擎,就是将对象相关物理属性的计算封装在类库中,由类库去维护物理属性的变化。在原始的Processing编程的过程中,如果我们需要模拟物体的运动, 需要让物体去维护位置、速度、加速度、角度等物理属性,如果我们引入了Box2D,那么就可以将这大部分的工作交给物理引擎去进行计算,减少了代码的复杂度。Box2D最初是用C++编写的, 后期也引入了java版本,Processing是基于java, 所以也能使用Box2D, 但是Box2D物理世界中的属性是模拟的真实的世界,而在Processing中是针对像素进行编程的,所以需要进行复杂的转换, 而PBox2D就进行了这些工作的封装。
Box2D基础
Box2D物理世界中的核心元素
1.世界(world) 管理整个物理模拟过程,它知道坐标空间的所有信息,存放了世界中的所有物体。
2.物体(body) Box2D世界的基础元素,有自己的位置和速度。是否感到似曾相识?在前面力和向量的模拟程序中,我们开发了很多类,Box2D的物体就等同于这些类。
3.形状(shape) 记录所有与碰撞相关的几何信息。注意这个形状是抽象的,在Box2D中对物体的行为进行计算,并不包括渲染图像。
4.夹具(fixture) 将形状赋给物体,设置物体的一些属性,比如密度、摩擦系数、复原性。
5.关节(joint) 充当两个物体之间的连接器(或者物体和世界之间的连接器)。
如何使用Box2D?
创建世界
Box2DProcessing box2d = new Box2DProcessing();
box2d.setGravity(0, -10);//设置重力,注意这里的坐标使用的是box2d中的坐标系,也就是十字坐标系
在draw()中调用box2d.step();作用是让Box2D中物理世界中的时间向前推进一步,一定要调用,否则不会动
pbox2d提供了像素坐标和box2d世界坐标的转换函数,比如Vec2 mouseWorld = box2d.coordPixelsToWorld(mouseX,mouseY);//将mouseX、mouseY转化成Box2D坐标
创建Box2D物体
1.定义一个物体 BodyDef bd = new BodyDef();//创建物体之前先创建定义
2.定义物体的位置
Vec2 location= box2d.coordPixelsToWorld(width/2, height/2);//转化为Box2D坐标,假设物体位于processing窗口的正中间
bd.postion.set(location);//设置Box2D物体定义中的位置属性
3.定义物体的属性
bd.type = BodyType.DYNAMIC;//指定物体的类型
DYNAMIC:一个完全模拟的物体,可以运动, 能和周围的物体进行交互
STATIC:不能移动
Kinematic:对此类物体,你可以通过设置它的速度向量来控制其移动。如果你的世界中有一个完全由用户控制的对象,你可以创建Kinematic类型的物体。注意,Kinematic的物体只会和动态的物体发生碰撞,不会和静态或者Kinematic的物体发生碰撞。
bd.fixedRotation = true;//物体永远不旋转, 默认为false
bd.linearDamping = 0.8; //物体的线速度阻尼
bd.angularDamping = 0.9;//物体的角速度阻尼
bd.bullet = true;//告诉Box2D该物体运动非常快
4. 创建物体
Body body = box2d.createBody(bd); 传入物体定义,创建物体(可以用同一个定义创建多个物体)
5.设置物体的初始状态
body.setLinearVelocity(new Vec2(0,3)); 设置物体的初始速度
body.setAngularVelocity(1.2); 设置物体的初始角速度
创建形状
前面我们创建了物体(body), 但是仅仅创建物体是不够的, 物体更像是一个灵魂, 要想物体真实的存在在世界中,还需要定义物体的形状,然后通过夹具将这个形状连接在物体上。
形状是Box2D中管理与碰撞相关的几何结构,也可以设置物体的密度
1. 定义形状 PolygonShape ps = new PolygonShape();//定义形状:一个多边形
float box2Dw = box2d.scalarPixelsToWorld(150); 将像素尺寸转化为Box2D尺寸
float box2Dh = box2d.scalarPixelsToWorld(100);
ps.setAsBox(box2Dw, box2Dh);//用setAsBox()函数将形状定义为矩形
2.创建夹具,形状和物体现在是两个不相关的实体, 通过夹具可以将形状和物体连接在一起
FixtureDef fd = new FixtureDef();//创建夹具定义
fd.shape = ps;//将刚刚创建的PolygonShape对象赋给夹具对象
3.通过夹具可以设置它要连接的形状的属性
fd.friction = 0.3;//形状的摩擦系数,一般介于0~1;
fd.restitution = 0.5;//形状的复原性(也就是弹性):0~1;
fd.density = 1.0;//形状的密度,以kg/m2为单位
4.通过夹具将形状连接到物体上。
body.createFixture(fd);//创建夹具,将形状加到物体对象上
也可以不通过夹具设置物理属性直接绑定形状:body.createFixture(ps,1);//创建夹具,连接形状,将密度设为1
显示物体
创建一个显示函数,便于在draw()中调用
void display() {
Vec2 pos = box2d.getBodyPixelCoord(body);//获取物体的位置
float a = body.getAngle();//获取物体的角度
pushMatrix();
translate(pos.x, pos.y); 根据位置Vec2向量平移矩形,并根据角度旋转矩形
rotate(-a);//Box2D坐标系统的转动方向和Processing的是相反的,所以要乘-1
fill(175);
stroke(0);
rectMode(CENTER);
rect(0,0,w,h);
popMatrix();
}
void killBody() { 这个函数从Box2D世界中删除一个物体
box2d.destroyBody(body);
}