Torque2D MIT 学习笔记(15) ---- 物理系统(1)

前言

  Torque2D的物理系统建立是以Box2D作为基础,Box2D是一个纯粹的面向2D刚体的物理仿真引擎,详细的说明这里跳过,有兴趣的朋友可以参考Box2D的使用手册,地址:

  http://wenku.baidu.com/view/dee1281c650e52ea551898a1.html###

  TorqueScript导出了Box2D大部分的物理特性,所以结合Box2D的手册来学习是一种有效的选择.

世界单位

  和其他的引擎一样,Torque2D使用浮点型的逻辑数值作为世界单位.像Box2D一样,在引擎中,世界单位是米,也就是说一个单位仿真现实中的一米.参照Box2D的原文:

  "Box2D使用浮点数,所以必须使用一些公差来保证它正常工作.这些公差已经被调节的适合米/千克/秒(MKS)单位.尤其是,Box2D被调节的能够良好的处理0.1到10米之间移动的物体.

  这意味着从罐头到公交车大小的对象都能良好的工作."  

  屏幕上的物理有效区域依赖于相机的视野范围.如果你不能理解这个设定,并且创建了一个以一个每个像素为一米的对象,那么你不要指望它能够有预期的物理表现,这不是Toque的问题,而是Box2D.

  但是Box2D有自己的说法,那就是如果你的对象是500*500个世界单位,那么你这个物体就是250000平方的巨大物理(陨石了...).如果作为一个静态或者动态都会遇到一个精度问题,那就是它需要受到多么大的作用力.

计时更新与插值

  物理系统1/60秒更新一次,当渲染足够快时,渲染很多次才会有一次的物理系统更新,由此产生了一个问题就是在1/60之间的多次渲染的某个运动物体看上去是不动的.

  如果FPS比较低,那么就会出现卡顿,瞬移的情况,这就需要每帧的插值,比如角度,位置,使得物理表现尽可能的平滑.

场景与物理世界

  物理系统有自己的环境来处理物理对象,这个环境叫做"物理世界".在Torque2D中,已经将物理世界和Scene场景合二为一,只需要简单的设置几个变量就可以让整个场景变得有物理特性.  

  一个物理世界有多个特性值,最重要的莫过于重力向量,下面是一个具体的例子:  

%scene = new Scene();
// 设定重力向量
%scene.setGravity( 0, -9.8 );
或者:
// 设定重力向量
%scene.Gravity = "0 -9.8";

  重力参数有X/Y轴向两个变量组成,比如上面的就是垂直Y方向设定-9.8m/s的仿真地球重力.重力对物理世界中的所有动态物体都有作用.动态物理在下文中会有介绍.  

物体类型

  静态物体  

    静态物体不会与其他静态物体或者kinematic物体进行碰撞,通常静态物体是不可以移动的,不过你仍然可以设定它的位置,但是如果你想通过设定线性或者旋转速度,那是没有效果的.

    理论上你可以自由的设定静态物体的位置,但是因为这会影响性能,最好不要这么做.  

    由于静态物体不受环境重力的影响,不需要在每次的仿真更新中参与计算,所以有这最高的性能,我们可以尽可能的用它.  

  动态物体

    动态类型是所有t2d场景对象的默认类型,你可以创建并处理相关的物理模拟.与静态物体不同,它可以和所有的物理直接中的对象进行碰撞,并且可以驱使他们移动.这种类型的物体主要是被用来表现可以在场景中自由行动并且具有线性速度和角速度特性的场景元素.因为动态类型的物体需要处理很多的运算,所以不能将所有的场景对象都默认设置为动态的,物尽其用才是王道.    

    由于动态物体会受到环境重力的影响,所以会产生一种容易迷惑的现象,那就是当一个动态物体刚被创建并加入到物理世界中,它马上会受到重力作用移动位置,这样可能会造成当需要看到这个物体的时候这个物体已经不再屏幕之内,掉到很远很远的地方去了.

    还有一种方式可以调节重力的影响,用setGravityScale来调节对象对环境重力的作用比例.

  Kinematic物体

    这种类型很少使用,但是在特殊的情况下很有用,因为Kinematic对象不会和同类对象发生碰撞,只会和静态,动态的对象碰撞.

    Kinematic对象的移动依赖于线性或者旋转速度,而非外来力量.所以我们通常是直接设置它的这两种速度来让他移动.

  配置

    如果你想修改一种物体的类型,那么最好在将它加入场景世界之前进行,这样能获得最佳的性能.

    同时最好在加入场景之前设置好他们的初始化位置,如果都放进场景默认位置,比如0,0点,然后再设置位置,那么中间会发生很多次的碰撞检测,影响效率.配置方法如下:

%obj = new SceneObject();

%obj.BodyType = static;
%obj.BodyType = dynamic;
%obj.BodyType = kinematic;
// 或者
%obj.SetBodyType( static );
%obj.SetBodyType( dynamic );
%obj.SetBodyType( kinematic );

激活(Active)

  一个单纯的物理开关属性,来设定场景对象在物理世界中是否存在,当设定为false的时候,它将被从物理世界剔除,不会与其他对象发生关系也不会受制于速度属性和外来力量.它与是否渲染无关,只是物理变量.  

%obj = new SceneObject();

%obj.Active = false;

唤醒(Awake)

  在物理系统中,当一个对象不动或者没有任何外在力来接触它的时候,就会用到这个属性,在这种情况下,仿真的结果就是将对象认为是"睡着"了.这么做会节省很大的计算开销.如果有外在力量或者速度属性,位置改变的时候,睡眠的对象会自动被唤醒.

  在引擎中,所有的场景对象都被默认为唤醒状态,但是为了最佳的性能,开发者需要根据具体的需要来初始设定它的唤醒状态,而不是等待物理系统的仿真结果来解决它是否应该"睡眠".具体方法如下:

%obj = new SceneObject();
// 初始为睡眠状态,默认为真
%obj.Awake = false;
// 是否允许自动睡眠,默认为真
%obj.SleepingAllowed = false;

子弹(快速移动物体)

  "子弹"类型是指那些移动非常快速的物体.默认的碰撞算法只适用于低速或者中速的移动方式来计算他们物理计算的平衡和精度.而高速物体会直接击穿这些低速的物体.大多数情况下我们看不到这种对象,但是当你要做一款"射击游戏"的时候,就会用到子弹类型的对象.Box2D会采用一种叫做CCD(连续碰撞检测)的算法来模拟高速移动,这个的代价会很高.引擎默认这个属性是关闭的,具体使用如下:

%obj = new SceneObject();
// 子弹
%obj.Bullet = true;

位置,角度,速度

  一个对象有四种基本的物理属性,分别是位置,角度,线性速度,角速度,参考下面的代码:

%obj = new SceneObject();

// X/Y
%obj.Position = "10 20"

// 角度(in degrees)
%obj.Angle = 30; 

// 线性速度(米/秒)
%obj.LinearVelocity = "5 8";

// 角速度(角度/秒)
%obj.AngularVelocity = 10;

   与角度相关的还有一个方法,用来固定角度,使得后续的角度设定无效:

%obj.FixedAngle = true;

引力响应比例

  物理世界有环境引力设置,这个是全局的,对整个世界中的所有动态物体都有作用.但是有些时候特定对象需要打破这个定律,模拟脱离引力控制的表现,这就需要修改引力响应比例.

%obj.GravityScale = 0.5; // 只受控于一半的世界引力
%obj.GravityScale = 0; // 不受引力控制

 

posted on 2013-03-07 09:52  Kevin Game  阅读(1512)  评论(0编辑  收藏  举报