2013-03-27 146 views
0

我創建了這個函數,在我的渲染循環中調用以檢測碰撞並移動播放器/相機(這是第一人稱遊戲)使用名爲pCube的CubeGeometry檢測碰撞被移動到每幀匹配相機:使用THREE.Raycaster檢測碰撞

// Player movements 
function pMovements() { 
    mPlayer.colBottom = false; 

    pCube.position.x = mPlayer.yawObject.position.x + 50; // The cube is placed +50 so we can see/debug it. 
    pCube.position.y = mPlayer.yawObject.position.y - 10; 
    pCube.position.z = mPlayer.yawObject.position.z; 

    // -- COLLISION DETECTION START -- 
    var originPoint = pCube.position.clone(); 

    for (var vertexIndex = 0; vertexIndex < pCube.geometry.vertices.length; vertexIndex++) 
    {  
     var localVertex = pCube.geometry.vertices[vertexIndex].clone(); 
     var globalVertex = localVertex.applyMatrix4(pCube.matrix); 
     var directionVector = globalVertex.sub(pCube.position); 

     var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize()); 
     var collisionResults = ray.intersectObjects(collidableMeshList); 
     if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) { 

      // Bottom vertices 
      if (vertexIndex == 2 || vertexIndex == 3 || vertexIndex == 6 || vertexIndex == 7) { 
       mPlayer.colBottom = true; 
       mPlayer.velocity.y = Math.max(0, mPlayer.velocity.y); // Stop falling 
      } 
     } 
    } 
    // -- COLLISION DETECTION END -- 

    var delta = (Date.now() - time) * 0.1; 

    mPlayer.velocity.x += (-mPlayer.velocity.x) * 0.08 * delta; // walking 
    mPlayer.velocity.z += (-mPlayer.velocity.z) * 0.08 * delta; // walking 
    if (mPlayer.colBottom == false) { 
     mPlayer.velocity.y -= 0.1 * delta; // falling 
    } 

    if (mPlayer.moveForward) mPlayer.velocity.z -= mPlayer.speed * delta; 
    if (mPlayer.moveBack) mPlayer.velocity.z += mPlayer.speed * delta; 
    if (mPlayer.moveLeft) mPlayer.velocity.x -= mPlayer.speed * delta; 
    if (mPlayer.moveRight) mPlayer.velocity.x += mPlayer.speed * delta; 

    mPlayer.yawObject.translateX(mPlayer.velocity.x); 
    mPlayer.yawObject.translateY(mPlayer.velocity.y); 
    mPlayer.yawObject.translateZ(mPlayer.velocity.z); 

    if (mPlayer.yawObject.position.y < -2000) { 
     // Player has fallen out of bounds :(so re-initialise the players position 
     mPlayer.velocity.y = 0; 
     mPlayer.yawObject.position.y = 100; 
     mPlayer.yawObject.position.x = 0; 
     mPlayer.yawObject.position.z = 0; 

     mPlayer.yawObject.rotation.y = 0; 
     mPlayer.pitchObject.rotation.x = 0; 
    } 

    if (mPlayer.moveDown) { 
     mPlayer.yawObject.position.y -= 1; 
    } 
    if (mPlayer.moveUp) { 
     mPlayer.yawObject.position.y += 1; 
    } 
} 

Click here for the demo.
WASD移動。空間跳躍(排序)。黑色立方體/矩形在x軸上鏡像攝像機位置+50。在立方體上檢測到碰撞。

基本上我對這個兩個問題。我應該使用立方體的頂點來檢測碰撞還是面部?如果一個物體小於立方體,則不會檢測到碰撞,因爲它不會碰到任何頂點。那麼我應該改寫它的面孔呢?

其次,我怎麼能防止落立方體太遠下來檢測到碰撞時。如果你檢查演示,每當立方體掉下來的東西,它會停下來一段時間後停下來。我認爲有事情做與mPlayer.velocity.y,但我一直沒能解決它。即使跳躍也會讓立方體沉入地下。

+0

這是很難通過你張貼在你的鏈接代碼閱讀 - 我想人們應該看看HTML源鏈接到render.js,但註釋掉這麼多的代碼 - 它看起來像你放棄使用physi.js並自己照顧基礎物理?一個最簡單,乾淨的例子會讓診斷你的問題容易得多...... – 2013-03-28 04:00:52

回答

1

爲了增加您的碰撞檢測「的決議」,你可以添加更多的頂點到多維數據集,例如當您聲明pCube時,請嘗試:

pCube = new THREE.CubeGeometry(100,100,100, 5,5,5); 

並且您的其他代碼可能保持不變。

至於更小的物體碰撞檢測產生的射線,一般來說,如果您使用此方法,但有小物件創建射線「之間打滑」,那麼你會更準確地檢測碰撞。