melonjs 14.0.2 → 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.
- package/README.md +2 -0
- package/dist/melonjs.mjs/_virtual/_commonjsHelpers.js +10 -0
- package/dist/melonjs.mjs/_virtual/arraymultimap.js +10 -0
- package/dist/melonjs.mjs/_virtual/earcut.js +10 -0
- package/dist/melonjs.mjs/_virtual/howler.js +10 -0
- package/dist/melonjs.mjs/_virtual/index.js +10 -0
- package/dist/melonjs.mjs/_virtual/index2.js +10 -0
- package/dist/melonjs.mjs/_virtual/multimap.js +10 -0
- package/dist/melonjs.mjs/_virtual/setmultimap.js +10 -0
- package/dist/melonjs.mjs/application/application.js +240 -0
- package/dist/melonjs.mjs/audio/audio.js +536 -0
- package/dist/melonjs.mjs/camera/camera2d.js +732 -0
- package/dist/melonjs.mjs/entity/entity.js +248 -0
- package/dist/melonjs.mjs/game.js +29 -0
- package/dist/melonjs.mjs/geometries/ellipse.js +275 -0
- package/dist/melonjs.mjs/geometries/line.js +116 -0
- package/dist/melonjs.mjs/geometries/path2d.js +319 -0
- package/dist/melonjs.mjs/geometries/point.js +89 -0
- package/dist/melonjs.mjs/geometries/poly.js +500 -0
- package/dist/melonjs.mjs/geometries/rectangle.js +375 -0
- package/dist/melonjs.mjs/geometries/roundrect.js +168 -0
- package/dist/melonjs.mjs/index.js +248 -0
- package/dist/melonjs.mjs/input/gamepad.js +501 -0
- package/dist/melonjs.mjs/input/input.js +26 -0
- package/dist/melonjs.mjs/input/keyboard.js +470 -0
- package/dist/melonjs.mjs/input/pointer.js +393 -0
- package/dist/melonjs.mjs/input/pointerevent.js +818 -0
- package/dist/melonjs.mjs/lang/deprecated.js +157 -0
- package/dist/melonjs.mjs/level/level.js +297 -0
- package/dist/melonjs.mjs/level/tiled/TMXGroup.js +141 -0
- package/dist/melonjs.mjs/level/tiled/TMXLayer.js +448 -0
- package/dist/melonjs.mjs/level/tiled/TMXObject.js +355 -0
- package/dist/melonjs.mjs/level/tiled/TMXTile.js +194 -0
- package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +639 -0
- package/dist/melonjs.mjs/level/tiled/TMXTileset.js +311 -0
- package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +83 -0
- package/dist/melonjs.mjs/level/tiled/TMXUtils.js +367 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +506 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +220 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +157 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +125 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +109 -0
- package/dist/melonjs.mjs/loader/loader.js +801 -0
- package/dist/melonjs.mjs/loader/loadingscreen.js +120 -0
- package/dist/melonjs.mjs/loader/melonjs_logo.png.js +11 -0
- package/dist/melonjs.mjs/math/color.js +618 -0
- package/dist/melonjs.mjs/math/math.js +218 -0
- package/dist/melonjs.mjs/math/matrix2.js +503 -0
- package/dist/melonjs.mjs/math/matrix3.js +681 -0
- package/dist/melonjs.mjs/math/observable_vector2.js +471 -0
- package/dist/melonjs.mjs/math/observable_vector3.js +561 -0
- package/dist/melonjs.mjs/math/vector2.js +528 -0
- package/dist/melonjs.mjs/math/vector3.js +569 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/arraymultimap.js +73 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/index.js +21 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/multimap.js +324 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/setmultimap.js +69 -0
- package/dist/melonjs.mjs/node_modules/earcut/src/earcut.js +691 -0
- package/dist/melonjs.mjs/node_modules/eventemitter3/index.js +350 -0
- package/dist/melonjs.mjs/node_modules/howler/dist/howler.js +3241 -0
- package/dist/melonjs.mjs/particles/emitter.js +267 -0
- package/dist/melonjs.mjs/particles/particle.js +188 -0
- package/dist/melonjs.mjs/particles/settings.js +319 -0
- package/dist/melonjs.mjs/physics/body.js +704 -0
- package/dist/melonjs.mjs/physics/bounds.js +460 -0
- package/dist/melonjs.mjs/physics/collision.js +132 -0
- package/dist/melonjs.mjs/physics/detector.js +194 -0
- package/dist/melonjs.mjs/physics/quadtree.js +391 -0
- package/dist/melonjs.mjs/physics/response.js +57 -0
- package/dist/melonjs.mjs/physics/sat.js +483 -0
- package/dist/melonjs.mjs/physics/world.js +221 -0
- package/dist/melonjs.mjs/plugin/plugin.js +141 -0
- package/dist/melonjs.mjs/renderable/collectable.js +62 -0
- package/dist/melonjs.mjs/renderable/colorlayer.js +80 -0
- package/dist/melonjs.mjs/renderable/container.js +1018 -0
- package/dist/melonjs.mjs/renderable/dragndrop.js +224 -0
- package/dist/melonjs.mjs/renderable/imagelayer.js +306 -0
- package/dist/melonjs.mjs/renderable/light2d.js +156 -0
- package/dist/melonjs.mjs/renderable/nineslicesprite.js +247 -0
- package/dist/melonjs.mjs/renderable/renderable.js +783 -0
- package/dist/melonjs.mjs/renderable/sprite.js +654 -0
- package/dist/melonjs.mjs/renderable/trigger.js +157 -0
- package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +213 -0
- package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +226 -0
- package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +128 -0
- package/dist/melonjs.mjs/state/stage.js +237 -0
- package/dist/melonjs.mjs/state/state.js +596 -0
- package/dist/melonjs.mjs/system/device.js +909 -0
- package/dist/melonjs.mjs/system/dom.js +78 -0
- package/dist/melonjs.mjs/system/event.js +537 -0
- package/dist/melonjs.mjs/system/platform.js +41 -0
- package/dist/melonjs.mjs/system/pooling.js +209 -0
- package/dist/melonjs.mjs/system/save.js +157 -0
- package/dist/melonjs.mjs/system/timer.js +286 -0
- package/dist/melonjs.mjs/text/bitmaptext.js +364 -0
- package/dist/melonjs.mjs/text/bitmaptextdata.js +199 -0
- package/dist/melonjs.mjs/text/glyph.js +66 -0
- package/dist/melonjs.mjs/text/text.js +453 -0
- package/dist/melonjs.mjs/text/textmetrics.js +176 -0
- package/dist/melonjs.mjs/text/textstyle.js +23 -0
- package/dist/melonjs.mjs/tweens/easing.js +336 -0
- package/dist/melonjs.mjs/tweens/interpolation.js +112 -0
- package/dist/melonjs.mjs/tweens/tween.js +480 -0
- package/dist/melonjs.mjs/utils/agent.js +76 -0
- package/dist/melonjs.mjs/utils/array.js +63 -0
- package/dist/melonjs.mjs/utils/file.js +42 -0
- package/dist/melonjs.mjs/utils/function.js +70 -0
- package/dist/melonjs.mjs/utils/string.js +82 -0
- package/dist/melonjs.mjs/utils/utils.js +173 -0
- package/dist/melonjs.mjs/video/canvas/canvas_renderer.js +807 -0
- package/dist/melonjs.mjs/video/renderer.js +411 -0
- package/dist/melonjs.mjs/video/texture/atlas.js +519 -0
- package/dist/melonjs.mjs/video/texture/cache.js +143 -0
- package/dist/melonjs.mjs/video/texture/canvas_texture.js +144 -0
- package/dist/melonjs.mjs/video/video.js +462 -0
- package/dist/melonjs.mjs/video/webgl/buffer/vertex.js +143 -0
- package/dist/melonjs.mjs/video/webgl/glshader.js +168 -0
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.frag.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.vert.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/quad.frag.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/quad.vert.js +10 -0
- package/dist/melonjs.mjs/video/webgl/utils/attributes.js +25 -0
- package/dist/melonjs.mjs/video/webgl/utils/precision.js +20 -0
- package/dist/melonjs.mjs/video/webgl/utils/program.js +67 -0
- package/dist/melonjs.mjs/video/webgl/utils/string.js +25 -0
- package/dist/melonjs.mjs/video/webgl/utils/uniforms.js +92 -0
- package/dist/melonjs.mjs/video/webgl/webgl_compositor.js +495 -0
- package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +1036 -0
- package/dist/melonjs.module.d.ts +1163 -1163
- package/dist/melonjs.module.js +1903 -3274
- package/package.json +22 -17
- package/src/application/application.js +3 -3
- package/src/audio/audio.js +32 -32
- package/src/camera/camera2d.js +31 -31
- package/src/entity/entity.js +17 -17
- package/src/geometries/ellipse.js +16 -16
- package/src/geometries/line.js +5 -5
- package/src/geometries/path2d.js +32 -32
- package/src/geometries/poly.js +15 -15
- package/src/geometries/rectangle.js +18 -18
- package/src/geometries/roundrect.js +8 -8
- package/src/input/gamepad.js +15 -15
- package/src/input/keyboard.js +12 -12
- package/src/input/pointer.js +6 -6
- package/src/input/pointerevent.js +12 -12
- package/src/lang/deprecated.js +12 -12
- package/src/level/level.js +25 -25
- package/src/level/tiled/TMXLayer.js +22 -22
- package/src/level/tiled/TMXTile.js +5 -5
- package/src/level/tiled/TMXTileMap.js +6 -6
- package/src/level/tiled/TMXTileset.js +2 -2
- package/src/level/tiled/TMXUtils.js +5 -5
- package/src/level/tiled/renderer/TMXHexagonalRenderer.js +2 -2
- package/src/level/tiled/renderer/TMXIsometricRenderer.js +2 -2
- package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXRenderer.js +19 -19
- package/src/loader/loader.js +20 -20
- package/src/math/color.js +20 -20
- package/src/math/math.js +16 -16
- package/src/math/matrix2.js +16 -16
- package/src/math/matrix3.js +25 -25
- package/src/math/observable_vector2.js +14 -14
- package/src/math/observable_vector3.js +16 -16
- package/src/math/vector2.js +9 -9
- package/src/math/vector3.js +10 -10
- package/src/particles/emitter.js +6 -6
- package/src/particles/particle.js +2 -2
- package/src/physics/body.js +28 -28
- package/src/physics/bounds.js +8 -8
- package/src/physics/collision.js +2 -2
- package/src/physics/detector.js +6 -6
- package/src/physics/quadtree.js +11 -11
- package/src/physics/sat.js +31 -31
- package/src/physics/world.js +5 -5
- package/src/plugin/plugin.js +5 -5
- package/src/renderable/collectable.js +3 -3
- package/src/renderable/colorlayer.js +5 -5
- package/src/renderable/container.js +21 -21
- package/src/renderable/dragndrop.js +14 -14
- package/src/renderable/imagelayer.js +13 -13
- package/src/renderable/light2d.js +3 -3
- package/src/renderable/nineslicesprite.js +16 -16
- package/src/renderable/renderable.js +23 -23
- package/src/renderable/sprite.js +28 -28
- package/src/renderable/trigger.js +15 -15
- package/src/renderable/ui/uibaseelement.js +7 -7
- package/src/renderable/ui/uispriteelement.js +6 -6
- package/src/renderable/ui/uitextbutton.js +13 -13
- package/src/state/stage.js +7 -7
- package/src/state/state.js +17 -17
- package/src/system/device.js +11 -11
- package/src/system/event.js +10 -10
- package/src/system/pooling.js +9 -9
- package/src/system/save.js +2 -2
- package/src/system/timer.js +10 -10
- package/src/text/bitmaptext.js +18 -18
- package/src/text/bitmaptextdata.js +2 -2
- package/src/text/text.js +23 -23
- package/src/text/textmetrics.js +8 -8
- package/src/tweens/tween.js +19 -19
- package/src/utils/agent.js +5 -5
- package/src/utils/array.js +4 -4
- package/src/utils/file.js +2 -2
- package/src/utils/function.js +6 -6
- package/src/utils/string.js +5 -5
- package/src/utils/utils.js +4 -4
- package/src/video/canvas/canvas_renderer.js +70 -70
- package/src/video/renderer.js +26 -26
- package/src/video/texture/atlas.js +22 -22
- package/src/video/texture/canvas_texture.js +9 -9
- package/src/video/video.js +17 -17
- package/src/video/webgl/glshader.js +10 -10
- package/src/video/webgl/webgl_compositor.js +41 -41
- package/src/video/webgl/webgl_renderer.js +75 -75
|
@@ -0,0 +1,483 @@
|
|
|
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
|
+
* Separating Axis Theorem implementation, based on the SAT.js library by Jim Riecken <jimr@jimr.ca>
|
|
12
|
+
* Available under the MIT License - https://github.com/jriecken/sat-js
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Constants for Vornoi regions
|
|
17
|
+
* @ignore
|
|
18
|
+
*/
|
|
19
|
+
const LEFT_VORNOI_REGION = -1;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Constants for Vornoi regions
|
|
23
|
+
* @ignore
|
|
24
|
+
*/
|
|
25
|
+
const MIDDLE_VORNOI_REGION = 0;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Constants for Vornoi regions
|
|
29
|
+
* @ignore
|
|
30
|
+
*/
|
|
31
|
+
const RIGHT_VORNOI_REGION = 1;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A pool of `Vector` objects that are used in calculations to avoid allocating memory.
|
|
36
|
+
* @type {Array.<Vector2d>}
|
|
37
|
+
* @ignore
|
|
38
|
+
*/
|
|
39
|
+
var T_VECTORS = [];
|
|
40
|
+
for (var v = 0; v < 10; v++) { T_VECTORS.push(new Vector2d()); }
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A pool of arrays of numbers used in calculations to avoid allocating memory.
|
|
44
|
+
* @type {Array.<Array.<number>>}
|
|
45
|
+
* @ignore
|
|
46
|
+
*/
|
|
47
|
+
var T_ARRAYS = [];
|
|
48
|
+
for (var a = 0; a < 5; a++) { T_ARRAYS.push([]); }
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Flattens the specified array of points onto a unit vector axis,
|
|
53
|
+
* resulting in a one dimensional range of the minimum and
|
|
54
|
+
* maximum value on that axis.
|
|
55
|
+
* @ignore
|
|
56
|
+
* @param {Array.<Vector2d>} points - The points to flatten.
|
|
57
|
+
* @param {Vector2d} normal - The unit vector axis to flatten on.
|
|
58
|
+
* @param {Array.<number>} result - An array. After calling this function,
|
|
59
|
+
* result[0] will be the minimum value,
|
|
60
|
+
* result[1] will be the maximum value.
|
|
61
|
+
*/
|
|
62
|
+
function flattenPointsOn(points, normal, result) {
|
|
63
|
+
var min = Number.MAX_VALUE;
|
|
64
|
+
var max = -Number.MAX_VALUE;
|
|
65
|
+
var len = points.length;
|
|
66
|
+
for (var i = 0; i < len; i++) {
|
|
67
|
+
// The magnitude of the projection of the point onto the normal
|
|
68
|
+
var dot = points[i].dot(normal);
|
|
69
|
+
if (dot < min) { min = dot; }
|
|
70
|
+
if (dot > max) { max = dot; }
|
|
71
|
+
}
|
|
72
|
+
result[0] = min;
|
|
73
|
+
result[1] = max;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check whether two convex polygons are separated by the specified
|
|
78
|
+
* axis (must be a unit vector).
|
|
79
|
+
* @ignore
|
|
80
|
+
* @param {Vector2d} aPos - The position of the first polygon.
|
|
81
|
+
* @param {Vector2d} bPos - The position of the second polygon.
|
|
82
|
+
* @param {Array.<Vector2d>} aPoints - The points in the first polygon.
|
|
83
|
+
* @param {Array.<Vector2d>} bPoints - The points in the second polygon.
|
|
84
|
+
* @param {Vector2d} axis - The axis (unit sized) to test against. The points of both polygons
|
|
85
|
+
* will be projected onto this axis.
|
|
86
|
+
* @param {Response=} response - A Response object (optional) which will be populated
|
|
87
|
+
* if the axis is not a separating axis.
|
|
88
|
+
* @returns {boolean} true if it is a separating axis, false otherwise. If false,
|
|
89
|
+
* and a response is passed in, information about how much overlap and
|
|
90
|
+
* the direction of the overlap will be populated.
|
|
91
|
+
*/
|
|
92
|
+
function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) {
|
|
93
|
+
var rangeA = T_ARRAYS.pop();
|
|
94
|
+
var rangeB = T_ARRAYS.pop();
|
|
95
|
+
// The magnitude of the offset between the two polygons
|
|
96
|
+
var offsetV = T_VECTORS.pop().copy(bPos).sub(aPos);
|
|
97
|
+
var projectedOffset = offsetV.dot(axis);
|
|
98
|
+
|
|
99
|
+
// Project the polygons onto the axis.
|
|
100
|
+
flattenPointsOn(aPoints, axis, rangeA);
|
|
101
|
+
flattenPointsOn(bPoints, axis, rangeB);
|
|
102
|
+
// Move B's range to its position relative to A.
|
|
103
|
+
rangeB[0] += projectedOffset;
|
|
104
|
+
rangeB[1] += projectedOffset;
|
|
105
|
+
// Check if there is a gap. If there is, this is a separating axis and we can stop
|
|
106
|
+
if (rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) {
|
|
107
|
+
T_VECTORS.push(offsetV);
|
|
108
|
+
T_ARRAYS.push(rangeA);
|
|
109
|
+
T_ARRAYS.push(rangeB);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// This is not a separating axis. If we're calculating a response, calculate the overlap.
|
|
114
|
+
if (response) {
|
|
115
|
+
var overlap = 0;
|
|
116
|
+
// A starts further left than B
|
|
117
|
+
if (rangeA[0] < rangeB[0]) {
|
|
118
|
+
response.aInB = false;
|
|
119
|
+
// A ends before B does. We have to pull A out of B
|
|
120
|
+
if (rangeA[1] < rangeB[1]) {
|
|
121
|
+
overlap = rangeA[1] - rangeB[0];
|
|
122
|
+
response.bInA = false;
|
|
123
|
+
// B is fully inside A. Pick the shortest way out.
|
|
124
|
+
} else {
|
|
125
|
+
var option1 = rangeA[1] - rangeB[0];
|
|
126
|
+
var option2 = rangeB[1] - rangeA[0];
|
|
127
|
+
overlap = option1 < option2 ? option1 : -option2;
|
|
128
|
+
}
|
|
129
|
+
// B starts further left than A
|
|
130
|
+
} else {
|
|
131
|
+
response.bInA = false;
|
|
132
|
+
// B ends before A ends. We have to push A out of B
|
|
133
|
+
if (rangeA[1] > rangeB[1]) {
|
|
134
|
+
overlap = rangeA[0] - rangeB[1];
|
|
135
|
+
response.aInB = false;
|
|
136
|
+
// A is fully inside B. Pick the shortest way out.
|
|
137
|
+
} else {
|
|
138
|
+
var option11 = rangeA[1] - rangeB[0];
|
|
139
|
+
var option22 = rangeB[1] - rangeA[0];
|
|
140
|
+
overlap = option11 < option22 ? option11 : -option22;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// If this is the smallest amount of overlap we've seen so far, set it as the minimum overlap.
|
|
145
|
+
var absOverlap = Math.abs(overlap);
|
|
146
|
+
if (absOverlap < response.overlap) {
|
|
147
|
+
response.overlap = absOverlap;
|
|
148
|
+
response.overlapN.copy(axis);
|
|
149
|
+
if (overlap < 0) {
|
|
150
|
+
response.overlapN.negateSelf();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
T_VECTORS.push(offsetV);
|
|
155
|
+
T_ARRAYS.push(rangeA);
|
|
156
|
+
T_ARRAYS.push(rangeB);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Calculates which Vornoi region a point is on a line segment. <br>
|
|
163
|
+
* It is assumed that both the line and the point are relative to `(0,0)`<br>
|
|
164
|
+
* <pre>
|
|
165
|
+
* | (0) |
|
|
166
|
+
* (-1) [S]--------------[E] (1)
|
|
167
|
+
* | (0) |
|
|
168
|
+
* </pre>
|
|
169
|
+
*
|
|
170
|
+
* @ignore
|
|
171
|
+
* @param {Vector2d} line - The line segment.
|
|
172
|
+
* @param {Vector2d} point - The point.
|
|
173
|
+
* @returns {number} LEFT_VORNOI_REGION (-1) if it is the left region,
|
|
174
|
+
* MIDDLE_VORNOI_REGION (0) if it is the middle region,
|
|
175
|
+
* RIGHT_VORNOI_REGION (1) if it is the right region.
|
|
176
|
+
*/
|
|
177
|
+
function vornoiRegion(line, point) {
|
|
178
|
+
var len2 = line.length2();
|
|
179
|
+
var dp = point.dot(line);
|
|
180
|
+
if (dp < 0) {
|
|
181
|
+
// If the point is beyond the start of the line, it is in the
|
|
182
|
+
// left vornoi region.
|
|
183
|
+
return LEFT_VORNOI_REGION;
|
|
184
|
+
} else if (dp > len2) {
|
|
185
|
+
// If the point is beyond the end of the line, it is in the
|
|
186
|
+
// right vornoi region.
|
|
187
|
+
return RIGHT_VORNOI_REGION;
|
|
188
|
+
} else {
|
|
189
|
+
// Otherwise, it's in the middle one.
|
|
190
|
+
return MIDDLE_VORNOI_REGION;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Checks whether polygons collide.
|
|
196
|
+
* @ignore
|
|
197
|
+
* @param {Renderable} a - a reference to the object A.
|
|
198
|
+
* @param {Polygon} polyA - a reference to the object A Polygon to be tested
|
|
199
|
+
* @param {Renderable} b - a reference to the object B.
|
|
200
|
+
* @param {Polygon} polyB - a reference to the object B Polygon to be tested
|
|
201
|
+
* @param {Response=} response - Response object (optional) that will be populated if they intersect.
|
|
202
|
+
* @returns {boolean} true if they intersect, false if they don't.
|
|
203
|
+
*/
|
|
204
|
+
function testPolygonPolygon(a, polyA, b, polyB, response) {
|
|
205
|
+
// specific point for
|
|
206
|
+
var aPoints = polyA.points;
|
|
207
|
+
var aNormals = polyA.normals;
|
|
208
|
+
var aLen = aNormals.length;
|
|
209
|
+
var bPoints = polyB.points;
|
|
210
|
+
var bNormals = polyB.normals;
|
|
211
|
+
var bLen = bNormals.length;
|
|
212
|
+
// aboslute shape position
|
|
213
|
+
var posA = T_VECTORS.pop().copy(a.pos).add(a.ancestor.getAbsolutePosition()).add(polyA.pos);
|
|
214
|
+
var posB = T_VECTORS.pop().copy(b.pos).add(b.ancestor.getAbsolutePosition()).add(polyB.pos);
|
|
215
|
+
var i;
|
|
216
|
+
|
|
217
|
+
// If any of the edge normals of A is a separating axis, no intersection.
|
|
218
|
+
for (i = 0; i < aLen; i++) {
|
|
219
|
+
if (isSeparatingAxis(posA, posB, aPoints, bPoints, aNormals[i], response)) {
|
|
220
|
+
T_VECTORS.push(posA);
|
|
221
|
+
T_VECTORS.push(posB);
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// If any of the edge normals of B is a separating axis, no intersection.
|
|
227
|
+
for (i = 0; i < bLen; i++) {
|
|
228
|
+
if (isSeparatingAxis(posA, posB, aPoints, bPoints, bNormals[i], response)) {
|
|
229
|
+
T_VECTORS.push(posA);
|
|
230
|
+
T_VECTORS.push(posB);
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Since none of the edge normals of A or B are a separating axis, there is an intersection
|
|
236
|
+
// and we've already calculated the smallest overlap (in isSeparatingAxis). Calculate the
|
|
237
|
+
// final overlap vector.
|
|
238
|
+
if (response) {
|
|
239
|
+
response.a = a;
|
|
240
|
+
response.b = b;
|
|
241
|
+
response.overlapV.copy(response.overlapN).scale(response.overlap);
|
|
242
|
+
}
|
|
243
|
+
T_VECTORS.push(posA);
|
|
244
|
+
T_VECTORS.push(posB);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Check if two Ellipse collide.
|
|
250
|
+
* @ignore
|
|
251
|
+
* @param {Renderable} a - a reference to the object A.
|
|
252
|
+
* @param {Ellipse} ellipseA - a reference to the object A Ellipse to be tested
|
|
253
|
+
* @param {Renderable} b - a reference to the object B.
|
|
254
|
+
* @param {Ellipse} ellipseB - a reference to the object B Ellipse to be tested
|
|
255
|
+
* @param {Response=} response - Response object (optional) that will be populated if
|
|
256
|
+
* the circles intersect.
|
|
257
|
+
* @returns {boolean} true if the circles intersect, false if they don't.
|
|
258
|
+
*/
|
|
259
|
+
function testEllipseEllipse(a, ellipseA, b, ellipseB, response) {
|
|
260
|
+
// Check if the distance between the centers of the two
|
|
261
|
+
// circles is greater than their combined radius.
|
|
262
|
+
var differenceV = T_VECTORS.pop().copy(b.pos).add(b.ancestor.getAbsolutePosition()).add(ellipseB.pos)
|
|
263
|
+
.sub(a.pos).add(a.ancestor.getAbsolutePosition()).sub(ellipseA.pos);
|
|
264
|
+
var radiusA = ellipseA.radius;
|
|
265
|
+
var radiusB = ellipseB.radius;
|
|
266
|
+
var totalRadius = radiusA + radiusB;
|
|
267
|
+
var totalRadiusSq = totalRadius * totalRadius;
|
|
268
|
+
var distanceSq = differenceV.length2();
|
|
269
|
+
// If the distance is bigger than the combined radius, they don't intersect.
|
|
270
|
+
if (distanceSq > totalRadiusSq) {
|
|
271
|
+
T_VECTORS.push(differenceV);
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
// They intersect. If we're calculating a response, calculate the overlap.
|
|
275
|
+
if (response) {
|
|
276
|
+
var dist = Math.sqrt(distanceSq);
|
|
277
|
+
response.a = a;
|
|
278
|
+
response.b = b;
|
|
279
|
+
response.overlap = totalRadius - dist;
|
|
280
|
+
response.overlapN.copy(differenceV.normalize());
|
|
281
|
+
response.overlapV.copy(differenceV).scale(response.overlap);
|
|
282
|
+
response.aInB = radiusA <= radiusB && dist <= radiusB - radiusA;
|
|
283
|
+
response.bInA = radiusB <= radiusA && dist <= radiusA - radiusB;
|
|
284
|
+
}
|
|
285
|
+
T_VECTORS.push(differenceV);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Check if a polygon and an ellipse collide.
|
|
291
|
+
* @ignore
|
|
292
|
+
* @param {Renderable} a - a reference to the object A.
|
|
293
|
+
* @param {Polygon} polyA - a reference to the object A Polygon to be tested
|
|
294
|
+
* @param {Renderable} b - a reference to the object B.
|
|
295
|
+
* @param {Ellipse} ellipseB - a reference to the object B Ellipse to be tested
|
|
296
|
+
* @param {Response=} response - Response object (optional) that will be populated if they intersect.
|
|
297
|
+
* @returns {boolean} true if they intersect, false if they don't.
|
|
298
|
+
*/
|
|
299
|
+
function testPolygonEllipse(a, polyA, b, ellipseB, response) {
|
|
300
|
+
// Get the position of the circle relative to the polygon.
|
|
301
|
+
var circlePos = T_VECTORS.pop().copy(b.pos).add(b.ancestor.getAbsolutePosition()).add(ellipseB.pos)
|
|
302
|
+
.sub(a.pos).add(a.ancestor.getAbsolutePosition()).sub(polyA.pos);
|
|
303
|
+
var radius = ellipseB.radius;
|
|
304
|
+
var radius2 = radius * radius;
|
|
305
|
+
var points = polyA.points;
|
|
306
|
+
var edges = polyA.edges;
|
|
307
|
+
var len = edges.length;
|
|
308
|
+
var edge = T_VECTORS.pop();
|
|
309
|
+
var normal = T_VECTORS.pop();
|
|
310
|
+
var point = T_VECTORS.pop();
|
|
311
|
+
var dist = 0;
|
|
312
|
+
|
|
313
|
+
// For each edge in the polygon:
|
|
314
|
+
for (var i = 0; i < len; i++) {
|
|
315
|
+
var next = i === len - 1 ? 0 : i + 1;
|
|
316
|
+
var prev = i === 0 ? len - 1 : i - 1;
|
|
317
|
+
var overlap = 0;
|
|
318
|
+
var overlapN = null;
|
|
319
|
+
|
|
320
|
+
// Get the edge.
|
|
321
|
+
edge.copy(edges[i]);
|
|
322
|
+
// Calculate the center of the circle relative to the starting point of the edge.
|
|
323
|
+
point.copy(circlePos).sub(points[i]);
|
|
324
|
+
|
|
325
|
+
// If the distance between the center of the circle and the point
|
|
326
|
+
// is bigger than the radius, the polygon is definitely not fully in
|
|
327
|
+
// the circle.
|
|
328
|
+
if (response && point.length2() > radius2) {
|
|
329
|
+
response.aInB = false;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Calculate which Vornoi region the center of the circle is in.
|
|
333
|
+
var region = vornoiRegion(edge, point);
|
|
334
|
+
var inRegion = true;
|
|
335
|
+
// If it's the left region:
|
|
336
|
+
if (region === LEFT_VORNOI_REGION) {
|
|
337
|
+
var point2 = null;
|
|
338
|
+
if (len > 1) {
|
|
339
|
+
// We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge.
|
|
340
|
+
edge.copy(edges[prev]);
|
|
341
|
+
// Calculate the center of the circle relative the starting point of the previous edge
|
|
342
|
+
point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]);
|
|
343
|
+
region = vornoiRegion(edge, point2);
|
|
344
|
+
if (region !== RIGHT_VORNOI_REGION) {
|
|
345
|
+
inRegion = false;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if (inRegion) {
|
|
350
|
+
// It's in the region we want. Check if the circle intersects the point.
|
|
351
|
+
dist = point.length();
|
|
352
|
+
if (dist > radius) {
|
|
353
|
+
// No intersection
|
|
354
|
+
T_VECTORS.push(circlePos);
|
|
355
|
+
T_VECTORS.push(edge);
|
|
356
|
+
T_VECTORS.push(normal);
|
|
357
|
+
T_VECTORS.push(point);
|
|
358
|
+
if (point2) {
|
|
359
|
+
T_VECTORS.push(point2);
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
} else if (response) {
|
|
363
|
+
// It intersects, calculate the overlap.
|
|
364
|
+
response.bInA = false;
|
|
365
|
+
overlapN = point.normalize();
|
|
366
|
+
overlap = radius - dist;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (point2) {
|
|
371
|
+
T_VECTORS.push(point2);
|
|
372
|
+
}
|
|
373
|
+
// If it's the right region:
|
|
374
|
+
} else if (region === RIGHT_VORNOI_REGION) {
|
|
375
|
+
if (len > 1) {
|
|
376
|
+
// We need to make sure we're in the left region on the next edge
|
|
377
|
+
edge.copy(edges[next]);
|
|
378
|
+
// Calculate the center of the circle relative to the starting point of the next edge.
|
|
379
|
+
point.copy(circlePos).sub(points[next]);
|
|
380
|
+
region = vornoiRegion(edge, point);
|
|
381
|
+
if (region !== LEFT_VORNOI_REGION) {
|
|
382
|
+
inRegion = false;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (inRegion) {
|
|
387
|
+
// It's in the region we want. Check if the circle intersects the point.
|
|
388
|
+
dist = point.length();
|
|
389
|
+
if (dist > radius) {
|
|
390
|
+
// No intersection
|
|
391
|
+
T_VECTORS.push(circlePos);
|
|
392
|
+
T_VECTORS.push(edge);
|
|
393
|
+
T_VECTORS.push(normal);
|
|
394
|
+
T_VECTORS.push(point);
|
|
395
|
+
return false;
|
|
396
|
+
} else if (response) {
|
|
397
|
+
// It intersects, calculate the overlap.
|
|
398
|
+
response.bInA = false;
|
|
399
|
+
overlapN = point.normalize();
|
|
400
|
+
overlap = radius - dist;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// Otherwise, it's the middle region:
|
|
404
|
+
} else {
|
|
405
|
+
// Need to check if the circle is intersecting the edge,
|
|
406
|
+
// Get the normal.
|
|
407
|
+
normal.copy(polyA.normals[i]);
|
|
408
|
+
// Find the perpendicular distance between the center of the
|
|
409
|
+
// circle and the edge.
|
|
410
|
+
dist = point.dot(normal);
|
|
411
|
+
var distAbs = Math.abs(dist);
|
|
412
|
+
// If the circle is on the outside of the edge, there is no intersection.
|
|
413
|
+
if ((len === 1 || dist > 0) && distAbs > radius) {
|
|
414
|
+
// No intersection
|
|
415
|
+
T_VECTORS.push(circlePos);
|
|
416
|
+
T_VECTORS.push(edge);
|
|
417
|
+
T_VECTORS.push(normal);
|
|
418
|
+
T_VECTORS.push(point);
|
|
419
|
+
return false;
|
|
420
|
+
} else if (response) {
|
|
421
|
+
// It intersects, calculate the overlap.
|
|
422
|
+
overlapN = normal;
|
|
423
|
+
overlap = radius - dist;
|
|
424
|
+
// If the center of the circle is on the outside of the edge, or part of the
|
|
425
|
+
// circle is on the outside, the circle is not fully inside the polygon.
|
|
426
|
+
if (dist >= 0 || overlap < 2 * radius) {
|
|
427
|
+
response.bInA = false;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// If this is the smallest overlap we've seen, keep it.
|
|
433
|
+
// (overlapN may be null if the circle was in the wrong Vornoi region).
|
|
434
|
+
if (overlapN && response && Math.abs(overlap) < Math.abs(response.overlap)) {
|
|
435
|
+
response.overlap = overlap;
|
|
436
|
+
response.overlapN.copy(overlapN);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Calculate the final overlap vector - based on the smallest overlap.
|
|
441
|
+
if (response) {
|
|
442
|
+
response.a = a;
|
|
443
|
+
response.b = b;
|
|
444
|
+
response.overlapV.copy(response.overlapN).scale(response.overlap);
|
|
445
|
+
}
|
|
446
|
+
T_VECTORS.push(circlePos);
|
|
447
|
+
T_VECTORS.push(edge);
|
|
448
|
+
T_VECTORS.push(normal);
|
|
449
|
+
T_VECTORS.push(point);
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Check if an ellipse and a polygon collide. <br>
|
|
455
|
+
* **NOTE:** This is slightly less efficient than testPolygonEllipse as it just
|
|
456
|
+
* runs testPolygonEllipse and reverses the response at the end.
|
|
457
|
+
* @ignore
|
|
458
|
+
* @param {Renderable} a - a reference to the object A.
|
|
459
|
+
* @param {Ellipse} ellipseA - a reference to the object A Ellipse to be tested
|
|
460
|
+
* @param {Renderable} b - a reference to the object B.
|
|
461
|
+
* @param {Polygon} polyB - a reference to the object B Polygon to be tested
|
|
462
|
+
* @param {Response=} response - Response object (optional) that will be populated if
|
|
463
|
+
* they intersect.
|
|
464
|
+
* @returns {boolean} true if they intersect, false if they don't.
|
|
465
|
+
*/
|
|
466
|
+
function testEllipsePolygon(a, ellipseA, b, polyB, response) {
|
|
467
|
+
// Test the polygon against the circle.
|
|
468
|
+
var result = testPolygonEllipse(b, polyB, a, ellipseA, response);
|
|
469
|
+
if (result && response) {
|
|
470
|
+
// Swap A and B in the response.
|
|
471
|
+
var resa = response.a;
|
|
472
|
+
var aInB = response.aInB;
|
|
473
|
+
response.overlapN.negateSelf();
|
|
474
|
+
response.overlapV.negateSelf();
|
|
475
|
+
response.a = response.b;
|
|
476
|
+
response.b = resa;
|
|
477
|
+
response.aInB = response.bInA;
|
|
478
|
+
response.bInA = aInB;
|
|
479
|
+
}
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export { testEllipseEllipse, testEllipsePolygon, testPolygonEllipse, testPolygonPolygon };
|
|
@@ -0,0 +1,221 @@
|
|
|
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 { on, GAME_RESET, LEVEL_LOADED } from '../system/event.js';
|
|
10
|
+
import QuadTree from './quadtree.js';
|
|
11
|
+
import Container from '../renderable/container.js';
|
|
12
|
+
import collision from './collision.js';
|
|
13
|
+
import { collisionCheck } from './detector.js';
|
|
14
|
+
import state from '../state/state.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @classdesc
|
|
18
|
+
* an object representing the physic world, and responsible for managing and updating all childs and physics
|
|
19
|
+
* @augments Container
|
|
20
|
+
*/
|
|
21
|
+
class World extends Container {
|
|
22
|
+
/**
|
|
23
|
+
* @param {number} [x=0] - position of the container (accessible via the inherited pos.x property)
|
|
24
|
+
* @param {number} [y=0] - position of the container (accessible via the inherited pos.y property)
|
|
25
|
+
* @param {number} [width=game.viewport.width] - width of the container
|
|
26
|
+
* @param {number} [height=game.viewport.height] - height of the container
|
|
27
|
+
*/
|
|
28
|
+
constructor(x = 0, y = 0, width = Infinity, height = Infinity) {
|
|
29
|
+
// call the super constructor
|
|
30
|
+
super(x, y, width, height, true);
|
|
31
|
+
|
|
32
|
+
// world is the root container
|
|
33
|
+
this.name = "rootContainer";
|
|
34
|
+
|
|
35
|
+
// to mimic the previous behavior
|
|
36
|
+
this.anchorPoint.set(0, 0);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* the application (game) this physic world belong to
|
|
40
|
+
* @public
|
|
41
|
+
* @type {Application}
|
|
42
|
+
*/
|
|
43
|
+
this.app = null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* the rate at which the game world is updated,
|
|
47
|
+
* may be greater than or lower than the display fps
|
|
48
|
+
* @public
|
|
49
|
+
* @type {Vector2d}
|
|
50
|
+
* @default 60
|
|
51
|
+
* @name fps
|
|
52
|
+
* @memberof World
|
|
53
|
+
* @see timer.maxfps
|
|
54
|
+
*/
|
|
55
|
+
this.fps = 60;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* world gravity
|
|
59
|
+
* @public
|
|
60
|
+
* @type {Vector2d}
|
|
61
|
+
* @default <0,0.98>
|
|
62
|
+
* @name gravity
|
|
63
|
+
* @memberof World
|
|
64
|
+
*/
|
|
65
|
+
this.gravity = new Vector2d(0, 0.98);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Specify the rendering method for tile layers. <br>
|
|
69
|
+
* if false visible part of the layers are rendered dynamically,<br>
|
|
70
|
+
* if true the entire layers are first rendered into an offscreen canvas.<br>
|
|
71
|
+
* the "best" rendering method depends of your game
|
|
72
|
+
* (amount of layer, layer size, amount of tiles per layer, etc.)<br>
|
|
73
|
+
* note : rendering method is also configurable per layer by adding this
|
|
74
|
+
* property to your layer (in Tiled).
|
|
75
|
+
* @type {boolean}
|
|
76
|
+
* @default false
|
|
77
|
+
* @memberof World
|
|
78
|
+
*/
|
|
79
|
+
this.preRender = false;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* the active physic bodies in this simulation
|
|
83
|
+
* @name bodies
|
|
84
|
+
* @memberof World
|
|
85
|
+
* @public
|
|
86
|
+
* @type {Set<Body>}
|
|
87
|
+
*/
|
|
88
|
+
this.bodies = new Set();
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* the instance of the game world quadtree used for broadphase
|
|
92
|
+
* @name broadphase
|
|
93
|
+
* @memberof World
|
|
94
|
+
* @public
|
|
95
|
+
* @type {QuadTree}
|
|
96
|
+
*/
|
|
97
|
+
this.broadphase = new QuadTree(this, this.getBounds().clone(), collision.maxChildren, collision.maxDepth);
|
|
98
|
+
|
|
99
|
+
// reset the world container on the game reset signal
|
|
100
|
+
on(GAME_RESET, this.reset, this);
|
|
101
|
+
|
|
102
|
+
// update the broadband world bounds if a new level is loaded
|
|
103
|
+
on(LEVEL_LOADED, () => {
|
|
104
|
+
// reset the quadtree
|
|
105
|
+
this.broadphase.clear(this.getBounds());
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* reset the game world
|
|
111
|
+
* @name reset
|
|
112
|
+
* @memberof World
|
|
113
|
+
*/
|
|
114
|
+
reset() {
|
|
115
|
+
// clear the quadtree
|
|
116
|
+
this.broadphase.clear();
|
|
117
|
+
|
|
118
|
+
// reset the anchorPoint
|
|
119
|
+
this.anchorPoint.set(0, 0);
|
|
120
|
+
|
|
121
|
+
// call the parent method
|
|
122
|
+
super.reset();
|
|
123
|
+
|
|
124
|
+
// empty the list of active physic bodies
|
|
125
|
+
// Note: this should be empty already when calling the parent method
|
|
126
|
+
this.bodies.clear();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Add a physic body to the game world
|
|
131
|
+
* @name addBody
|
|
132
|
+
* @memberof World
|
|
133
|
+
* @see Container.addChild
|
|
134
|
+
* @param {Body} body
|
|
135
|
+
* @returns {World} this game world
|
|
136
|
+
*/
|
|
137
|
+
addBody(body) {
|
|
138
|
+
//add it to the list of active body
|
|
139
|
+
this.bodies.add(body);
|
|
140
|
+
return this;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Remove a physic body from the game world
|
|
145
|
+
* @name removeBody
|
|
146
|
+
* @memberof World
|
|
147
|
+
* @see Container.removeChild
|
|
148
|
+
* @param {Body} body
|
|
149
|
+
* @returns {World} this game world
|
|
150
|
+
*/
|
|
151
|
+
removeBody(body) {
|
|
152
|
+
//remove from the list of active body
|
|
153
|
+
this.bodies.delete(body);
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Apply gravity to the given body
|
|
159
|
+
* @name bodyApplyVelocity
|
|
160
|
+
* @memberof World
|
|
161
|
+
* @private
|
|
162
|
+
* @param {Body} body
|
|
163
|
+
*/
|
|
164
|
+
bodyApplyGravity(body) {
|
|
165
|
+
// apply gravity to the current velocity
|
|
166
|
+
if (!body.ignoreGravity && body.gravityScale !== 0) {
|
|
167
|
+
var gravity = this.gravity;
|
|
168
|
+
|
|
169
|
+
// apply gravity if defined
|
|
170
|
+
body.force.x += (body.mass * gravity.x) * body.gravityScale;
|
|
171
|
+
body.force.y += (body.mass * gravity.y) * body.gravityScale;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* update the game world
|
|
177
|
+
* @name reset
|
|
178
|
+
* @memberof World
|
|
179
|
+
* @param {number} dt - the time passed since the last frame update
|
|
180
|
+
* @returns {boolean} true if the word is dirty
|
|
181
|
+
*/
|
|
182
|
+
update(dt) {
|
|
183
|
+
var isPaused = state.isPaused();
|
|
184
|
+
|
|
185
|
+
// clear the quadtree
|
|
186
|
+
this.broadphase.clear();
|
|
187
|
+
|
|
188
|
+
// insert the world container (children) into the quadtree
|
|
189
|
+
this.broadphase.insertContainer(this);
|
|
190
|
+
|
|
191
|
+
// iterate through all bodies
|
|
192
|
+
this.bodies.forEach((body) => {
|
|
193
|
+
if (!body.isStatic) {
|
|
194
|
+
var ancestor = body.ancestor;
|
|
195
|
+
// if the game is not paused, and ancestor can be updated
|
|
196
|
+
if (!(isPaused && (!ancestor.updateWhenPaused)) &&
|
|
197
|
+
(ancestor.inViewport || ancestor.alwaysUpdate)) {
|
|
198
|
+
// apply gravity to this body
|
|
199
|
+
this.bodyApplyGravity(body);
|
|
200
|
+
// body update function (this moves it)
|
|
201
|
+
if (body.update(dt) === true) {
|
|
202
|
+
// mark ancestor as dirty
|
|
203
|
+
ancestor.isDirty = true;
|
|
204
|
+
}
|
|
205
|
+
// handle collisions against other objects
|
|
206
|
+
collisionCheck(ancestor);
|
|
207
|
+
// clear body force
|
|
208
|
+
body.force.set(0, 0);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// call the super constructor
|
|
214
|
+
return super.update(dt);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
var World$1 = World;
|
|
220
|
+
|
|
221
|
+
export { World$1 as default };
|