В своей игре я создаю сферу (созданную с помощью а-сферы), динамическое тело, сталкивающееся с другим динамическим телом (прямоугольной рамкой).
При столкновении сфера разбивается на несколько меньших сфер. Мне нужно остановить этот распад
Вот код - сфера разбивается при столкновении с динамическим телом
Вот сопроводительный код -
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.info("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);
}
Есть ли способ остановить это, и сфера останется нетронутой после столкновения?
Сфера не ломается, происходит то, что ваш обработчик событий click
вызывается несколько раз для каждого щелчка и создает множество сфер одновременно. Я не совсем понимаю, почему это происходит. Один из способов обойти это - использовать AFRAME.utils.throttle
, чтобы предотвратить слишком быстрое создание сфер:
spawnBullet = AFRAME.utils.throttle(spawnBullet, 100);
scene.addEventListener('click', spawnBullet);
Обновление до более новой версии A-Frame также может решить проблему.
Прослушивание события click
на сцене приводит к обратным результатам, потому что вы получаете три события
- курсор излучает единицу при нажатии на что-то
- target
издает один при нажатии
- холст излучает один (щелчок мышью, а не курсор в виде рамки - на элементе холста DOM).
Вы можете увидеть это в примере это, щелкнуть любой объект на сцене и проверить консоль.
mousedown
event which is emitted by the cursor everytime its "clicked". Check it out здесьvive
then just call the shootBullet
when a trigger is pulled.
Убедитесь, что он работает правильно здесь.