forked from n5ro/aframe-physics-system
-
Notifications
You must be signed in to change notification settings - Fork 11
/
rain-of-entities.js
90 lines (78 loc) · 2.47 KB
/
rain-of-entities.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
* Rain of Entities component.
*
* Creates a spawner on the scene, which periodically generates new entities
* and drops them from the sky. Objects falling below altitude=0 will be
* recycled after a few seconds.
*
* Requires: physics
*/
AFRAME.registerComponent('rain-of-entities', {
schema: {
tagName: { default: 'a-box' },
components: { default: ['dynamic-body', 'force-pushable', 'color|#39BB82', 'scale|0.2 0.2 0.2'] },
spread: { default: 10, min: 0 },
maxCount: { default: 10, min: 0 },
interval: { default: 1000, min: 0 },
lifetime: { default: 10000, min: 0 }
},
init: function () {
this.boxes = [];
this.timeout = setInterval(this.spawn.bind(this), this.data.interval);
},
spawn: function () {
if (this.boxes.length >= this.data.maxCount) {
clearTimeout(this.timeout);
return;
}
var data = this.data,
physics = this.el.sceneEl.systems.physics,
box = document.createElement(data.tagName);
this.boxes.push(box);
this.el.appendChild(box);
box.setAttribute('position', this.randomPosition());
data.components.forEach(function (s) {
var parts = s.split('|');
box.setAttribute(parts[0], parts[1] || '');
});
// Recycling is important, kids.
setInterval(function () {
if (box.object3D.position.y > 0) return;
this.recycleBox(box);
}.bind(this), this.data.lifetime);
},
randomPosition: function () {
var spread = this.data.spread;
return {
x: Math.random() * spread - spread / 2,
y: 3,
z: Math.random() * spread - spread / 2
};
},
recycleBox(box) {
if (box.body.position) {
this.recycleBoxCannon(box)
}
else {
this.recycleBoxAmmo(box)
}
},
recycleBoxCannon(box) {
box.body.position.copy(this.randomPosition());
box.body.quaternion.set(0, 0, 0, 1);
box.body.velocity.set(0, 0, 0);
box.body.angularVelocity.set(0, 0, 0);
box.body.updateProperties();
},
recycleBoxAmmo(box) {
// recycling (i.e. teleporting an object to a new position / velocity) is
// not something that can be done in Ammo.
// instead we remove the ammo-body component, modify the object3D position & re-add the ammo-body.
box.removeAttribute("ammo-shape")
box.removeAttribute("ammo-body")
box.object3D.position.copy(this.randomPosition());
box.object3D.quaternion.identity();
box.setAttribute("ammo-body", "")
box.setAttribute("ammo-shape", "")
}
});