世界空间与本地空间
世界空间坐标系用于场景对象的组织,但是对象本质上还是存在于自身的本地坐标系中,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,它是一个组合数据,包含了碰撞相关的所有信息:
-
Collision Shape Index A: A对象的碰撞形状索引号(SceneObject回调的%this就是A)
-
Collision Shape Index B: B对象的碰撞形状索引号
-
Collision Normal: 碰撞法线
-
Contact World Point #1: 碰撞点世界坐标
-
Collision Normal Impulse #1: 法线方向的力
-
Collision Tangent Impulse #1: 切线方向的力
-
Contact World Point #2 (Only if two contacts): 这三个参数用于产生两个碰撞点的情况
-
Collision Normal Impulse #2 (Only if two contacts):
-
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"