天天看點

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/archive/2013/03/07/2947744.html