melonjs 14.0.1 → 14.1.0

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 (214) 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 +240 -0
  11. package/dist/melonjs.mjs/audio/audio.js +536 -0
  12. package/dist/melonjs.mjs/camera/camera2d.js +732 -0
  13. package/dist/melonjs.mjs/entity/entity.js +248 -0
  14. package/dist/melonjs.mjs/game.js +29 -0
  15. package/dist/melonjs.mjs/geometries/ellipse.js +275 -0
  16. package/dist/melonjs.mjs/geometries/line.js +116 -0
  17. package/dist/melonjs.mjs/geometries/path2d.js +319 -0
  18. package/dist/melonjs.mjs/geometries/point.js +89 -0
  19. package/dist/melonjs.mjs/geometries/poly.js +500 -0
  20. package/dist/melonjs.mjs/geometries/rectangle.js +375 -0
  21. package/dist/melonjs.mjs/geometries/roundrect.js +168 -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 +448 -0
  32. package/dist/melonjs.mjs/level/tiled/TMXObject.js +355 -0
  33. package/dist/melonjs.mjs/level/tiled/TMXTile.js +194 -0
  34. package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +639 -0
  35. package/dist/melonjs.mjs/level/tiled/TMXTileset.js +311 -0
  36. package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +83 -0
  37. package/dist/melonjs.mjs/level/tiled/TMXUtils.js +367 -0
  38. package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +506 -0
  39. package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +220 -0
  40. package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +157 -0
  41. package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +125 -0
  42. package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +109 -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 +618 -0
  47. package/dist/melonjs.mjs/math/math.js +218 -0
  48. package/dist/melonjs.mjs/math/matrix2.js +503 -0
  49. package/dist/melonjs.mjs/math/matrix3.js +681 -0
  50. package/dist/melonjs.mjs/math/observable_vector2.js +471 -0
  51. package/dist/melonjs.mjs/math/observable_vector3.js +561 -0
  52. package/dist/melonjs.mjs/math/vector2.js +528 -0
  53. package/dist/melonjs.mjs/math/vector3.js +569 -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 +267 -0
  62. package/dist/melonjs.mjs/particles/particle.js +188 -0
  63. package/dist/melonjs.mjs/particles/settings.js +319 -0
  64. package/dist/melonjs.mjs/physics/body.js +704 -0
  65. package/dist/melonjs.mjs/physics/bounds.js +460 -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 +391 -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 +221 -0
  72. package/dist/melonjs.mjs/plugin/plugin.js +141 -0
  73. package/dist/melonjs.mjs/renderable/collectable.js +62 -0
  74. package/dist/melonjs.mjs/renderable/colorlayer.js +80 -0
  75. package/dist/melonjs.mjs/renderable/container.js +1018 -0
  76. package/dist/melonjs.mjs/renderable/dragndrop.js +224 -0
  77. package/dist/melonjs.mjs/renderable/imagelayer.js +306 -0
  78. package/dist/melonjs.mjs/renderable/light2d.js +156 -0
  79. package/dist/melonjs.mjs/renderable/nineslicesprite.js +247 -0
  80. package/dist/melonjs.mjs/renderable/renderable.js +783 -0
  81. package/dist/melonjs.mjs/renderable/sprite.js +654 -0
  82. package/dist/melonjs.mjs/renderable/trigger.js +157 -0
  83. package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +213 -0
  84. package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +226 -0
  85. package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +128 -0
  86. package/dist/melonjs.mjs/state/stage.js +237 -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 +364 -0
  96. package/dist/melonjs.mjs/text/bitmaptextdata.js +199 -0
  97. package/dist/melonjs.mjs/text/glyph.js +66 -0
  98. package/dist/melonjs.mjs/text/text.js +453 -0
  99. package/dist/melonjs.mjs/text/textmetrics.js +176 -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 +480 -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 +807 -0
  111. package/dist/melonjs.mjs/video/renderer.js +411 -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 +143 -0
  117. package/dist/melonjs.mjs/video/webgl/glshader.js +168 -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 +495 -0
  128. package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +1036 -0
  129. package/dist/melonjs.module.d.ts +1163 -1163
  130. package/dist/melonjs.module.js +1903 -3274
  131. package/package.json +22 -17
  132. package/src/application/application.js +3 -3
  133. package/src/audio/audio.js +32 -32
  134. package/src/camera/camera2d.js +31 -31
  135. package/src/entity/entity.js +17 -17
  136. package/src/geometries/ellipse.js +16 -16
  137. package/src/geometries/line.js +5 -5
  138. package/src/geometries/path2d.js +32 -32
  139. package/src/geometries/poly.js +15 -15
  140. package/src/geometries/rectangle.js +18 -18
  141. package/src/geometries/roundrect.js +8 -8
  142. package/src/input/gamepad.js +15 -15
  143. package/src/input/keyboard.js +12 -12
  144. package/src/input/pointer.js +6 -6
  145. package/src/input/pointerevent.js +12 -12
  146. package/src/lang/deprecated.js +12 -12
  147. package/src/level/level.js +25 -25
  148. package/src/level/tiled/TMXLayer.js +22 -22
  149. package/src/level/tiled/TMXTile.js +5 -5
  150. package/src/level/tiled/TMXTileMap.js +6 -6
  151. package/src/level/tiled/TMXTileset.js +2 -2
  152. package/src/level/tiled/TMXUtils.js +5 -5
  153. package/src/level/tiled/renderer/TMXHexagonalRenderer.js +2 -2
  154. package/src/level/tiled/renderer/TMXIsometricRenderer.js +2 -2
  155. package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
  156. package/src/level/tiled/renderer/TMXRenderer.js +19 -19
  157. package/src/loader/loader.js +20 -20
  158. package/src/math/color.js +20 -20
  159. package/src/math/math.js +16 -16
  160. package/src/math/matrix2.js +16 -16
  161. package/src/math/matrix3.js +25 -25
  162. package/src/math/observable_vector2.js +14 -14
  163. package/src/math/observable_vector3.js +16 -16
  164. package/src/math/vector2.js +9 -9
  165. package/src/math/vector3.js +10 -10
  166. package/src/particles/emitter.js +6 -6
  167. package/src/particles/particle.js +2 -2
  168. package/src/physics/body.js +28 -28
  169. package/src/physics/bounds.js +8 -8
  170. package/src/physics/collision.js +2 -2
  171. package/src/physics/detector.js +6 -6
  172. package/src/physics/quadtree.js +11 -11
  173. package/src/physics/sat.js +31 -31
  174. package/src/physics/world.js +5 -5
  175. package/src/plugin/plugin.js +5 -5
  176. package/src/renderable/collectable.js +3 -3
  177. package/src/renderable/colorlayer.js +5 -5
  178. package/src/renderable/container.js +21 -21
  179. package/src/renderable/dragndrop.js +14 -14
  180. package/src/renderable/imagelayer.js +13 -13
  181. package/src/renderable/light2d.js +3 -3
  182. package/src/renderable/nineslicesprite.js +16 -16
  183. package/src/renderable/renderable.js +23 -23
  184. package/src/renderable/sprite.js +28 -28
  185. package/src/renderable/trigger.js +15 -15
  186. package/src/renderable/ui/uibaseelement.js +7 -7
  187. package/src/renderable/ui/uispriteelement.js +6 -6
  188. package/src/renderable/ui/uitextbutton.js +13 -13
  189. package/src/state/stage.js +7 -7
  190. package/src/state/state.js +17 -17
  191. package/src/system/device.js +11 -11
  192. package/src/system/event.js +10 -10
  193. package/src/system/pooling.js +9 -9
  194. package/src/system/save.js +2 -2
  195. package/src/system/timer.js +10 -10
  196. package/src/text/bitmaptext.js +18 -18
  197. package/src/text/bitmaptextdata.js +2 -2
  198. package/src/text/text.js +23 -23
  199. package/src/text/textmetrics.js +8 -8
  200. package/src/tweens/tween.js +19 -19
  201. package/src/utils/agent.js +5 -5
  202. package/src/utils/array.js +4 -4
  203. package/src/utils/file.js +2 -2
  204. package/src/utils/function.js +6 -6
  205. package/src/utils/string.js +5 -5
  206. package/src/utils/utils.js +4 -4
  207. package/src/video/canvas/canvas_renderer.js +70 -70
  208. package/src/video/renderer.js +26 -26
  209. package/src/video/texture/atlas.js +22 -22
  210. package/src/video/texture/canvas_texture.js +9 -9
  211. package/src/video/video.js +17 -17
  212. package/src/video/webgl/glshader.js +10 -10
  213. package/src/video/webgl/webgl_compositor.js +41 -41
  214. package/src/video/webgl/webgl_renderer.js +75 -75
@@ -0,0 +1,194 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.0
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,391 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.0
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 Container from '../renderable/container.js';
10
+ import { remove } from '../utils/array.js';
11
+
12
+ /*
13
+ * A QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm.
14
+ * Based on the QuadTree Library by Timo Hausmann and released under the MIT license
15
+ * https://github.com/timohausmann/quadtree-js/
16
+ **/
17
+
18
+
19
+ /**
20
+ * a pool of `QuadTree` objects
21
+ * @ignore
22
+ */
23
+ var QT_ARRAY = [];
24
+
25
+ /**
26
+ * will pop a quadtree object from the array
27
+ * or create a new one if the array is empty
28
+ * @ignore
29
+ */
30
+ function QT_ARRAY_POP(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
31
+ if (QT_ARRAY.length > 0) {
32
+ var _qt = QT_ARRAY.pop();
33
+ _qt.world = world;
34
+ _qt.bounds = bounds;
35
+ _qt.max_objects = max_objects;
36
+ _qt.max_levels = max_levels;
37
+ _qt.level = level;
38
+ return _qt;
39
+ } else {
40
+ return new QuadTree(world, bounds, max_objects, max_levels, level);
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Push back a quadtree back into the array
46
+ * @ignore
47
+ */
48
+ function QT_ARRAY_PUSH(qt) {
49
+ QT_ARRAY.push(qt);
50
+ }
51
+
52
+ /**
53
+ * a temporary vector object to be reused
54
+ * @ignore
55
+ */
56
+ var QT_VECTOR = new Vector2d();
57
+
58
+ /**
59
+ * @classdesc
60
+ * a QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm.
61
+ * @see game.world.broadphase
62
+ */
63
+ class QuadTree {
64
+ /**
65
+ * @param {World} world - the physic world this QuadTree belongs to
66
+ * @param {Bounds} bounds - bounds of the node
67
+ * @param {number} [max_objects=4] - max objects a node can hold before splitting into 4 subnodes
68
+ * @param {number} [max_levels=4] - total max levels inside root Quadtree
69
+ * @param {number} [level] - deepth level, required for subnodes
70
+ */
71
+ constructor(world, bounds, max_objects = 4, max_levels = 4, level = 0) {
72
+
73
+ this.world = world;
74
+ this.bounds = bounds;
75
+
76
+ this.max_objects = max_objects;
77
+ this.max_levels = max_levels;
78
+
79
+ this.level = level;
80
+ this.bounds = bounds;
81
+
82
+ this.objects = [];
83
+ this.nodes = [];
84
+ }
85
+
86
+ /*
87
+ * Split the node into 4 subnodes
88
+ */
89
+ split() {
90
+ this.level + 1;
91
+ var subWidth = this.bounds.width / 2,
92
+ subHeight = this.bounds.height / 2,
93
+ left = this.bounds.left,
94
+ top = this.bounds.top;
95
+
96
+ //top right node
97
+ this.nodes[0] = QT_ARRAY_POP(
98
+ this.world,
99
+ this.bounds, {
100
+ left : left + subWidth,
101
+ top : top,
102
+ width : subWidth,
103
+ height : subHeight
104
+ },
105
+ this.max_objects,
106
+ this.max_levels);
107
+
108
+ //top left node
109
+ this.nodes[1] = QT_ARRAY_POP(
110
+ this.world,
111
+ this.bounds, {
112
+ left : left,
113
+ top: top,
114
+ width : subWidth,
115
+ height : subHeight
116
+ },
117
+ this.max_objects,
118
+ this.max_levels);
119
+
120
+ //bottom left node
121
+ this.nodes[2] = QT_ARRAY_POP(
122
+ this.world,
123
+ this.bounds, {
124
+ left : left,
125
+ top : top + subHeight,
126
+ width : subWidth,
127
+ height : subHeight
128
+ },
129
+ this.max_objects,
130
+ this.max_levels);
131
+
132
+ //bottom right node
133
+ this.nodes[3] = QT_ARRAY_POP(
134
+ this.world,
135
+ this.bounds, {
136
+ left : left + subWidth,
137
+ top : top + subHeight,
138
+ width : subWidth,
139
+ height : subHeight
140
+ },
141
+ this.max_objects,
142
+ this.max_levels);
143
+ }
144
+
145
+ /*
146
+ * Determine which node the object belongs to
147
+ * @param {Rect} rect bounds of the area to be checked
148
+ * @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
149
+ */
150
+ getIndex(item) {
151
+ var pos;
152
+ var bounds = item.getBounds();
153
+
154
+ // use game world coordinates for floating items
155
+ if (item.isFloating === true) {
156
+ pos = this.world.app.viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR);
157
+ } else {
158
+ pos = QT_VECTOR.set(bounds.left, bounds.top);
159
+ }
160
+
161
+ var index = -1,
162
+ rx = pos.x,
163
+ ry = pos.y,
164
+ rw = bounds.width,
165
+ rh = bounds.height,
166
+ verticalMidpoint = this.bounds.left + (this.bounds.width / 2),
167
+ horizontalMidpoint = this.bounds.top + (this.bounds.height / 2),
168
+ //rect can completely fit within the top quadrants
169
+ topQuadrant = (ry < horizontalMidpoint && ry + rh < horizontalMidpoint),
170
+ //rect can completely fit within the bottom quadrants
171
+ bottomQuadrant = (ry > horizontalMidpoint);
172
+
173
+ //rect can completely fit within the left quadrants
174
+ if (rx < verticalMidpoint && rx + rw < verticalMidpoint) {
175
+ if (topQuadrant) {
176
+ index = 1;
177
+ } else if (bottomQuadrant) {
178
+ index = 2;
179
+ }
180
+ } else if (rx > verticalMidpoint) {
181
+ //rect can completely fit within the right quadrants
182
+ if (topQuadrant) {
183
+ index = 0;
184
+ } else if (bottomQuadrant) {
185
+ index = 3;
186
+ }
187
+ }
188
+
189
+ return index;
190
+ }
191
+
192
+ /**
193
+ * Insert the given object container into the node.
194
+ * @name insertContainer
195
+ * @memberof QuadTree
196
+ * @param {Container} container - group of objects to be added
197
+ */
198
+ insertContainer(container) {
199
+ for (var i = container.children.length, child; i--, (child = container.children[i]);) {
200
+ if (child.isKinematic !== true) {
201
+ if (child instanceof Container) {
202
+ if (child.name !== "rootContainer") {
203
+ this.insert(child);
204
+ }
205
+ // recursivly insert all childs
206
+ this.insertContainer(child);
207
+ } else {
208
+ // only insert object with a bounding box
209
+ // Probably redundant with `isKinematic`
210
+ if (typeof (child.getBounds) === "function") {
211
+ this.insert(child);
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Insert the given object into the node. If the node
220
+ * exceeds the capacity, it will split and add all
221
+ * objects to their corresponding subnodes.
222
+ * @name insert
223
+ * @memberof QuadTree
224
+ * @param {object} item - object to be added
225
+ */
226
+ insert(item) {
227
+ var index = -1;
228
+
229
+ //if we have subnodes ...
230
+ if (this.nodes.length > 0) {
231
+ index = this.getIndex(item);
232
+
233
+ if (index !== -1) {
234
+ this.nodes[index].insert(item);
235
+ return;
236
+ }
237
+ }
238
+
239
+ this.objects.push(item);
240
+
241
+ if (this.objects.length > this.max_objects && this.level < this.max_levels) {
242
+
243
+ //split if we don't already have subnodes
244
+ if (this.nodes.length === 0) {
245
+ this.split();
246
+ }
247
+
248
+ var i = 0;
249
+
250
+ //add all objects to there corresponding subnodes
251
+ while (i < this.objects.length) {
252
+
253
+ index = this.getIndex(this.objects[i]);
254
+
255
+ if (index !== -1) {
256
+ this.nodes[index].insert(this.objects.splice(i, 1)[0]);
257
+ } else {
258
+ i = i + 1;
259
+ }
260
+ }
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Return all objects that could collide with the given object
266
+ * @name retrieve
267
+ * @memberof QuadTree
268
+ * @param {object} item - object to be checked against
269
+ * @param {object} [fn] - a sorting function for the returned array
270
+ * @returns {object[]} array with all detected objects
271
+ */
272
+ retrieve(item, fn) {
273
+ var returnObjects = this.objects;
274
+
275
+ //if we have subnodes ...
276
+ if (this.nodes.length > 0) {
277
+
278
+ var index = this.getIndex(item);
279
+
280
+ //if rect fits into a subnode ..
281
+ if (index !== -1) {
282
+ returnObjects = returnObjects.concat(this.nodes[index].retrieve(item));
283
+ } else {
284
+ //if rect does not fit into a subnode, check it against all subnodes
285
+ for (var i = 0; i < this.nodes.length; i = i + 1) {
286
+ returnObjects = returnObjects.concat(this.nodes[i].retrieve(item));
287
+ }
288
+ }
289
+ }
290
+
291
+ if (typeof(fn) === "function") {
292
+ returnObjects.sort(fn);
293
+ }
294
+
295
+ return returnObjects;
296
+ }
297
+
298
+ /**
299
+ * Remove the given item from the quadtree.
300
+ * (this function won't recalculate the impacted node)
301
+ * @name remove
302
+ * @memberof QuadTree
303
+ * @param {object} item - object to be removed
304
+ * @returns {boolean} true if the item was found and removed.
305
+ */
306
+ remove(item) {
307
+ var found = false;
308
+
309
+ if (typeof (item.getBounds) === "undefined") {
310
+ // ignore object that cannot be added in the first place
311
+ return false;
312
+ }
313
+
314
+ //if we have subnodes ...
315
+ if (this.nodes.length > 0) {
316
+ // determine to which node the item belongs to
317
+ var index = this.getIndex(item);
318
+
319
+ if (index !== -1) {
320
+ found = remove(this.nodes[index], item);
321
+ // trim node if empty
322
+ if (found && this.nodes[index].isPrunable()) {
323
+ this.nodes.splice(index, 1);
324
+ }
325
+ }
326
+ }
327
+
328
+ if (found === false) {
329
+ // try and remove the item from the list of items in this node
330
+ if (this.objects.indexOf(item) !== -1) {
331
+ remove(this.objects, item);
332
+ found = true;
333
+ }
334
+ }
335
+
336
+ return found;
337
+ }
338
+
339
+ /**
340
+ * return true if the node is prunable
341
+ * @name isPrunable
342
+ * @memberof QuadTree
343
+ * @returns {boolean} true if the node is prunable
344
+ */
345
+ isPrunable() {
346
+ return !(this.hasChildren() || (this.objects.length > 0));
347
+ }
348
+
349
+ /**
350
+ * return true if the node has any children
351
+ * @name hasChildren
352
+ * @memberof QuadTree
353
+ * @returns {boolean} true if the node has any children
354
+ */
355
+ hasChildren() {
356
+ for (var i = 0; i < this.nodes.length; i = i + 1) {
357
+ var subnode = this.nodes[i];
358
+ if (subnode.length > 0 || subnode.objects.length > 0) {
359
+ return true;
360
+ }
361
+ }
362
+ return false;
363
+ }
364
+
365
+ /**
366
+ * clear the quadtree
367
+ * @name clear
368
+ * @memberof QuadTree
369
+ * @param {Bounds} [bounds=this.bounds] - the bounds to be cleared
370
+ */
371
+ clear(bounds) {
372
+ this.objects.length = 0;
373
+
374
+ for (var i = 0; i < this.nodes.length; i++) {
375
+ this.nodes[i].clear();
376
+ // recycle the quadTree object
377
+ QT_ARRAY_PUSH(this.nodes[i]);
378
+ }
379
+ // empty the array
380
+ this.nodes.length = 0;
381
+
382
+ // resize the root bounds if required
383
+ if (typeof bounds !== "undefined") {
384
+ this.bounds.setMinMax(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y);
385
+ }
386
+ }
387
+ }
388
+
389
+ var QuadTree$1 = QuadTree;
390
+
391
+ export { QuadTree$1 as default };
@@ -0,0 +1,57 @@
1
+ /*!
2
+ * melonJS Game Engine - v14.1.0
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 };