melonjs 14.0.2 → 14.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/README.md +2 -0
  2. package/dist/melonjs.mjs/_virtual/_commonjsHelpers.js +10 -0
  3. package/dist/melonjs.mjs/_virtual/arraymultimap.js +10 -0
  4. package/dist/melonjs.mjs/_virtual/earcut.js +10 -0
  5. package/dist/melonjs.mjs/_virtual/howler.js +10 -0
  6. package/dist/melonjs.mjs/_virtual/index.js +10 -0
  7. package/dist/melonjs.mjs/_virtual/index2.js +10 -0
  8. package/dist/melonjs.mjs/_virtual/multimap.js +10 -0
  9. package/dist/melonjs.mjs/_virtual/setmultimap.js +10 -0
  10. package/dist/melonjs.mjs/application/application.js +238 -0
  11. package/dist/melonjs.mjs/audio/audio.js +536 -0
  12. package/dist/melonjs.mjs/camera/camera2d.js +731 -0
  13. package/dist/melonjs.mjs/entity/entity.js +247 -0
  14. package/dist/melonjs.mjs/game.js +29 -0
  15. package/dist/melonjs.mjs/geometries/ellipse.js +274 -0
  16. package/dist/melonjs.mjs/geometries/line.js +115 -0
  17. package/dist/melonjs.mjs/geometries/path2d.js +318 -0
  18. package/dist/melonjs.mjs/geometries/point.js +88 -0
  19. package/dist/melonjs.mjs/geometries/poly.js +498 -0
  20. package/dist/melonjs.mjs/geometries/rectangle.js +374 -0
  21. package/dist/melonjs.mjs/geometries/roundrect.js +167 -0
  22. package/dist/melonjs.mjs/index.js +248 -0
  23. package/dist/melonjs.mjs/input/gamepad.js +501 -0
  24. package/dist/melonjs.mjs/input/input.js +26 -0
  25. package/dist/melonjs.mjs/input/keyboard.js +470 -0
  26. package/dist/melonjs.mjs/input/pointer.js +393 -0
  27. package/dist/melonjs.mjs/input/pointerevent.js +818 -0
  28. package/dist/melonjs.mjs/lang/deprecated.js +157 -0
  29. package/dist/melonjs.mjs/level/level.js +297 -0
  30. package/dist/melonjs.mjs/level/tiled/TMXGroup.js +141 -0
  31. package/dist/melonjs.mjs/level/tiled/TMXLayer.js +446 -0
  32. package/dist/melonjs.mjs/level/tiled/TMXObject.js +355 -0
  33. package/dist/melonjs.mjs/level/tiled/TMXTile.js +193 -0
  34. package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +636 -0
  35. package/dist/melonjs.mjs/level/tiled/TMXTileset.js +309 -0
  36. package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +81 -0
  37. package/dist/melonjs.mjs/level/tiled/TMXUtils.js +367 -0
  38. package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +504 -0
  39. package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +218 -0
  40. package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +155 -0
  41. package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +124 -0
  42. package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +107 -0
  43. package/dist/melonjs.mjs/loader/loader.js +801 -0
  44. package/dist/melonjs.mjs/loader/loadingscreen.js +120 -0
  45. package/dist/melonjs.mjs/loader/melonjs_logo.png.js +11 -0
  46. package/dist/melonjs.mjs/math/color.js +616 -0
  47. package/dist/melonjs.mjs/math/math.js +218 -0
  48. package/dist/melonjs.mjs/math/matrix2.js +501 -0
  49. package/dist/melonjs.mjs/math/matrix3.js +679 -0
  50. package/dist/melonjs.mjs/math/observable_vector2.js +469 -0
  51. package/dist/melonjs.mjs/math/observable_vector3.js +559 -0
  52. package/dist/melonjs.mjs/math/vector2.js +526 -0
  53. package/dist/melonjs.mjs/math/vector3.js +567 -0
  54. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/arraymultimap.js +73 -0
  55. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/index.js +21 -0
  56. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/multimap.js +324 -0
  57. package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/setmultimap.js +69 -0
  58. package/dist/melonjs.mjs/node_modules/earcut/src/earcut.js +691 -0
  59. package/dist/melonjs.mjs/node_modules/eventemitter3/index.js +350 -0
  60. package/dist/melonjs.mjs/node_modules/howler/dist/howler.js +3241 -0
  61. package/dist/melonjs.mjs/particles/emitter.js +265 -0
  62. package/dist/melonjs.mjs/particles/particle.js +186 -0
  63. package/dist/melonjs.mjs/particles/settings.js +319 -0
  64. package/dist/melonjs.mjs/physics/body.js +702 -0
  65. package/dist/melonjs.mjs/physics/bounds.js +459 -0
  66. package/dist/melonjs.mjs/physics/collision.js +132 -0
  67. package/dist/melonjs.mjs/physics/detector.js +194 -0
  68. package/dist/melonjs.mjs/physics/quadtree.js +394 -0
  69. package/dist/melonjs.mjs/physics/response.js +57 -0
  70. package/dist/melonjs.mjs/physics/sat.js +483 -0
  71. package/dist/melonjs.mjs/physics/world.js +219 -0
  72. package/dist/melonjs.mjs/plugin/plugin.js +141 -0
  73. package/dist/melonjs.mjs/renderable/collectable.js +60 -0
  74. package/dist/melonjs.mjs/renderable/colorlayer.js +78 -0
  75. package/dist/melonjs.mjs/renderable/container.js +1016 -0
  76. package/dist/melonjs.mjs/renderable/dragndrop.js +224 -0
  77. package/dist/melonjs.mjs/renderable/imagelayer.js +305 -0
  78. package/dist/melonjs.mjs/renderable/light2d.js +155 -0
  79. package/dist/melonjs.mjs/renderable/nineslicesprite.js +246 -0
  80. package/dist/melonjs.mjs/renderable/renderable.js +781 -0
  81. package/dist/melonjs.mjs/renderable/sprite.js +653 -0
  82. package/dist/melonjs.mjs/renderable/trigger.js +156 -0
  83. package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +212 -0
  84. package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +225 -0
  85. package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +127 -0
  86. package/dist/melonjs.mjs/state/stage.js +236 -0
  87. package/dist/melonjs.mjs/state/state.js +596 -0
  88. package/dist/melonjs.mjs/system/device.js +909 -0
  89. package/dist/melonjs.mjs/system/dom.js +78 -0
  90. package/dist/melonjs.mjs/system/event.js +537 -0
  91. package/dist/melonjs.mjs/system/platform.js +41 -0
  92. package/dist/melonjs.mjs/system/pooling.js +209 -0
  93. package/dist/melonjs.mjs/system/save.js +157 -0
  94. package/dist/melonjs.mjs/system/timer.js +286 -0
  95. package/dist/melonjs.mjs/text/bitmaptext.js +363 -0
  96. package/dist/melonjs.mjs/text/bitmaptextdata.js +198 -0
  97. package/dist/melonjs.mjs/text/glyph.js +65 -0
  98. package/dist/melonjs.mjs/text/text.js +452 -0
  99. package/dist/melonjs.mjs/text/textmetrics.js +175 -0
  100. package/dist/melonjs.mjs/text/textstyle.js +23 -0
  101. package/dist/melonjs.mjs/tweens/easing.js +336 -0
  102. package/dist/melonjs.mjs/tweens/interpolation.js +112 -0
  103. package/dist/melonjs.mjs/tweens/tween.js +479 -0
  104. package/dist/melonjs.mjs/utils/agent.js +76 -0
  105. package/dist/melonjs.mjs/utils/array.js +63 -0
  106. package/dist/melonjs.mjs/utils/file.js +42 -0
  107. package/dist/melonjs.mjs/utils/function.js +70 -0
  108. package/dist/melonjs.mjs/utils/string.js +82 -0
  109. package/dist/melonjs.mjs/utils/utils.js +173 -0
  110. package/dist/melonjs.mjs/video/canvas/canvas_renderer.js +806 -0
  111. package/dist/melonjs.mjs/video/renderer.js +410 -0
  112. package/dist/melonjs.mjs/video/texture/atlas.js +519 -0
  113. package/dist/melonjs.mjs/video/texture/cache.js +143 -0
  114. package/dist/melonjs.mjs/video/texture/canvas_texture.js +144 -0
  115. package/dist/melonjs.mjs/video/video.js +462 -0
  116. package/dist/melonjs.mjs/video/webgl/buffer/vertex.js +142 -0
  117. package/dist/melonjs.mjs/video/webgl/glshader.js +167 -0
  118. package/dist/melonjs.mjs/video/webgl/shaders/primitive.frag.js +10 -0
  119. package/dist/melonjs.mjs/video/webgl/shaders/primitive.vert.js +10 -0
  120. package/dist/melonjs.mjs/video/webgl/shaders/quad.frag.js +10 -0
  121. package/dist/melonjs.mjs/video/webgl/shaders/quad.vert.js +10 -0
  122. package/dist/melonjs.mjs/video/webgl/utils/attributes.js +25 -0
  123. package/dist/melonjs.mjs/video/webgl/utils/precision.js +20 -0
  124. package/dist/melonjs.mjs/video/webgl/utils/program.js +67 -0
  125. package/dist/melonjs.mjs/video/webgl/utils/string.js +25 -0
  126. package/dist/melonjs.mjs/video/webgl/utils/uniforms.js +92 -0
  127. package/dist/melonjs.mjs/video/webgl/webgl_compositor.js +494 -0
  128. package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +1035 -0
  129. package/dist/melonjs.module.d.ts +1298 -1359
  130. package/dist/melonjs.module.js +2072 -3520
  131. package/package.json +21 -16
  132. package/src/application/application.js +4 -5
  133. package/src/audio/audio.js +32 -32
  134. package/src/camera/camera2d.js +32 -33
  135. package/src/entity/entity.js +18 -19
  136. package/src/geometries/ellipse.js +17 -18
  137. package/src/geometries/line.js +6 -7
  138. package/src/geometries/path2d.js +33 -34
  139. package/src/geometries/point.js +1 -2
  140. package/src/geometries/poly.js +16 -18
  141. package/src/geometries/rectangle.js +19 -20
  142. package/src/geometries/roundrect.js +9 -10
  143. package/src/input/gamepad.js +15 -15
  144. package/src/input/keyboard.js +12 -12
  145. package/src/input/pointer.js +6 -6
  146. package/src/input/pointerevent.js +12 -12
  147. package/src/lang/deprecated.js +12 -12
  148. package/src/level/level.js +25 -25
  149. package/src/level/tiled/TMXLayer.js +23 -24
  150. package/src/level/tiled/TMXTile.js +6 -7
  151. package/src/level/tiled/TMXTileMap.js +8 -10
  152. package/src/level/tiled/TMXTileset.js +3 -4
  153. package/src/level/tiled/TMXTilesetGroup.js +1 -2
  154. package/src/level/tiled/TMXUtils.js +5 -5
  155. package/src/level/tiled/renderer/TMXHexagonalRenderer.js +3 -4
  156. package/src/level/tiled/renderer/TMXIsometricRenderer.js +3 -4
  157. package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +2 -3
  158. package/src/level/tiled/renderer/TMXRenderer.js +20 -21
  159. package/src/level/tiled/renderer/TMXStaggeredRenderer.js +1 -2
  160. package/src/loader/loader.js +20 -20
  161. package/src/math/color.js +21 -22
  162. package/src/math/math.js +16 -16
  163. package/src/math/matrix2.js +17 -18
  164. package/src/math/matrix3.js +26 -27
  165. package/src/math/observable_vector2.js +15 -16
  166. package/src/math/observable_vector3.js +17 -18
  167. package/src/math/vector2.js +10 -11
  168. package/src/math/vector3.js +11 -12
  169. package/src/particles/emitter.js +7 -8
  170. package/src/particles/particle.js +3 -4
  171. package/src/physics/body.js +29 -30
  172. package/src/physics/bounds.js +10 -10
  173. package/src/physics/collision.js +2 -2
  174. package/src/physics/detector.js +6 -6
  175. package/src/physics/quadtree.js +18 -23
  176. package/src/physics/sat.js +31 -31
  177. package/src/physics/world.js +6 -7
  178. package/src/plugin/plugin.js +5 -5
  179. package/src/renderable/collectable.js +4 -6
  180. package/src/renderable/colorlayer.js +6 -8
  181. package/src/renderable/container.js +25 -27
  182. package/src/renderable/dragndrop.js +14 -14
  183. package/src/renderable/imagelayer.js +14 -15
  184. package/src/renderable/light2d.js +4 -5
  185. package/src/renderable/nineslicesprite.js +17 -18
  186. package/src/renderable/renderable.js +26 -28
  187. package/src/renderable/sprite.js +29 -30
  188. package/src/renderable/trigger.js +16 -17
  189. package/src/renderable/ui/uibaseelement.js +8 -9
  190. package/src/renderable/ui/uispriteelement.js +8 -8
  191. package/src/renderable/ui/uitextbutton.js +15 -15
  192. package/src/state/stage.js +8 -9
  193. package/src/state/state.js +17 -17
  194. package/src/system/device.js +11 -11
  195. package/src/system/event.js +10 -10
  196. package/src/system/pooling.js +9 -9
  197. package/src/system/save.js +2 -2
  198. package/src/system/timer.js +10 -10
  199. package/src/text/bitmaptext.js +19 -20
  200. package/src/text/bitmaptextdata.js +3 -4
  201. package/src/text/glyph.js +1 -2
  202. package/src/text/text.js +24 -25
  203. package/src/text/textmetrics.js +9 -10
  204. package/src/tweens/tween.js +20 -21
  205. package/src/utils/agent.js +5 -5
  206. package/src/utils/array.js +4 -4
  207. package/src/utils/file.js +2 -2
  208. package/src/utils/function.js +6 -6
  209. package/src/utils/string.js +5 -5
  210. package/src/utils/utils.js +4 -4
  211. package/src/video/canvas/canvas_renderer.js +72 -73
  212. package/src/video/renderer.js +27 -28
  213. package/src/video/texture/atlas.js +22 -22
  214. package/src/video/texture/canvas_texture.js +9 -9
  215. package/src/video/video.js +17 -17
  216. package/src/video/webgl/buffer/vertex.js +1 -2
  217. package/src/video/webgl/glshader.js +12 -12
  218. package/src/video/webgl/webgl_compositor.js +42 -43
  219. package/src/video/webgl/webgl_renderer.js +76 -77
@@ -0,0 +1,194 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.1
3
+ * http://www.melonjs.org
4
+ * melonjs is licensed under the MIT License.
5
+ * http://www.opensource.org/licenses/mit-license
6
+ * @copyright (C) 2011 - 2022 Olivier Biot (AltByte Pte Ltd)
7
+ */
8
+ import * as sat from './sat.js';
9
+ import ResponseObject from './response.js';
10
+ import Vector2d from '../math/vector2.js';
11
+ import game from '../game.js';
12
+ import Bounds from './bounds.js';
13
+
14
+ // a dummy object when using Line for raycasting
15
+ let dummyObj = {
16
+ pos : new Vector2d(0, 0),
17
+ ancestor : {
18
+ _absPos : new Vector2d(0, 0),
19
+ getAbsolutePosition : function () {
20
+ return this._absPos;
21
+ }
22
+ }
23
+ };
24
+
25
+ let boundsA = new Bounds();
26
+ let boundsB = new Bounds();
27
+
28
+ // the global response object used for collisions
29
+ let globalResponse = new ResponseObject();
30
+
31
+ /**
32
+ * a function used to determine if two objects should collide (based on both respective objects collision mask and type).<br>
33
+ * you can redefine this function if you need any specific rules over what should collide with what.
34
+ * @name shouldCollide
35
+ * @memberof collision
36
+ * @ignore
37
+ * @param {Renderable} a - a reference to the object A.
38
+ * @param {Renderable} b - a reference to the object B.
39
+ * @returns {boolean} true if they should collide, false otherwise
40
+ */
41
+ function shouldCollide(a, b) {
42
+ var bodyA = a.body,
43
+ bodyB = b.body;
44
+ return (
45
+ a !== b &&
46
+ a.isKinematic !== true && b.isKinematic !== true &&
47
+ typeof bodyA === "object" && typeof bodyB === "object" &&
48
+ bodyA.shapes.length > 0 && bodyB.shapes.length > 0 &&
49
+ !(bodyA.isStatic === true && bodyB.isStatic === true) &&
50
+ (bodyA.collisionMask & bodyB.collisionType) !== 0 &&
51
+ (bodyA.collisionType & bodyB.collisionMask) !== 0
52
+ );
53
+ }
54
+
55
+
56
+
57
+ /**
58
+ * find all the collisions for the specified object
59
+ * @name collisionCheck
60
+ * @ignore
61
+ * @param {Renderable} objA - object to be tested for collision
62
+ * @param {ResponseObject} [response] - a user defined response object that will be populated if they intersect.
63
+ * @returns {boolean} in case of collision, false otherwise
64
+ */
65
+ function collisionCheck(objA, response = globalResponse) {
66
+ var collisionCounter = 0;
67
+ // retreive a list of potential colliding objects from the game world
68
+ var candidates = game.world.broadphase.retrieve(objA);
69
+
70
+ boundsA.addBounds(objA.getBounds(), true);
71
+ boundsA.addBounds(objA.body.getBounds());
72
+
73
+ candidates.forEach((objB) => {
74
+ // check if both objects "should" collide
75
+ if (shouldCollide(objA, objB)) {
76
+
77
+ boundsB.addBounds(objB.getBounds(), true);
78
+ boundsB.addBounds(objB.body.getBounds());
79
+
80
+ // fast AABB check if both bounding boxes are overlaping
81
+ if (boundsA.overlaps(boundsB)) {
82
+ // for each shape in body A
83
+ objA.body.shapes.forEach((shapeA, indexA) => {
84
+ // for each shape in body B
85
+ objB.body.shapes.forEach((shapeB, indexB) => {
86
+ // full SAT collision check
87
+ if (sat["test" + shapeA.shapeType + shapeB.shapeType].call(
88
+ this,
89
+ objA, // a reference to the object A
90
+ shapeA,
91
+ objB, // a reference to the object B
92
+ shapeB,
93
+ // clear response object before reusing
94
+ response.clear()) === true
95
+ ) {
96
+ // we touched something !
97
+ collisionCounter++;
98
+
99
+ // set the shape index
100
+ response.indexShapeA = indexA;
101
+ response.indexShapeB = indexB;
102
+
103
+ // execute the onCollision callback
104
+ if (objA.onCollision && objA.onCollision(response, objB) !== false && objA.body.isStatic === false) {
105
+ objA.body.respondToCollision.call(objA.body, response);
106
+ }
107
+ if (objB.onCollision && objB.onCollision(response, objA) !== false && objB.body.isStatic === false) {
108
+ objB.body.respondToCollision.call(objB.body, response);
109
+ }
110
+ }
111
+ });
112
+ });
113
+ }
114
+ }
115
+ });
116
+ // we could return the amount of objects we collided with ?
117
+ return collisionCounter > 0;
118
+ }
119
+
120
+ /**
121
+ * Checks for object colliding with the given line
122
+ * @name rayCast
123
+ * @ignore
124
+ * @param {Line} line - line to be tested for collision
125
+ * @param {Array.<Renderable>} [result] - a user defined array that will be populated with intersecting physic objects.
126
+ * @returns {Array.<Renderable>} an array of intersecting physic objects
127
+ * @example
128
+ * // define a line accross the viewport
129
+ * var ray = new me.Line(
130
+ * // absolute position of the line
131
+ * 0, 0, [
132
+ * // starting point relative to the initial position
133
+ * new me.Vector2d(0, 0),
134
+ * // ending point
135
+ * new me.Vector2d(me.game.viewport.width, me.game.viewport.height)
136
+ * ]);
137
+ *
138
+ * // check for collition
139
+ * result = me.collision.rayCast(ray);
140
+ *
141
+ * if (result.length > 0) {
142
+ * // ...
143
+ * }
144
+ */
145
+ function rayCast(line, result = []) {
146
+ var collisionCounter = 0;
147
+
148
+ // retrieve a list of potential colliding objects from the game world
149
+ var candidates = game.world.broadphase.retrieve(line);
150
+
151
+ for (var i = candidates.length, objB; i--, (objB = candidates[i]);) {
152
+
153
+ // fast AABB check if both bounding boxes are overlaping
154
+ if (objB.body && line.getBounds().overlaps(objB.getBounds())) {
155
+
156
+ // go trough all defined shapes in B (if any)
157
+ var bLen = objB.body.shapes.length;
158
+ if ( objB.body.shapes.length === 0) {
159
+ continue;
160
+ }
161
+
162
+ var shapeA = line;
163
+
164
+ // go through all defined shapes in B
165
+ var indexB = 0;
166
+ do {
167
+ var shapeB = objB.body.getShape(indexB);
168
+
169
+ // full SAT collision check
170
+ if (sat["test" + shapeA.shapeType + shapeB.shapeType]
171
+ .call(
172
+ this,
173
+ dummyObj, // a reference to the object A
174
+ shapeA,
175
+ objB, // a reference to the object B
176
+ shapeB
177
+ )) {
178
+ // we touched something !
179
+ result[collisionCounter] = objB;
180
+ collisionCounter++;
181
+ }
182
+ indexB++;
183
+ } while (indexB < bLen);
184
+ }
185
+ }
186
+
187
+ // cap result in case it was not empty
188
+ result.length = collisionCounter;
189
+
190
+ // return the list of colliding objects
191
+ return result;
192
+ }
193
+
194
+ export { collisionCheck, rayCast };
@@ -0,0 +1,394 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.1
3
+ * http://www.melonjs.org
4
+ * melonjs is licensed under the MIT License.
5
+ * http://www.opensource.org/licenses/mit-license
6
+ * @copyright (C) 2011 - 2022 Olivier Biot (AltByte Pte Ltd)
7
+ */
8
+ import Vector2d from '../math/vector2.js';
9
+ import { remove } from '../utils/array.js';
10
+
11
+ /*
12
+ * A QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm.
13
+ * Based on the QuadTree Library by Timo Hausmann and released under the MIT license
14
+ * https://github.com/timohausmann/quadtree-js/
15
+ **/
16
+
17
+ /**
18
+ * a pool of `QuadTree` objects
19
+ * @ignore
20
+ */
21
+ var QT_ARRAY = [];
22
+
23
+ /**
24
+ * will pop a quadtree object from the array
25
+ * or create a new one if the array is empty
26
+ * @ignore
27
+ */
28
+ function QT_ARRAY_POP(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
29
+ if (QT_ARRAY.length > 0) {
30
+ var _qt = QT_ARRAY.pop();
31
+ _qt.world = world;
32
+ _qt.bounds = bounds;
33
+ _qt.max_objects = max_objects;
34
+ _qt.max_levels = max_levels;
35
+ _qt.level = level;
36
+ return _qt;
37
+ } else {
38
+ return new QuadTree(world, bounds, max_objects, max_levels, level);
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Push back a quadtree back into the array
44
+ * @ignore
45
+ */
46
+ function QT_ARRAY_PUSH(qt) {
47
+ QT_ARRAY.push(qt);
48
+ }
49
+
50
+ /**
51
+ * a temporary vector object to be reused
52
+ * @ignore
53
+ */
54
+ var QT_VECTOR = new Vector2d();
55
+
56
+ /**
57
+ * @classdesc
58
+ * a QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm.
59
+ * @see game.world.broadphase
60
+ */
61
+ class QuadTree {
62
+ /**
63
+ * @param {World} world - the physic world this QuadTree belongs to
64
+ * @param {Bounds} bounds - bounds of the node
65
+ * @param {number} [max_objects=4] - max objects a node can hold before splitting into 4 subnodes
66
+ * @param {number} [max_levels=4] - total max levels inside root Quadtree
67
+ * @param {number} [level] - deepth level, required for subnodes
68
+ */
69
+ constructor(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
70
+
71
+ this.world = world;
72
+ this.bounds = bounds;
73
+
74
+ this.max_objects = max_objects;
75
+ this.max_levels = max_levels;
76
+
77
+ this.level = level;
78
+
79
+ this.objects = [];
80
+ this.nodes = [];
81
+ }
82
+
83
+ /*
84
+ * Split the node into 4 subnodes
85
+ */
86
+ split() {
87
+ var nextLevel = this.level + 1,
88
+ subWidth = this.bounds.width / 2,
89
+ subHeight = this.bounds.height / 2,
90
+ left = this.bounds.left,
91
+ top = this.bounds.top;
92
+
93
+ //top right node
94
+ this.nodes[0] = QT_ARRAY_POP(
95
+ this.world,
96
+ {
97
+ left : left + subWidth,
98
+ top : top,
99
+ width : subWidth,
100
+ height : subHeight
101
+ },
102
+ this.max_objects,
103
+ this.max_levels,
104
+ nextLevel
105
+ );
106
+
107
+ //top left node
108
+ this.nodes[1] = QT_ARRAY_POP(
109
+ this.world,
110
+ {
111
+ left : left,
112
+ top: top,
113
+ width : subWidth,
114
+ height : subHeight
115
+ },
116
+ this.max_objects,
117
+ this.max_levels,
118
+ nextLevel
119
+ );
120
+
121
+ //bottom left node
122
+ this.nodes[2] = QT_ARRAY_POP(
123
+ this.world,
124
+ {
125
+ left : left,
126
+ top : top + subHeight,
127
+ width : subWidth,
128
+ height : subHeight
129
+ },
130
+ this.max_objects,
131
+ this.max_levels,
132
+ nextLevel
133
+ );
134
+
135
+ //bottom right node
136
+ this.nodes[3] = QT_ARRAY_POP(
137
+ this.world,
138
+ {
139
+ left : left + subWidth,
140
+ top : top + subHeight,
141
+ width : subWidth,
142
+ height : subHeight
143
+ },
144
+ this.max_objects,
145
+ this.max_levels,
146
+ nextLevel
147
+ );
148
+ }
149
+
150
+ /*
151
+ * Determine which node the object belongs to
152
+ * @param {Rect} rect bounds of the area to be checked
153
+ * @returns Integer index of the subnode (0-3), or -1 if rect cannot completely fit within a subnode and is part of the parent node
154
+ */
155
+ getIndex(item) {
156
+ var pos;
157
+ var bounds = item.getBounds();
158
+
159
+ // use game world coordinates for floating items
160
+ if (item.isFloating === true) {
161
+ pos = this.world.app.viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR);
162
+ } else {
163
+ pos = QT_VECTOR.set(item.left, item.top);
164
+ }
165
+
166
+ var index = -1,
167
+ rx = pos.x,
168
+ ry = pos.y,
169
+ rw = bounds.width,
170
+ rh = bounds.height,
171
+ verticalMidpoint = this.bounds.left + (this.bounds.width / 2),
172
+ horizontalMidpoint = this.bounds.top + (this.bounds.height / 2),
173
+ //rect can completely fit within the top quadrants
174
+ topQuadrant = (ry < horizontalMidpoint && ry + rh < horizontalMidpoint),
175
+ //rect can completely fit within the bottom quadrants
176
+ bottomQuadrant = (ry > horizontalMidpoint);
177
+
178
+ //rect can completely fit within the left quadrants
179
+ if (rx < verticalMidpoint && rx + rw < verticalMidpoint) {
180
+ if (topQuadrant) {
181
+ index = 1;
182
+ } else if (bottomQuadrant) {
183
+ index = 2;
184
+ }
185
+ } else if (rx > verticalMidpoint) {
186
+ //rect can completely fit within the right quadrants
187
+ if (topQuadrant) {
188
+ index = 0;
189
+ } else if (bottomQuadrant) {
190
+ index = 3;
191
+ }
192
+ }
193
+
194
+ return index;
195
+ }
196
+
197
+ /**
198
+ * Insert the given object container into the node.
199
+ * @name insertContainer
200
+ * @memberof QuadTree
201
+ * @param {Container} container - group of objects to be added
202
+ */
203
+ insertContainer(container) {
204
+ for (var i = container.children.length, child; i--, (child = container.children[i]);) {
205
+ if (child.isKinematic !== true) {
206
+ if (typeof child.addChild === "function") {
207
+ if (child.name !== "rootContainer") {
208
+ this.insert(child);
209
+ }
210
+ // recursivly insert all childs
211
+ this.insertContainer(child);
212
+ } else {
213
+ // only insert object with a bounding box
214
+ // Probably redundant with `isKinematic`
215
+ if (typeof (child.getBounds) === "function") {
216
+ this.insert(child);
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * Insert the given object into the node. If the node
225
+ * exceeds the capacity, it will split and add all
226
+ * objects to their corresponding subnodes.
227
+ * @name insert
228
+ * @memberof QuadTree
229
+ * @param {object} item - object to be added
230
+ */
231
+ insert(item) {
232
+ var index = -1;
233
+
234
+ //if we have subnodes ...
235
+ if (this.nodes.length > 0) {
236
+ index = this.getIndex(item);
237
+
238
+ if (index !== -1) {
239
+ this.nodes[index].insert(item);
240
+ return;
241
+ }
242
+ }
243
+
244
+ this.objects.push(item);
245
+
246
+ if (this.objects.length > this.max_objects && this.level < this.max_levels) {
247
+
248
+ //split if we don't already have subnodes
249
+ if (this.nodes.length === 0) {
250
+ this.split();
251
+ }
252
+
253
+ var i = 0;
254
+
255
+ //add all objects to there corresponding subnodes
256
+ while (i < this.objects.length) {
257
+
258
+ index = this.getIndex(this.objects[i]);
259
+
260
+ if (index !== -1) {
261
+ this.nodes[index].insert(this.objects.splice(i, 1)[0]);
262
+ } else {
263
+ i = i + 1;
264
+ }
265
+ }
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Return all objects that could collide with the given object
271
+ * @name retrieve
272
+ * @memberof QuadTree
273
+ * @param {object} item - object to be checked against
274
+ * @param {object} [fn] - a sorting function for the returned array
275
+ * @returns {object[]} array with all detected objects
276
+ */
277
+ retrieve(item, fn) {
278
+ var returnObjects = this.objects;
279
+
280
+ //if we have subnodes ...
281
+ if (this.nodes.length > 0) {
282
+
283
+ var index = this.getIndex(item);
284
+
285
+ //if rect fits into a subnode ..
286
+ if (index !== -1) {
287
+ returnObjects = returnObjects.concat(this.nodes[index].retrieve(item));
288
+ } else {
289
+ //if rect does not fit into a subnode, check it against all subnodes
290
+ for (var i = 0; i < this.nodes.length; i = i + 1) {
291
+ returnObjects = returnObjects.concat(this.nodes[i].retrieve(item));
292
+ }
293
+ }
294
+ }
295
+
296
+ if (typeof(fn) === "function") {
297
+ returnObjects.sort(fn);
298
+ }
299
+
300
+ return returnObjects;
301
+ }
302
+
303
+ /**
304
+ * Remove the given item from the quadtree.
305
+ * (this function won't recalculate the impacted node)
306
+ * @name remove
307
+ * @memberof QuadTree
308
+ * @param {object} item - object to be removed
309
+ * @returns {boolean} true if the item was found and removed.
310
+ */
311
+ remove(item) {
312
+ var found = false;
313
+
314
+ if (typeof (item.getBounds) === "undefined") {
315
+ // ignore object that cannot be added in the first place
316
+ return false;
317
+ }
318
+
319
+ //if we have subnodes ...
320
+ if (this.nodes.length > 0) {
321
+ // determine to which node the item belongs to
322
+ var index = this.getIndex(item);
323
+
324
+ if (index !== -1) {
325
+ found = remove(this.nodes[index], item);
326
+ // trim node if empty
327
+ if (found && this.nodes[index].isPrunable()) {
328
+ this.nodes.splice(index, 1);
329
+ }
330
+ }
331
+ }
332
+
333
+ if (found === false) {
334
+ // try and remove the item from the list of items in this node
335
+ if (this.objects.indexOf(item) !== -1) {
336
+ remove(this.objects, item);
337
+ found = true;
338
+ }
339
+ }
340
+
341
+ return found;
342
+ }
343
+
344
+ /**
345
+ * return true if the node is prunable
346
+ * @name isPrunable
347
+ * @memberof QuadTree
348
+ * @returns {boolean} true if the node is prunable
349
+ */
350
+ isPrunable() {
351
+ return !(this.hasChildren() || (this.objects.length > 0));
352
+ }
353
+
354
+ /**
355
+ * return true if the node has any children
356
+ * @name hasChildren
357
+ * @memberof QuadTree
358
+ * @returns {boolean} true if the node has any children
359
+ */
360
+ hasChildren() {
361
+ for (var i = 0; i < this.nodes.length; i = i + 1) {
362
+ var subnode = this.nodes[i];
363
+ if (subnode.length > 0 || subnode.objects.length > 0) {
364
+ return true;
365
+ }
366
+ }
367
+ return false;
368
+ }
369
+
370
+ /**
371
+ * clear the quadtree
372
+ * @name clear
373
+ * @memberof QuadTree
374
+ * @param {Bounds} [bounds=this.bounds] - the bounds to be cleared
375
+ */
376
+ clear(bounds) {
377
+ this.objects.length = 0;
378
+
379
+ for (var i = 0; i < this.nodes.length; i++) {
380
+ this.nodes[i].clear();
381
+ // recycle the quadTree object
382
+ QT_ARRAY_PUSH(this.nodes[i]);
383
+ }
384
+ // empty the array
385
+ this.nodes.length = 0;
386
+
387
+ // resize the root bounds if required
388
+ if (typeof bounds !== "undefined") {
389
+ this.bounds.setMinMax(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
390
+ }
391
+ }
392
+ }
393
+
394
+ export { QuadTree as default };
@@ -0,0 +1,57 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.1
3
+ * http://www.melonjs.org
4
+ * melonjs is licensed under the MIT License.
5
+ * http://www.opensource.org/licenses/mit-license
6
+ * @copyright (C) 2011 - 2022 Olivier Biot (AltByte Pte Ltd)
7
+ */
8
+ import Vector2d from '../math/vector2.js';
9
+
10
+ /**
11
+ * @classdesc
12
+ * An object representing the result of an intersection.
13
+ * @property {Renderable} a The first object participating in the intersection
14
+ * @property {Renderable} b The second object participating in the intersection
15
+ * @property {number} overlap Magnitude of the overlap on the shortest colliding axis
16
+ * @property {Vector2d} overlapV The overlap vector (i.e. `overlapN.scale(overlap, overlap)`). If this vector is subtracted from the position of a, a and b will no longer be colliding
17
+ * @property {Vector2d} overlapN The shortest colliding axis (unit-vector)
18
+ * @property {boolean} aInB Whether the first object is entirely inside the second
19
+ * @property {boolean} bInA Whether the second object is entirely inside the first
20
+ * @property {number} indexShapeA The index of the colliding shape for the object a body
21
+ * @property {number} indexShapeB The index of the colliding shape for the object b body
22
+ * @name ResponseObject
23
+ * @public
24
+ */
25
+ class ResponseObject {
26
+ constructor() {
27
+ this.a = null;
28
+ this.b = null;
29
+ this.overlapN = new Vector2d();
30
+ this.overlapV = new Vector2d();
31
+ this.aInB = true;
32
+ this.bInA = true;
33
+ this.indexShapeA = -1;
34
+ this.indexShapeB = -1;
35
+ this.overlap = Number.MAX_VALUE;
36
+ }
37
+
38
+ /**
39
+ * Set some values of the response back to their defaults. <br>
40
+ * Call this between tests if you are going to reuse a single <br>
41
+ * Response object for multiple intersection tests <br>
42
+ * (recommended as it will avoid allocating extra memory) <br>
43
+ * @name clear
44
+ * @public
45
+ * @returns {object} this object for chaining
46
+ */
47
+ clear () {
48
+ this.aInB = true;
49
+ this.bInA = true;
50
+ this.overlap = Number.MAX_VALUE;
51
+ this.indexShapeA = -1;
52
+ this.indexShapeB = -1;
53
+ return this;
54
+ }
55
+ }
56
+
57
+ export { ResponseObject as default };