logo资料库

JBox2D详解.doc

第1页 / 共48页
第2页 / 共48页
第3页 / 共48页
第4页 / 共48页
第5页 / 共48页
第6页 / 共48页
第7页 / 共48页
第8页 / 共48页
资料共48页,剩余部分请下载后查看
10.2 2D 的王者 JBox2D JBox2D 是开源的物理引擎 Box2D 的 Java 版本,可以直接用于 Android。由于 JBox2D 的图形渲 染使用的是 Processing 库,因此在 Android 平台上使用 JBox2D 时,图形渲染工作只能自行开发。该引擎 能够根据开发人员设定的参数,如重力、密度、摩擦系数和弹性系数等,自动地进行 2D 刚体物理运 动的全方位模拟。 每种物理引擎都有其独特的概念,在学习开源的物理引擎时,首先需要弄明白的就是其基本概念。 因此,本节主要为读者复习一下物理学中的一些基本概念,并介绍 JBox2D 中的一些常用类与概念。 10.2.1 基本的物理学概念 游戏是对真实世界的仿真,其中用到了许多物理学知识,如密度、质量、质心、摩擦 力、扭矩以及碰撞(恢复)系数等。接下来,本小节将简要介绍用 JBox2D 开发游戏时经常用到的一 些物理学概念。 密度 物理学中密度指的是单位体积的质量,符号为"ρ",常用单位为 kg/m^3。其是物质的一种基本特性, 不随物体的质量、体积的改变而改变,同种物质的密度相同。 质量 质量指的是物体中所含物质的量,即物体惯性的大小,国际单位是 kg。同一物体的质量通常是一个 常量,不因高度、经度或者纬度的改变而变化。但是根据爱因斯坦的相对论,同一物体的质量会随 着速度的变化而改变。只有运动接近光速才能感觉到这种变化,因此在游戏中一般不考虑速度对质 量的影响。 质心 物体(或物体系)的质量中心,是研究物体(或物体系)机械运动的一个重要参考点。当作用力 (或合力)通过该点时,物体只作移动而不发生转动;否则在发生移动的同时物体将绕该点转动。 研究质心的运动时,可将物体的质量看作集中于质心。理论上,质心是对物体的质量分布用"加权平 均法"求出的平均中心。 摩擦力 当两个互相接触的物体,如果要发生或者已经发生相对运动。就会在接触面上产生一种阻碍该相对 运动的力,这种力就称之为摩擦力。其基本情况如图 10-9 所示。 提示 根据物体是否发生相对运动可以分为静摩擦力与滑动摩擦力,实际开发中可以进行简化,但若 要模拟更加真实的效果就需要分别开发。 图 10-9 摩擦力示意图 扭矩 扭矩在物理学中就是力矩的大小,等于力与力臂的乘积,国际单位是 Nm(牛米)。在力臂不变的情 况下,力越大,扭矩越大。基本情况如图 10-10 所示。
恢复系数 两物体碰撞后的总动能与碰撞前的总动能之间的比称之为恢复系数,其取值范围为 0~1。如果恢复 系数为 1,则碰撞为完全弹性碰撞,满足机械能守恒;如果恢复系数小于 1 并且大于 0,则为非完全 弹性碰撞,不满足机械能守恒,这种情况是最常见的;如果恢复系数为 0,则为完全非弹性碰撞,两 个物体会粘在一起。基本情况如图 10-11 所示。 图 10-10 扭矩示意图 说明 在图 10-11 中,两个小球的质量相等,小球的初速度 V1 大于 V2。 图 10-11 各种碰撞情况 10.2.2 JBox2D 中常用类的介绍(1) 俗话说得好"基础不牢,地动山摇"。在学习新技术时,首先要学习的就是该技术的一些 基本概念,因此本小节主要介绍 JBox2D 中一些必知必会的类。 1.Vec2 类(二维向量) 该类属于 org.jbox2d.common 包,继承自 java.lang.Object 类,其对象用于表示一个二维向量 或二维笛卡尔坐标。二维向量 Vec2 类的基本功能如图 10-12 所示。
该类在 JBox2D 中的使用频率非常高,通常用于表示物体的位置、速度等,其构造器与常用方法及属 性如表 10-2 所列。 图 10-12 二维向量示意图 表 10-2 构造器与主要方法 方法、属性或构造器签名 说 明 public Vec2(float x,float y) 创 建 一 个 Vec2 的 对 象 , 该对象表示 X轴分量为 x,Y轴分量为 y 的一个 向量或坐标系中的(x,y)点 public static Vec2 abs(Vec2 a) 求向量的绝对值 public Vec2 add(Vec2 v) 返回该向量与另一向量的 和, 并不改变其中的任何一个 的值 类 型 构 造器 方 方 法 法 public Vec2 addLocal(Vec2 v) 返回该向量与另一向量的 方 和, 并改变当前的向量 public Vec2 clone() 复制向量 public float length() 返回该向量的长度 public float lengthSquared() 返回该向量长度的平方 public static Vec2 max(Vec2 返回两个向量中最大的 a,Vec2 b) public static Vec2 min(Vec2 返回两个向量中最小的 a,Vec2 b) public void set(float x,float y) 设置向量的两个分量 public void set(Vec2 v) 设置当前向量为向量 v public void setZero() 将向量设置为 0 向量 法 法 法 法 法 法 法 法 法 方 方 方 方 方 方 方 方 2.AABB 包围盒 该类属于 org.jbox2d.collision 包,继承自 java.lang.Object 类,表示轴对齐的边界盒子。所 谓的轴对齐是指,盒子左、右侧边界与 Y 轴平行,同时上、下侧边界与 X 轴平行,基本情况如图 10- 13 所示。
该类的构造器与常用方法及属性如表 10-3 所列。 表 10-3 构造器与常用方法 图 10-13 轴对齐 方法、属性或构造器 含 义 签名 public AABB() 创建 AABB 轴对齐的边界盒 子对象 public Vec2 lowerBound 此属性用于指定包围盒的 左、上边界 public Vec2 upperBound 此属性用于指定包围盒的 public boolean isValid() public boolean testOverlap (AABB box) 右、下边界 检查 AABB 对象是否合法 检测两个 AABB 对象是否重 叠(碰撞) 类 型 构 造器 属 属 方 方 性 性 法 法 提示 使用此类对象创建边界时,使用的度量单位为现实世界中的单位(m-米)。同时 AABB 应该永远 大于等于物体实际所占区域。 10.2.2 JBox2D 中常用类的介绍(2) 3.BodyDef 类(刚体描述) 该类属于 org.jbox2d.dynamics 包,继承自 java.lang.Object 类,其对象用于存储刚体的一些 描述性信息,主要是在创建刚体时调用。该类的构造器与常用方法及属性如表 10-4 所列。 表 10-4 构造器与常用方法 方法、属性或构造 含 义 器签名 public BodyDef() 创建 BodyDef 对象 public allowSleep boolean 是否允许刚体休眠的 标志位 public float angle 该刚体在世界坐标系 中的角度 类 型 构 造器 属 属 性 性
public boolean 设置是不是时刻检测 属 isBullet public isSleeping 碰撞 性 (一般为子弹类刚体 服务) boolean 表示刚体当前是否处 属 于 休眠状态的标志位 public MassData 刚体的质量 massData public Vec2 position 刚体的位置 性 性 性 属 属 4.World 类(世界) 该类属于 org.jbox2d.dynamics 包,继承自 java.lang.Object 类,表示的是物理世界。一个物 理世界就是物体、形状和约束相互作用的集合。JBox2D 支持同时创建多个世界,但这通常是不必要 的。要创建一个世界对象,首先需要创建一个世界的 AABB 包围盒,JBox2D 使用 AABB 包围盒来加速碰 撞检测。 该类构造器与常用方法及属性如表 10-5 所列。 表 10-5 构造器与常用方法 方法、属性或构造器签名 含 义 public World(AABB worldAABB, 创建 World 类的对象 Vec2 gravity,boolean doSleep) worldAABB —— 整 个 世 界 的 AABB 包围盒 gravity——重力向量 doSleep——是否允许刚体休眠 public Body createBody(BodyDef def) 根据给出的 BodyDef 对象创建 刚体 public Joint createJoint(JointDef 根据给出的 JointDef 对象创建 def) 关节 public void destroyBody(Body b) 从世界中销毁刚体,如游戏中 的 物体爆炸后消失就可以采用其 完成 public void destroyJoint(Joint j) 销毁关节,这个可能影响连 public int getBodyCount() 接的刚体进行碰撞 得到刚体的数量 public Body getBodyList() 得到刚体的列表 public Vec2 getGravity() 得到重力向量 类 型 构 造器 法 法 法 法 法 法 方 方 方 方 方 方 方
public AABB getWorldAABB() 得到世界的 AABB 包围盒对象 public void setGravity(Vec2 设置重力向量 gravity) public void step(float dt,int 进行一轮迭代模拟 iterations) 5.ShapeDef 类(形状描述) dt——模拟的频率 iterations—— 迭 代 次 数 。 迭 代越大, 模拟越精确、同时性能越低 法 法 法 法 方 方 方 该类属于 org.jbox2d.collision 包,继承自 java.lang.Object 类,其对象用来存储形状的描述 性信息。该类有两个子类,分别为 CircleDef(圆形描述),PolygonDef(多边形描述),3 个类的继承 关系如图 10-14 所示。 图 10-14 ShapeDef 类的继承树 10.2.2 JBox2D 中常用类的介绍(3) 该类的基本属性如表 10-6 所列。 表 10-6 ShapeDef 类属性 属性签名 含 义 public float density 密度,单位为 kg/m2 public float friction 摩擦系数 public float restitution 弹 性 系 数 ( 碰 撞 恢 复 系 数) public java.lang.Object 用这个来存储自定义的用 userData 户数据 6.CircleDef 类(圆形描述) 该类属于 org.jbox2d.collision 包,继承自 ShapeDef 类,其对象用于存储圆形的一些描述性 信息,如圆心坐标、半径等。该类的构造器及属性如表 10-7 所列。 表 10-7 CircleDef 类构造器及属性 构造器及属性签名 含 义 类 型
public CircleDef() 创建 CircleDef 构 public float radius 圆的半径 对象 public Vec2 localPosition 圆心坐标 造器 属 属 性 性 7.PolygonDef 类(多边形描述) 该类属于 org.jbox2d.collision 包,继承自 ShapeDef 类,其对象用于存储多边形的顶点信 息。要特别注意的是,这里的多边形指的是凸多边形,并且在卷绕凸多边形顶点时,顺序是顺时针 的。基本情况如图 10-15 所示。 图 10-15 凹凸多边形及卷绕顺序 该类的构造器与主要方法如表 10-8 所列。 表 10-8 PolygonDef 类构造器与常用方法 构造器及方法签名 含 义 public PolygonDef() 创 建 PolygonDef public addVertex(Vec2 v) public clearVertices() public getVertexCount() 对象 void 为该多边形添加 一个顶点 void 移除所有的顶点 int 得到顶点的数量 类 型 构 造器 方 方 方 法 法 法 续表 构造器及方法签名 含 义 public java.util.List getVertexList() 得到所有顶点的集合 public void setAsBox(float hx,float hy) 把多边形设定为一个 矩形的形状 hx — 宽度的一半 hy — 高度的一半 类 型 方 方 法 法 8.Body 类(刚体) 该类属于 org.jbox2d.dynamics 包,继承自 java.lang.Object 类,其对象表示一个刚体。在创
建该类的对象时,不可以直接从构造器创建,必须通过 World 类对象的.createBody(BodyDef bd)方法创 建。然后调用其 createShape(ShapeDef sd)方法创建刚体对应的几何形状,再调用 setMassFromShapes()方 法计算出该刚体的质量。 该类常用的方法如表 10-9 所列。 表 10-9 Body 类的常用方法 方法签名 含 义 public Shape createShape(ShapeDef 创建一个几何形状, def) 并将其添加进刚体中 public void destroyShape(Shape s) 销毁一个几何形状 public float getAngle() 获得角度(单位为弧度) public float getAngularVelocity() 获得角速度 public Vec2 getLinearVelocity 获得此刚体质心的平移速度 FromWorldPoint (Vec2 worldPoint) public float getMass() public Body getNext() 获得刚体的质量 获得列表中的下一个刚体 public Vec2 getPosition() 获得刚体定位点的位置 public Shape getShapeList() 获得刚体包含的几何形状的列 表 public World getWorld() 获得刚体所属的世界对象 public Vec2 getWorldCenter() 获得刚体质心在世界坐标系的 位置 public boolean isSleeping() 判断该刚体是不是活动的 public boolean isStatic() 判断该刚体是不是静止的 public void setMassFromShapes() 根据密度及几何形状自动计算 该刚体的质量 本小节对 JBox2D 中的一些常用类的基本原理与 API 进行了简要的介绍,详细的使用将在后继章节的具 体案例中一一给出。 10.3 球体撞击木块金字塔案例 上一小节主要介绍了 JBox2D 的一些基本概念,但是只讲概念就相当于纸上谈兵--不切实 际。而且考虑到大篇幅的概念介绍只会使得本章更显得枯燥,因此特意准备了几个小案例,以供参 考。首先给出一个钢球撞击木块金字塔的案例。 提示 由于本案例开发时使用了第三方的物理引擎 JBox2D,因此需要在项目中添加相应的 支持 jar 包"jbox2d-2.0.1-library-only.jar"。如果读者不清楚如何在 Eclipse 中为项目添加 jar 包,可以 查阅相关资料,本书篇幅所限不再赘述。没有 jar 包的读者可以到 JBox2D 的官方网站"www.jbox2d.org" 下载并解压即可。 10.3.1 案例运行效果 本小节给出的是一个钢球撞击木块金字塔的案例。案例一旦开始运行,从屏幕上方有一
分享到:
收藏