Aframe物理球在碰撞时会分裂成较小的球

时间:2018-08-01 11:12:29

标签: collision-detection game-physics aframe cannon.js

在我的游戏中,我制作一个球体(使用a球体创建),一个动态物体,并与另一个动态物体(a-box)碰撞。

在碰撞时,球体会分成多个较小的球体。我需要停止这种瓦解

这是codepen-sphere breaks on collision with dynamic body

这是随附的代码-

HTML

<a-scene physics="debug: true; gravity: -5.0">
  <a-entity camera="userHeight: 1.6"
                look-controls
                kinematic-body>
        <a-entity cursor
                  position="0 0 -1"
                  geometry="primitive: circle; radius: 0.01; segments: 4;"
                  material="color: #FF4444; shader: flat"></a-entity>
    <a-entity position="0 0 1" id="attachment"></a-entity>
  </a-entity>

  <a-entity geometry="primitive: box; height:2" material="color: black; shader: flat" position="0 2 -5" dynamic-body></a-entity>

  <a-plane static-body color="#ccc" height="100" width="100" position="0 -0.1 0" rotation="-90 0 0"></a-plane>
</a-scene>

和JS

const scene = document.querySelector('a-scene');
const camera = document.querySelector('[camera]');
const attachment = document.querySelector('#attachment');

function spawnBullet() {
    let entity = document.createElement('a-sphere');
    let impulseAmount = 8;

    entity.setAttribute('radius', 1);
    // Set initial position of projectile to that of the camera.
    entity.setAttribute('position', camera.getAttribute('position'));
    entity.setAttribute('color', '#00FFCC');
    entity.setAttribute('shader', 'flat');
    entity.setAttribute('mass', 10);

    // Append projectile to the scene, not to the camera, to
    // avoid all sorts of complications. Most notably, CANNON.js
    // has no scene graph or nesting.
    scene.appendChild(entity);

    entity.setAttribute('dynamic-body', true);  

    entity.addEventListener('body-loaded', function(){
      // Can't apply forces during the same tick that attaches the body, because
      // it hasn't been fully synced to the physics sim. (bug)
      setTimeout(function () {
        let pStart = new CANNON.Vec3();
        // Use an origin point behind the head, not at the head, so
        // there's a useful vector between the origin and the projectile.
        pStart.copy(attachment.object3D.getWorldPosition());
        let force = entity.body.position.vsub(pStart);
        force.normalize(); 
        force.scale(impulseAmount, force);
        entity.body.applyImpulse(force, entity.body.position);
      }, 0);

      entity.addEventListener('collide', function(e){
        console.log("hit");
      })
    });
}

if (scene.hasLoaded) init(); // change 2
else scene.addEventListener('loaded', init);

function init () {
  // any code that appends things to the scene
  scene.addEventListener('click', spawnBullet);
}

有没有一种方法可以停止碰撞并且球体在碰撞后保持完好无损?

2 个答案:

答案 0 :(得分:2)

范围没有破裂,正在发生的是,您的click事件处理程序每​​次单击都被调用多次,并一次创建多个范围。我不确定为什么会这样。解决此问题的一种方法,使用AFRAME.utils.throttle来防止太快地创建球体:

spawnBullet = AFRAME.utils.throttle(spawnBullet, 100);
scene.addEventListener('click', spawnBullet);

更新到新版本的A-Frame也可以解决此问题。

答案 1 :(得分:2)

在现场观看click事件的过程令人反感,因为您收到了三个事件
-单击某物时光标会发出一个
-target在点击时会发出一个
-画布发出一个(鼠标单击,而不是DOM画布元素上的A帧光标)。

您可以在this示例中看到它,单击场景上的任何对象,然后检出控制台。


您可以侦听光标每次“单击”时发出的mousedown事件。签出here
只要您在PC上,您还可以收听无边框画布上的点击。如果您使用的是vive,则只需在扳动触发器时调用shootBullet

检查它是否可以正常工作here