I want to detect collisions between dynamically created falling boxes and the ground. After the collision, a highscore increases & the boxes are removed from the scene.
Problem: Some boxes don't collide correctly, i.e. "collidestart" isn't fired in this case. Can somebody help me and have an advice for my problem?
I used Aframe 1.4.1 and ammo.js to detect the collisions.
body.html
<a-scene
game-logic
xrextras-runtime-error
renderer="colorManagement:true"
physics="driver: ammo; debug: true; gravity: 0, -1, 0"
xrweb="allowedDevices: any; defaultEnvironmentFloorScale: 0.4">
<a-assets>
<a-asset-item id="green-box" src="./assets/green-box.glb"></a-asset-item>
</a-assets>
<a-camera id="camera" position="0 20 32"> </a-camera>
<a-entity
light="
type: directional;
intensity: 0.8;
castShadow: true;
shadowMapHeight:2048;
shadowMapWidth:2048;
shadowCameraTop: 20;
shadowCameraBottom: -20;
shadowCameraRight: 20;
shadowCameraLeft: -20;
target: #camera"
xrextras-attach="target: camera; offset: 0 15 0"
position="1 4.3 2.5"
shadow>
</a-entity>
<a-light type="ambient" intensity="0.5"></a-light>
<a-box
id="ground"
box-collide
scale="1000 2 1000"
position="0 -1 0"
material="shader: shadow; transparent: true; opacity: 0.4"
ammo-body="type: static; emitCollisionEvents: true;"
ammo-shape="type: box"
shadow>
</a-box>
</a-scene>
logic.js
init() {
setInterval(() => {
this.addElements()
}, 4000)
},
addElements() {
const newElement = document.createElement('a-entity')
const randomX = Math.random() * 10
const randomZ = -(Math.random() * 10)
const landingPoint = {x: randomX, y: 32, z: randomZ}
newElement.setAttribute('position', landingPoint)
const randomXRotation = Math.random() * 360
const randomYRotation = Math.random() * 360
const randomZRotation = Math.random() * 360
newElement.setAttribute('rotation', `${randomXRotation} ${randomYRotation} 0 `)
newElement.setAttribute('visible', 'false')
newElement.setAttribute('scale', '3 3 3')
newElement.setAttribute('shadow', {
receive: false,
})
newElement.setAttribute('gltf-model', '#green-box')
document.querySelector('a-scene').appendChild(newElement)
newElement.addEventListener('model-loaded', () => {
newElement.setAttribute('visible', 'true')
let didCollide = false
setTimeout(() => {
newElement.setAttribute('ammo-body', {
type: 'dynamic',
mass: 200,
emitCollisionEvents: true,
})
newElement.setAttribute('ammo-shape', {
type: 'hull',
})
}, 200)
newElement.addEventListener('collidestart', (e) => {
console.log('collidestart --> not fired fired for every a-entity ', e)
if (!didCollide && e.detail.targetEl.body.el.id === 'ground') {
didCollide = true
setTimeout(() => {
if (newElement.parentNode) {
newElement.parentElement.removeChild(newElement)
}
}, 800)
}
})
})
},