Torque2D MIT 学习笔记(16) 物理系统(2)

世界空间与本地空间

  世界空间坐标系用于场景对象的组织,但是对象本质上还是存在于自身的本地坐标系中,Torque的本地坐标系原点为对象的中心位置.

  另外两种坐标系的XY轴不是重合的,本地坐标系的轴与其当前旋转角度有关.

  引擎提供了相关的坐标系转换方法,如下:  

getLocalPoint( worldPoint )
getWorldPoint( localPoint )
getLocalVector( worldVector )
getWorldVector( localVector )

质心

  当你为一个场景对象设置碰撞形状的时候,引擎同时会根据它的密度计算出质量.但是可能由于对象的形状不对称,质量不一样,质心的位置也会有所不同.获取质心位置的方法有:

getLocalCenter()
getWorldCenter()

  在你对一个对象施加外力的时候,质心这个参数是非常重要的,比如如果在质心位置施加一个推动力,那么物体就不会旋转.

  PS: 质心不是对象的中心位置.

碰撞形状

  Torque支持四种形状的碰撞检测:

    圆形: 最高的效率,半径要大于0才有效.

    多边形(凸多边形): 不能超过8个定点(改代码可以更多),不过判断的效率不如其他几种,作者不推荐.

    边界: 也就是线段

    链: 类似于边界碰撞,但是它还允许指定多条连续的边界线段共同组成链.

  PS:所有的形状都是米作为单位.

碰撞形状的创建  

createCircleCollisionShape( radius, [position] )
createPolygonCollisionShape( points )
createPolygonBoxCollisionShape(width, height, [position, angle] )
createChainCollisionShape( points, [adjacentStartPoint], [adjacentEndPoint] )
createEdgeCollisionShape( startPoint, endPoint, [adjacentStartPoint], [adjacentEndPoint] )

 如果创建失返回-1,否则返回序号,脚本使用:

%obj = new SceneObject();

%obj.createCircleCollisionShape( 3 );
%obj.createPolygonCollisionShape( %points );
%obj.createPolygonBoxCollisionShape( 4, 3 );
%obj.createChainCollisionShape( %points );
%obj.createEdgeCollisionShape( %startPoint, %endPoint );

 删除的方法为:  

deleteCollisionShape( index )
// 脚本
%obj.deleteCollisionShape( %shapeIndex );

碰撞形状的基本参数配置

  物体要参与碰撞,出了形状外还需要一些基本的参数,比如密度,回复系数,摩擦力等等,引擎提供了一些方法便于设置/查询它们:

setCollisionShapeDensity(index, density)
getCollisionShapeDensity(index)
setCollisionShapeFriction(index, friction)
getCollisionShapeFriction(index)
setCollisionShapeRestitution(index, restitution)
getCollisionShapeRestitution(index)
setCollisionShapeIsSensor(index, isSensor?)
getCollisionShapeIsSensor(index)

碰撞控制

 上面说了如何将一个场景对象配置成为具有期望的碰撞效果物体,下面说说如何控制对象间的碰撞,或者说"接触".

 一个最基本的需求,那就是我们如何设定什么对象能和什么对象进行碰撞,而不与其他无关的对象接触或者说允许他们重叠?答案是分层,分组.

 在Torque2D中,一共提供了0-31(32层)的场景层,0在最前,31在最后面,可以通过设定对象的碰撞层来控制它与什么对象进行碰撞接触.方法如下:  

%obj = new SceneObject();

// 任选其一,功能一样
%obj.setCollisionLayers( 5, 6, 7 );
%obj.setCollisionLayers( "5 6 7" );
%obj.CollisionLayers = "5 6 7";

  进一步又有一个问题,那就是如果同层的对象也有碰撞过滤的功能呢? 答案是分组  

// 任选其一,功能一样
%obj.setCollisionGroups( 20, 30 );
%obj.setCollisionGroups( "20 30" );
%obj.CollisionGroups = "20 30";

 下面用一个实际的例子片段来解释用法:

// 玩家与敌人的游戏

// 玩家分到碰撞组10号
%player = new SceneObject();
%player.createCircleCollisionShape( 1 );
%player.SceneGroup = 10;

// 敌人分到碰撞组20号
%enemy = new SceneObject();
%enemy.createCircleCollisionShape( 1 );
%enemy.SceneGroup = 20;

// 设置玩家和20组的对象发生碰撞
%player.setCollisionGroups( 20 );

// 设置敌人和10组的对象发生碰撞
%enemy.setCollisionGroups( 10 );

如果是单对单的碰撞控制,可以使用另一个方法:

%objA.setCollisionAgainst( %objB );

 除此之外,还有一些组合设置,这里不做介绍,可以参照源代码.碰撞回调

 关于碰撞回调,在http://www.cnblogs.com/KevinYuen/archive/2013/03/05/2944966.html中有过一次介绍,下面对其他方面介绍一下:

 Torque2D支持两种碰撞回调,一种是通告给所属场景,一种是给具体对象绑定的脚本对象.  

function Scene::onSceneCollision( %this, %sceneObjectA, %sceneObjectB, %collisionDetails )
{
}
function SceneObject::onCollision( %this, %sceneObject, %collisionDetails )
{
}

 关于%collisionDetails,它是一个组合数据,包含了碰撞相关的所有信息:  

  1. Collision Shape Index A: A对象的碰撞形状索引号(SceneObject回调的%this就是A)
  2. Collision Shape Index B: B对象的碰撞形状索引号
  3. Collision Normal: 碰撞法线
  4. Contact World Point #1: 碰撞点世界坐标
  5. Collision Normal Impulse #1: 法线方向的力
  6. Collision Tangent Impulse #1: 切线方向的力
  7. Contact World Point #2 (Only if two contacts): 这三个参数用于产生两个碰撞点的情况
  8. Collision Normal Impulse #2 (Only if two contacts):
  9. Collision Tangent Impulse #2 (Only if two contacts):

  举个例子:  

// Collision Shape A Index = 0
// Collision Shape B Index = 2
// Collision Normal = (0.0, 1.0)
// Contact World Point #1 = (100.0, 50.0)
// Normal Impulse #1 = 30.0
// Tangent Impulse #1 = 0.0
// Contact World Point #2 = (100.0, 60.0)
// Normal Impulse #2 = 40.0
// Tangent Impulse #2 = 0.0
"0 2 0.0 1.0 100.0 50.0 30.0 0.0 100.0 50.0 40.0 0.0"

  

原文地址:https://www.cnblogs.com/KevinYuen/p/2947744.html