@makefully/platypus 4.1.5 → 4.1.6

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 (136) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -3
  3. package/lib/platypus.js +1 -1
  4. package/package.json +6 -5
  5. package/src/AABB.js +685 -0
  6. package/src/ActionState.js +121 -0
  7. package/src/AssetManager.js +206 -0
  8. package/src/CollisionData.js +96 -0
  9. package/src/CollisionDataContainer.js +127 -0
  10. package/src/CollisionShape.js +315 -0
  11. package/src/Component.js +231 -0
  12. package/src/Data.js +64 -0
  13. package/src/DataMap.js +204 -0
  14. package/src/Entity.js +404 -0
  15. package/src/EntityLinker.js +113 -0
  16. package/src/EventHandler.js +115 -0
  17. package/src/EventHandlerList.js +251 -0
  18. package/src/Game.js +840 -0
  19. package/src/Gamepad.js +175 -0
  20. package/src/ID3CaptionPlayer.js +61 -0
  21. package/src/Messenger.js +365 -0
  22. package/src/PIXIAnimation.js +622 -0
  23. package/src/RandomSet.js +140 -0
  24. package/src/SFXPlayer.js +120 -0
  25. package/src/StateMap.js +252 -0
  26. package/src/Storage.js +152 -0
  27. package/src/TickerClient.js +48 -0
  28. package/src/TickerServer.js +23 -0
  29. package/src/TimeEvent.js +50 -0
  30. package/src/TimeEventList.js +100 -0
  31. package/src/VOPlayer.js +684 -0
  32. package/src/Vector.js +702 -0
  33. package/src/components/AIChaser.js +161 -0
  34. package/src/components/AIPacer.js +107 -0
  35. package/src/components/AudioMusic.js +151 -0
  36. package/src/components/AudioSFX.js +673 -0
  37. package/src/components/AudioVO.js +301 -0
  38. package/src/components/CollisionBasic.js +826 -0
  39. package/src/components/CollisionFilter.js +74 -0
  40. package/src/components/CollisionGroup.js +448 -0
  41. package/src/components/CollisionTiles.js +608 -0
  42. package/src/components/ComponentSwitcher.js +173 -0
  43. package/src/components/ControllerInput.js +65 -0
  44. package/src/components/Counter.js +165 -0
  45. package/src/components/EntityCamera.js +215 -0
  46. package/src/components/EntityContainer.js +549 -0
  47. package/src/components/EntityController.js +541 -0
  48. package/src/components/HandlerCamera.js +1052 -0
  49. package/src/components/HandlerCollision.js +1318 -0
  50. package/src/components/HandlerController.js +291 -0
  51. package/src/components/HandlerLogic.js +394 -0
  52. package/src/components/HandlerRender.js +217 -0
  53. package/src/components/Interactive.js +502 -0
  54. package/src/components/LevelBuilder.js +524 -0
  55. package/src/components/LogicAngularMovement.js +154 -0
  56. package/src/components/LogicAttachment.js +265 -0
  57. package/src/components/LogicButton.js +466 -0
  58. package/src/components/LogicCarrier.js +39 -0
  59. package/src/components/LogicDestroyMe.js +58 -0
  60. package/src/components/LogicDirectionalMovement.js +325 -0
  61. package/src/components/LogicDragDrop.js +371 -0
  62. package/src/components/LogicImpactLaunch.js +144 -0
  63. package/src/components/LogicPacingPlatform.js +64 -0
  64. package/src/components/LogicPortable.js +112 -0
  65. package/src/components/LogicPortal.js +115 -0
  66. package/src/components/LogicPushable.js +98 -0
  67. package/src/components/LogicRebounder.js +136 -0
  68. package/src/components/LogicRegionSpawner.js +139 -0
  69. package/src/components/LogicRotationalMovement.js +205 -0
  70. package/src/components/LogicSpawner.js +159 -0
  71. package/src/components/LogicStateMachine.js +382 -0
  72. package/src/components/LogicSwitch.js +77 -0
  73. package/src/components/LogicTeleportee.js +68 -0
  74. package/src/components/LogicTeleporter.js +93 -0
  75. package/src/components/LogicTimer.js +178 -0
  76. package/src/components/LogicWindUpRacer.js +179 -0
  77. package/src/components/Motion.js +371 -0
  78. package/src/components/Mover.js +566 -0
  79. package/src/components/Node.js +289 -0
  80. package/src/components/NodeMap.js +295 -0
  81. package/src/components/NodeResident.js +636 -0
  82. package/src/components/Orientation.js +697 -0
  83. package/src/components/RandomEvents.js +73 -0
  84. package/src/components/RelativePosition.js +204 -0
  85. package/src/components/RelayFamily.js +106 -0
  86. package/src/components/RelayGame.js +53 -0
  87. package/src/components/RelayLinker.js +94 -0
  88. package/src/components/RelayParent.js +57 -0
  89. package/src/components/RelaySelf.js +55 -0
  90. package/src/components/Render.js +178 -0
  91. package/src/components/RenderAnimator.js +275 -0
  92. package/src/components/RenderContainer.js +646 -0
  93. package/src/components/RenderDebug.js +319 -0
  94. package/src/components/RenderDestroyMe.js +59 -0
  95. package/src/components/RenderLottie.js +149 -0
  96. package/src/components/RenderProgress.js +120 -0
  97. package/src/components/RenderSpine.js +833 -0
  98. package/src/components/RenderSprite.js +527 -0
  99. package/src/components/RenderText.js +147 -0
  100. package/src/components/RenderTiles.js +1391 -0
  101. package/src/components/SceneChanger.js +128 -0
  102. package/src/components/TiledLoader.js +1451 -0
  103. package/src/components/Timeline.js +314 -0
  104. package/src/components/Tutorial.js +267 -0
  105. package/src/components/Tween.js +296 -0
  106. package/src/components/VoiceOver.js +373 -0
  107. package/src/components/XHR.js +129 -0
  108. package/src/components/index.js +79 -0
  109. package/src/factory.js +305 -0
  110. package/src/index.js +159 -0
  111. package/src/mixins/PIXI.Graphics.js +41 -0
  112. package/src/platypus.css +68 -0
  113. package/src/sayHello.js +50 -0
  114. package/src/shapes/Capsule.js +74 -0
  115. package/src/shapes/Circle.js +43 -0
  116. package/src/shapes/Ellipse.js +117 -0
  117. package/src/shapes/Point.js +191 -0
  118. package/src/shapes/Polygon.js +112 -0
  119. package/src/shapes/Polyline.js +97 -0
  120. package/src/shapes/Rectangle.js +78 -0
  121. package/src/shapes/RoundedRectangle.js +33 -0
  122. package/src/shapes/Segment.js +346 -0
  123. package/src/shapes/adjustedXY.js +19 -0
  124. package/src/shapes/castFromBox2D.js +92 -0
  125. package/src/shapes/castFromObject.js +53 -0
  126. package/src/shapes/castFromPixiGraphics.js +6 -0
  127. package/src/shapes/castFromPixiShape.js +89 -0
  128. package/src/shapes/castToBox2D.js +190 -0
  129. package/src/shapes/castToPixiGraphics.js +100 -0
  130. package/src/shapes/castToPixiShape.js +61 -0
  131. package/src/shapes/checkPointsMap.js +313 -0
  132. package/src/shapes/index.js +35 -0
  133. package/src/utils/array.js +73 -0
  134. package/src/utils/string.js +39 -0
  135. package/lib/243.platypus.mjs +0 -1
  136. package/lib/platypus.mjs +0 -1
@@ -0,0 +1,97 @@
1
+ import Point from "./Point";
2
+ import Segment from "./Segment";
3
+
4
+ export default class Polyline extends Segment {
5
+ constructor (...args) {
6
+ super(...args);
7
+ this.type = 'polyline';
8
+ this._segments = null;
9
+ }
10
+
11
+ get loop () {
12
+ return this._loop;
13
+ }
14
+
15
+ set loop (loop) {
16
+ const
17
+ newValue = !!loop;
18
+
19
+ if (newValue !== this._loop) {
20
+ this._loop = newValue;
21
+ this._segments = null;
22
+ }
23
+ }
24
+
25
+ get segments () {
26
+ if (!this._segments) {
27
+ const
28
+ {points} = this,
29
+ segments = [];
30
+
31
+ for (let i = 0; i < points.length - 1; i++) {
32
+ segments.push(new Segment({
33
+ a: points[i],
34
+ b: points[i + 1]
35
+ }));
36
+ }
37
+
38
+ if (this.loop) {
39
+ segments.push(new Segment({
40
+ a: points[points.length - 1],
41
+ b: points[0]
42
+ }));
43
+ }
44
+
45
+ this._segments = segments;
46
+ }
47
+
48
+ return this._segments;
49
+ }
50
+
51
+ initialize (options) {
52
+ super.initialize(options);
53
+ this._loop = options.loop ?? false;
54
+ }
55
+
56
+ forEach (func) {
57
+ this.segments.forEach(func);
58
+ }
59
+
60
+ getLength () {
61
+ return this.segments.reduce((sum, segment) => sum + segment.getLength(), 0);
62
+ }
63
+
64
+ duplicate () {
65
+ return new Polyline(this);
66
+ }
67
+
68
+ toObject (options) {
69
+ const
70
+ {points, type} = this;
71
+
72
+ return {
73
+ points: points.map((point) => adjustedXY(point, options)),
74
+ type
75
+ };
76
+ }
77
+
78
+ static validateDefinition ({points} = {}) {
79
+ const
80
+ {length = 0} = points ?? [];
81
+
82
+ if (length < 2) {
83
+ return false;
84
+ } else {
85
+ for (let i = 0; i < length; i++) {
86
+ const
87
+ point = points[i];
88
+
89
+ if (!Point.validateDefinition(Array.isArray(point) ? {x: point[0], y: point[1]} : point)) {
90
+ return false;
91
+ }
92
+ }
93
+
94
+ return true;
95
+ }
96
+ }
97
+ }
@@ -0,0 +1,78 @@
1
+ import Polygon from "./Polygon";
2
+
3
+ const
4
+ errDelta = 0.0001,
5
+ isRectangle = ({x: ax, y: ay}, {x: bx, y: by}, {x: cx, y: cy}, {x: dx, y: dy}) => {
6
+ const
7
+ sqr = (a) => a * a,
8
+ x = (ax + bx + cx + dx) / 4,
9
+ y = (ay + by + cy + dy) / 4,
10
+ asqr = sqr(x - ax) + sqr(y - ay),
11
+ bsqr = sqr(x - bx) + sqr(y - by),
12
+ csqr = sqr(x - cx) + sqr(y - cy),
13
+ dsqr = sqr(x - dx) + sqr(y - dy);
14
+
15
+ return Math.abs(asqr - bsqr) < errDelta &&
16
+ Math.abs(asqr - csqr) < errDelta &&
17
+ Math.abs(asqr - dsqr) < errDelta;
18
+ };
19
+
20
+ export default class Rectangle extends Polygon {
21
+ constructor (...args) {
22
+ super(...args);
23
+ this.type = 'rectangle';
24
+ }
25
+
26
+ get halfHeight () {
27
+ return this.height / 2;
28
+ }
29
+
30
+ set halfHeight (hh) {
31
+ this.height = hh * 2;
32
+ }
33
+
34
+ get halfWidth () {
35
+ return this.width / 2;
36
+ }
37
+
38
+ set halfWidth (hw) {
39
+ this.width = hw * 2;
40
+ }
41
+
42
+ initialize (options) {
43
+ const
44
+ {anchor: {x: ax, y: ay} = {x: 0, y: 0}, height, width, x = 0, y = 0} = options,
45
+ left = x - ax * width,
46
+ top = y - ay * height,
47
+ right = x + (1 - ax) * width,
48
+ bottom = y + (1 - ay) * height;
49
+
50
+ this.width = width;
51
+ this.height = height;
52
+
53
+ super.initialize({
54
+ ...options,
55
+ points: [{
56
+ x: left,
57
+ y: top
58
+ }, {
59
+ x: right,
60
+ y: top
61
+ }, {
62
+ x: right,
63
+ y: bottom
64
+ }, {
65
+ x: left,
66
+ y: bottom
67
+ }]
68
+ });
69
+ }
70
+
71
+ duplicate () {
72
+ return new Rectangle(this);
73
+ }
74
+
75
+ static validateDefinition ({height, width, points} = {}) {
76
+ return typeof height === 'number' && height > 0 && typeof width === 'number' && width > 0 && (!points || ((points.length === 4) && isRectangle(...points)));
77
+ }
78
+ }
@@ -0,0 +1,33 @@
1
+ import Circle from "./Circle";
2
+ import Rectangle from "./Rectangle";
3
+
4
+ export default class RoundedRectangle extends Rectangle {
5
+ constructor (...args) {
6
+ super(...args);
7
+ this.type = 'roundedRectangle';
8
+ }
9
+
10
+ initialize (options) {
11
+ super.initialize(options);
12
+ this.radius = options.radius;
13
+ }
14
+
15
+ duplicate () {
16
+ return new RoundedRectangle(this);
17
+ }
18
+
19
+ toObject (options) {
20
+ const
21
+ {radius} = this,
22
+ {scale} = options;
23
+
24
+ return {
25
+ ...super.toObject(options),
26
+ radius: radius * scale
27
+ }
28
+ }
29
+
30
+ static validateDefinition (definition) {
31
+ return Circle.validateDefinition(definition) && Rectangle.validateDefinition(definition);
32
+ }
33
+ }
@@ -0,0 +1,346 @@
1
+ import Point from './Point';
2
+ import Vector from '../Vector';
3
+
4
+ const
5
+ EPSILON = 1e-10;
6
+
7
+ export default class Segment extends Point {
8
+ constructor (...args) {
9
+ super(...args);
10
+ this.type = 'segment';
11
+ this._points = null;
12
+ this._revolutions = 0;
13
+ }
14
+
15
+ get a () {
16
+ return this.points[0];
17
+ }
18
+
19
+ get b () {
20
+ return this.points[this.points.length - 1];
21
+ }
22
+
23
+ get points () {
24
+ if (!this._points) {
25
+ const
26
+ {revolutions, x: X, y: Y} = this;
27
+
28
+ if (revolutions % 1) {
29
+ const
30
+ {cos, sin} = this.getSinCos();
31
+
32
+ this._points = this._vectors.map(({x, y}) => new Point({
33
+ x: X + x * cos - y * sin,
34
+ y: Y + x * sin + y * cos
35
+ }));
36
+ } else {
37
+ this._points = this._vectors.map(({x, y}) => new Point({
38
+ x: X + x,
39
+ y: Y + y
40
+ }));
41
+ }
42
+ }
43
+ return this._points;
44
+ }
45
+
46
+ get revolutions () {
47
+ return this._revolutions;
48
+ }
49
+
50
+ set revolutions (revolutions) {
51
+ if (this._revolutions !== revolutions) {
52
+ this._points = null; // need to recalculate if they exist.
53
+ this._revolutions = revolutions;
54
+ }
55
+ }
56
+
57
+ get vectors () {
58
+ return this._vectors;
59
+ }
60
+
61
+ initialize (options) {
62
+ const
63
+ {a, b, points, revolutions = 0, x = 0, y = 0} = options;
64
+
65
+ super.initialize(options);
66
+
67
+ if (revolutions % 1) {
68
+ const
69
+ {cos, sin} = this.getSinCos();
70
+
71
+ this._vectors = (points ?? [a, b]).map((point) => {
72
+ if (Array.isArray(point)) {
73
+ return new Vector(point[0] * cos + point[1] * sin - x, -point[0] * sin + point[1] * cos - y);
74
+ } else {
75
+ return new Vector(point.x * cos + point.y * sin - x, -point.x * sin + point.y * cos - y);
76
+ }
77
+ });
78
+ } else {
79
+ this._vectors = (points ?? [a, b]).map((point) => {
80
+ if (Array.isArray(point)) {
81
+ return new Vector(point[0] - x, point[1] - y);
82
+ } else {
83
+ return new Vector(point.x - x, point.y - y);
84
+ }
85
+ });
86
+ }
87
+ }
88
+
89
+ getLength () {
90
+ const
91
+ {a, b} = this;
92
+
93
+ return Math.hypot(b.x - a.x, b.y - a.y);
94
+ }
95
+
96
+ intersects ({a: c, b: d}) {
97
+ const
98
+ ccw = (a, b, c) => (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x),
99
+ {a, b} = this;
100
+
101
+ return ccw(a, c, d) !== ccw(b, c, d) && ccw(a, b, c) !== ccw(a, b, d);
102
+ }
103
+
104
+ getIntersection (segment, {intersectsLine = false, segmentIsLine = false}) {
105
+ // Solve line intersection using determinants
106
+ const
107
+ {a, b} = this,
108
+ {a: c, b: d} = segment,
109
+ dabx = a.x - b.x,
110
+ daby = a.y - b.y,
111
+ dcdx = c.x - d.x,
112
+ dcdy = c.y - d.y,
113
+ det = dabx * dcdy - daby * dcdx;
114
+
115
+ if (Math.abs(det) < EPSILON) {
116
+ return null; // parallel or coincident
117
+ } else {
118
+ const
119
+ projection = (a, b, v) => (a.x - b.x) * v.x + (a.y - b.y) * v.y,
120
+ daxbyaybx = a.x * b.y - a.y * b.x,
121
+ dcxdycydx = c.x * d.y - c.y * d.x,
122
+ xy = new Point({
123
+ x: (daxbyaybx * dcdx - dabx * dcxdycydx) / det,
124
+ y: (daxbyaybx * dcdy - daby * dcxdycydx) / det
125
+ });
126
+
127
+ if (!intersectsLine) {
128
+ const
129
+ v = this.getVector(),
130
+ proj = projection(xy, a, v),
131
+ min = Math.min(0, projection(b, a, v)),
132
+ max = Math.max(0, projection(b, a, v));
133
+
134
+ v.recycle();
135
+
136
+ if (proj < min - EPSILON || proj > max + EPSILON) {
137
+ return null;
138
+ }
139
+ }
140
+
141
+ // Clamp against "segment" unless infinite
142
+ if (!segmentIsLine) {
143
+ const
144
+ v = segment.getVector(),
145
+ proj = projection(xy, c, v),
146
+ min = Math.min(0, projection(d, c, v)),
147
+ max = Math.max(0, projection(d, c, v));
148
+
149
+ v.recycle();
150
+
151
+ if (proj < min - EPSILON || proj > max + EPSILON) {
152
+ return null;
153
+ }
154
+ }
155
+
156
+ return xy;
157
+ }
158
+ }
159
+
160
+ getVector () {
161
+ const
162
+ {a, b} = this;
163
+
164
+ return Vector.setUp(b.x - a.x, b.y - a.y);
165
+ }
166
+
167
+ duplicate () {
168
+ return new Segment(this);
169
+ }
170
+
171
+ moveX (x) {
172
+ super.moveX(x);
173
+ this._points = null;
174
+ }
175
+
176
+ moveY (y) {
177
+ super.moveY(y);
178
+ this._points = null;
179
+ }
180
+
181
+ reflect (point) {
182
+ const
183
+ {a, b} = this,
184
+ segment = Vector.setUp(b.x - a.x, b.y - a.y),
185
+ aToPoint = Vector.setUp(point.x - a.x, point.y - a.y),
186
+ dot = segment.x * aToPoint.x + segment.y * aToPoint.y,
187
+ segmentSqr = segment.x * segment.x + segment.y * segment.y,
188
+ projectionFactor = dot / segmentSqr,
189
+ projectionOfPoint = Vector.setUp(a.x + projectionFactor * segment.x, a.y + projectionFactor * segment.y),
190
+ reflection = new Point({
191
+ x: 2 * projectionOfPoint.x - point.x,
192
+ y: 2 * projectionOfPoint.y - point.y
193
+ });
194
+
195
+ segment.recycle();
196
+ aToPoint.recycle();
197
+ projectionOfPoint.recycle();
198
+
199
+ return reflection;
200
+ }
201
+
202
+ isCollinear (segment, {epsilon = EPSILON} = {}) {
203
+ const
204
+ {a, b} = this,
205
+ {a: c, b: d} = segment,
206
+ orient = (p, q, r) => (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y),
207
+ aOrient = orient(c, d, a),
208
+ bOrient = orient(c, d, b);
209
+
210
+ return Math.abs(aOrient) < epsilon && Math.abs(bOrient) < epsilon;
211
+ }
212
+
213
+ bisect (segment, options) {
214
+ const
215
+ {a, b} = this,
216
+ {a: c, b: d} = segment,
217
+ v = segment.getVector(),
218
+ orient = (p, q, r) => (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y),
219
+ aOrient = orient(c, d, a),
220
+ bOrient = orient(c, d, b);
221
+
222
+ if (Math.abs(aOrient) < EPSILON && Math.abs(bOrient) < EPSILON) {
223
+ // collinear bisect
224
+ const
225
+ projection = (a) => (a.x - c.x) * v.x + (a.y - c.y) * v.y,
226
+ magA = projection(a),
227
+ magB = projection(b),
228
+ magC = projection(c),
229
+ magD = projection(d),
230
+ segmentMin = Math.min(magC, magD),
231
+ segmentMax = Math.max(magC, magD),
232
+ myMin = Math.min(magA, magB),
233
+ myMax = Math.max(magA, magB);
234
+
235
+ if (myMax < segmentMin) {
236
+ return [this, null];
237
+ } else if (myMin > segmentMax) {
238
+ return [null, this];
239
+ } else if (myMin >= segmentMin && myMax <= segmentMax) {
240
+ return [null, null]
241
+ } else {
242
+ // using unnormalized projection, so divide by |v|²
243
+ const
244
+ len2 = v.x * v.x + v.y * v.y;
245
+
246
+ return [
247
+ magA < segmentMin ? new Segment({
248
+ a,
249
+ b: {
250
+ x: c.x + (segmentMin / len2) * v.x,
251
+ y: c.y + (segmentMin / len2) * v.y
252
+ }
253
+ }) : null,
254
+ magB > segmentMax ? new Segment({
255
+ a: {
256
+ x: c.x + (segmentMax / len2) * v.x,
257
+ y: c.y + (segmentMax / len2) * v.y
258
+ },
259
+ b
260
+ }) : null
261
+ ]
262
+ }
263
+ } else if (aOrient > -EPSILON && bOrient > -EPSILON) {
264
+ return [this, null];
265
+ } else if (aOrient < EPSILON && bOrient < EPSILON) {
266
+ return [null, this];
267
+ } else {
268
+ const
269
+ intersection = this.getIntersection(segment, options);
270
+
271
+ if (!intersection) {
272
+ // no split, return identity
273
+ if (aOrient > 0) {
274
+ return [this, null];
275
+ } else {
276
+ return [null, this];
277
+ }
278
+ } else {
279
+ const
280
+ left = new Segment({a, b: intersection}),
281
+ right = new Segment({a: intersection, b});
282
+
283
+ return aOrient > 0 ? [left, right] : [right, left];
284
+ }
285
+ }
286
+ }
287
+
288
+ toArray (local = false) {
289
+ if (local) {
290
+ return this.vectors.map(({x, y}) => new Vector(x, y));
291
+ } else {
292
+ return this.points.map(({x, y}) => new Point({
293
+ x,
294
+ y
295
+ }));
296
+ }
297
+ }
298
+
299
+ toArray1D (local = false) {
300
+ if (local) {
301
+ return this.vectors.reduce((arr, {x, y}) => {
302
+ arr.push(x, y);
303
+ return arr
304
+ }, []);
305
+ } else {
306
+ return this.points.reduce((arr, {x, y}) => {
307
+ arr.push(x, y);
308
+ return arr
309
+ }, []);
310
+ }
311
+ }
312
+
313
+ toArray2D (local = false) {
314
+ if (local) {
315
+ return this.vectors.map(({x, y}) => ([x, y]));
316
+ } else {
317
+ return this.points.map(({x, y}) => ([x, y]));
318
+ }
319
+ }
320
+
321
+ toObject (options) {
322
+ const
323
+ {a, b, type} = this;
324
+
325
+ return {
326
+ a: adjustedXY(a, options),
327
+ b: adjustedXY(b, options),
328
+ type
329
+ };
330
+ }
331
+
332
+ static validateDefinition ({a, b, points} = {}) {
333
+ const
334
+ ab = points ?? [a, b];
335
+
336
+ if (ab.length !== 2) {
337
+ return false;
338
+ } else {
339
+ const
340
+ A = Array.isArray(ab[0]) ? {x: ab[0][0], y: ab[0][1]} : ab[0],
341
+ B = Array.isArray(ab[1]) ? {x: ab[1][0], y: ab[1][1]} : ab[1];
342
+
343
+ return Point.validateDefinition(A) && Point.validateDefinition(B) && (A.x !== B.x || A.y !== B.y);
344
+ }
345
+ }
346
+ }
@@ -0,0 +1,19 @@
1
+ export default function adjustedXY (shape, {local = true, scale = 1}) {
2
+ if (local) {
3
+ const
4
+ {registration: {x, y}} = shape;
5
+
6
+ return {
7
+ x: x * scale,
8
+ y: y * scale
9
+ };
10
+ } else {
11
+ const
12
+ {x, y} = shape;
13
+
14
+ return {
15
+ x: x * scale,
16
+ y: y * scale
17
+ };
18
+ }
19
+ }
@@ -0,0 +1,92 @@
1
+ import castFromObject from "./castFromObject";
2
+
3
+ /* global platypus */
4
+ const
5
+ BOX2D_SHAPES = [
6
+ 'circle',
7
+ 'capsule',
8
+ 'segment',
9
+ 'polygon',
10
+ 'segment' // <-- unsure how to convert chain shape segment into its owning chain shape as a `polyline`, so it'll be converted to a segment. */
11
+ ],
12
+ castTo = {
13
+ circle: (shapeId, {scale = 1} = {}) => {
14
+ const
15
+ {radius, center: {x, y}} = platypus.game.box2d.b2Shape_GetCircle(shapeId);
16
+
17
+ return {
18
+ radius: radius * scale,
19
+ type: 'circle',
20
+ x: x * scale,
21
+ y: y * scale
22
+ };
23
+ },
24
+ capsule: (shapeId, {scale = 1} = {}) => {
25
+ const
26
+ {radius, center1: {x: ax, y: ay}, center2: {x: bx, y: by}} = platypus.game.box2d.b2Shape_GetCapsule(shapeId);
27
+
28
+ return {
29
+ a: {
30
+ x: ax * scale,
31
+ y: ay * scale
32
+ },
33
+ b: {
34
+ x: bx * scale,
35
+ y: by * scale
36
+ },
37
+ radius: radius * scale,
38
+ type: 'capsule'
39
+ };
40
+ },
41
+ segment: (shapeId, {scale = 1} = {}) => {
42
+ const
43
+ {point1: {x: ax, y: ay}, point2: {x: bx, y: by}} = platypus.game.box2d.b2Shape_GetSegment(shapeId);
44
+
45
+ return {
46
+ a: {
47
+ x: ax * scale,
48
+ y: ay * scale
49
+ },
50
+ b: {
51
+ x: bx * scale,
52
+ y: by * scale
53
+ },
54
+ type: 'segment'
55
+ };
56
+ },
57
+ polygon: (shapeId, {scale = 1} = {}) => {
58
+ const
59
+ poly = platypus.game.box2d.b2Shape_GetPolygon(shapeId),
60
+ {count, radius} = poly,
61
+ points = [];
62
+
63
+ for (let i = 0; i < count; i++) {
64
+ const
65
+ {x, y} = poly.GetVertex(i);
66
+
67
+ points.push({
68
+ x: x * scale,
69
+ y: y * scale
70
+ });
71
+ }
72
+
73
+ return {
74
+ points,
75
+ radius: radius * scale,
76
+ type: 'polygon'
77
+ };
78
+ }
79
+ };
80
+
81
+ export default function castFromBox2D (shapeId, options) {
82
+ const
83
+ {b2Shape_GetType} = platypus.game.box2d,
84
+ shape = BOX2D_SHAPES[b2Shape_GetType(shapeId).value];
85
+
86
+ if (shape) {
87
+ return castFromObject(castTo[shape](shapeId, options));
88
+ } else {
89
+ platypus.debug.warn(`Unable to cast shape of type "${shape}" from Box2D.`, shape);
90
+ return null;
91
+ }
92
+ }