@makefully/platypus 4.1.4 → 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 (134) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +4 -2
  3. package/lib/platypus.js +1 -1
  4. package/package.json +7 -2
  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
@@ -0,0 +1,697 @@
1
+ import {arrayCache, greenSplice} from '../utils/array.js';
2
+ import Data from '../Data.js';
3
+ import Vector from '../Vector.js';
4
+ import createComponentClass from '../factory.js';
5
+ import {greenSplit} from '../utils/string.js';
6
+
7
+ const
8
+ normal = Vector.setUp(0, 0, 1),
9
+ origin = Vector.setUp(1, 0, 0),
10
+ matrices = {
11
+ 'identity': [[ 1, 0, 0],
12
+ [ 0, 1, 0],
13
+ [ 0, 0, 1]],
14
+ 'horizontal': [[ -1, 0, 0],
15
+ [ 0, 1, 0],
16
+ [ 0, 0, -1]],
17
+ 'vertical': [[ 1, 0, 0],
18
+ [ 0, -1, 0],
19
+ [ 0, 0, -1]],
20
+ 'diagonal': [[ 0, 1, 0],
21
+ [ 1, 0, 0],
22
+ [ 0, 0, -1]],
23
+ 'diagonal-inverse': [[ 0, -1, 0],
24
+ [ -1, 0, 0],
25
+ [ 0, 0, -1]],
26
+ 'rotate-90': [[ 0, -1, 0],
27
+ [ 1, 0, 0],
28
+ [ 0, 0, 1]],
29
+ 'rotate-180': [[ -1, 0, 0],
30
+ [ 0, -1, 0],
31
+ [ 0, 0, 1]],
32
+ 'rotate-270': [[ 0, 1, 0],
33
+ [ -1, 0, 0],
34
+ [ 0, 0, 1]]
35
+ },
36
+ multiply = (function () {
37
+ const
38
+ cell = function (row, column, m) {
39
+ let sum = 0;
40
+
41
+ for (let i = 0; i < row.length; i++) {
42
+ sum += row[i] * m[i][column];
43
+ }
44
+
45
+ return sum;
46
+ };
47
+
48
+ return function (a, b, dest) {
49
+ const
50
+ arr = arrayCache.setUp();
51
+
52
+ for (let i = 0; i < a.length; i++) {
53
+ for (let j = 0; j < a[0].length; j++) {
54
+ arr.push(cell(a[i], j, b));
55
+ }
56
+ }
57
+
58
+ for (let i = 0; i < a.length; i++) {
59
+ for (let j = 0; j < a[0].length; j++) {
60
+ dest[i][j] = arr.shift();
61
+ }
62
+ }
63
+
64
+ arrayCache.recycle(arr);
65
+ };
66
+ }()),
67
+ identitize = function (m) {
68
+ for (let i = 0; i < 3; i++) {
69
+ for (let j = 0; j < 3; j++) {
70
+ if (i === j) {
71
+ m[i][j] = 1;
72
+ } else {
73
+ m[i][j] = 0;
74
+ }
75
+ }
76
+ }
77
+
78
+ return m;
79
+ },
80
+ setupOrientation = function (self, orientation) {
81
+ const
82
+ vector = Vector.setUp(1, 0, 0),
83
+ owner = self.owner,
84
+ matrix = arrayCache.setUp(
85
+ arrayCache.setUp(1, 0, 0),
86
+ arrayCache.setUp(0, 1, 0),
87
+ arrayCache.setUp(0, 0, 1)
88
+ );
89
+
90
+ Object.defineProperty(owner, 'orientationMatrix', {
91
+ get: function () {
92
+ multiply(self.matrixTween, self.matrix, identitize(matrix));
93
+ return matrix;
94
+ },
95
+ enumerable: true
96
+ });
97
+
98
+ delete owner.orientation;
99
+ Object.defineProperty(owner, 'orientation', {
100
+ get: function () {
101
+ return vector.signedAngleTo(origin, normal);
102
+ },
103
+ set: function (value) {
104
+ vector.setVector(origin).rotate(value);
105
+ },
106
+ enumerable: true
107
+ });
108
+
109
+ Object.defineProperty(owner, 'rotation', {
110
+ get: function () {
111
+ return owner.orientation / Math.PI * 180;
112
+ },
113
+ set: function (value) {
114
+ owner.orientation = value * Math.PI / 180;
115
+ },
116
+ enumerable: true
117
+ });
118
+
119
+ if (orientation) {
120
+ if (typeof orientation !== 'number') {
121
+ vector.set(orientation);
122
+ } else {
123
+ vector.rotate(orientation);
124
+ }
125
+ }
126
+
127
+ return vector;
128
+ };
129
+
130
+ export default createComponentClass(/** @lends platypus.components.Orientation.prototype */{
131
+ id: 'Orientation',
132
+ publicProperties: {
133
+ /**
134
+ * The Entity's scale along the X-axis will mirror the entity's initial orientation if it is negative. This value is available via `entity.scaleX`, but is not manipulated by this component after instantiation.
135
+ *
136
+ * @property scaleX
137
+ * @type number
138
+ * @default 1
139
+ */
140
+ "scaleX": 1,
141
+
142
+ /**
143
+ * The Entity's scale along the Y-axis will flip the entity's initial orientation if it is negative. This value is available via `entity.scaleY`, but is not manipulated by this component after instantiation.
144
+ *
145
+ * @property scaleY
146
+ * @type number
147
+ * @default 1
148
+ */
149
+ "scaleY": 1,
150
+
151
+ /**
152
+ * The Entity's rotation will rotate entity's initial orientation if it is a multiple of 90 degrees. This value is available via `entity.rotation`, but is not manipulated by this component after instantiation.
153
+ *
154
+ * @property rotation
155
+ * @type number
156
+ * @default 0
157
+ */
158
+ "rotation": 0,
159
+
160
+ /**
161
+ * The Entity's orientation is an angle in radians describing an entity's orientation around the Z-axis. This property is affected by a changing `entity.orientationMatrix` but does not itself change the orientation matrix.
162
+ *
163
+ * @property orientation
164
+ * @type number
165
+ * @default 0
166
+ */
167
+ "orientation": 0,
168
+
169
+ /**
170
+ * The entity's orientation matrix determines the orientation of an entity and its vectors. It's a 3x3 2D Array describing an affine transformation of the entity.
171
+ *
172
+ * @property orientationMatrix
173
+ * @type Array
174
+ * @default 3x3 identity matrix
175
+ */
176
+ "orientationMatrix": null
177
+ },
178
+
179
+ /**
180
+ * This component handles the orientation of an entity. It maintains an `orientationMatrix` property on the owner to describe the entity's orientation using an affine transformation matrix.
181
+ *
182
+ * Several methods on this component accept either a 3x3 2D Array or a string to describe orientation changes. Accepted strings include:
183
+ * - "horizontal" - This flips the entity around the y-axis.
184
+ * - "vertical" - This flips the entity around the x-axis.
185
+ * - "diagonal" - This flips the entity around the x=y axis.
186
+ * - "diagonal-inverse" - This flips the entity around the x=-y axis.
187
+ * - "rotate-90" - This rotates the entity 90 degrees clockwise.
188
+ * - "rotate-180" - This rotates the entity 180 degrees clockwise (noticeable when tweening).
189
+ * - "rotate-270" - This rotates the entity 90 degrees counter-clockwise.
190
+ *
191
+ * NOTE: This component absorbs specific properties already on the entity into orientation:
192
+ * - **orientationMatrix**: 3x3 2D array describing an affine transformation.
193
+ * - If the above is not provided, these properties are used to set initial orientation. This is useful when importing Tiled maps.
194
+ * - **scaleX**: absorb -1 if described
195
+ * - **scaleY**: absorb -1 if described
196
+ * - **rotation**: absorb 90 degree rotations
197
+ *
198
+ * @memberof platypus.components
199
+ * @uses platypus.Component
200
+ * @constructs
201
+ * @listens platypus.Entity#handle-logic
202
+ * @listens platypus.Entity#append-transform
203
+ * @listens platypus.Entity#complete-tweens
204
+ * @listens platypus.Entity#drop-tweens
205
+ * @listens platypus.Entity#load
206
+ * @listens platypus.Entity#transform
207
+ * @listens platypus.Entity#translate
208
+ * @listens platypus.Entity#orient-vector
209
+ * @listens platypus.Entity#prepend-transform
210
+ * @listens platypus.Entity#remove-vector
211
+ * @listens platypus.Entity#replace-transform
212
+ * @listens platypus.Entity#tween-transform
213
+ * @fires platypus.Entity#orient-vector
214
+ * @fires platypus.Entity#orientation-updated
215
+ * @fires platypus.Entity#relocate-entity
216
+ */
217
+ initialize () {
218
+ this.loadedOrientationMatrix = this.orientationMatrix;
219
+
220
+ // This is the stationary transform
221
+ this.matrix = arrayCache.setUp(
222
+ arrayCache.setUp(1, 0, 0),
223
+ arrayCache.setUp(0, 1, 0),
224
+ arrayCache.setUp(0, 0, 1)
225
+ );
226
+
227
+ // This is the tweening transform
228
+ this.matrixTween = arrayCache.setUp(
229
+ arrayCache.setUp(1, 0, 0),
230
+ arrayCache.setUp(0, 1, 0),
231
+ arrayCache.setUp(0, 0, 1)
232
+ );
233
+
234
+ this.relocationMessage = Data.setUp(
235
+ "position", null
236
+ );
237
+
238
+ this.vectors = arrayCache.setUp();
239
+ this.inverses = arrayCache.setUp();
240
+ this.tweens = arrayCache.setUp();
241
+
242
+ this.orientationVector = setupOrientation(this, this.orientation);
243
+
244
+ /**
245
+ * On receiving a vector via this event, the component will transform the vector using the current orientation matrix and then store the vector and continue manipulating it as the orientation matrix changes.
246
+ *
247
+ * @event platypus.Entity#orient-vector
248
+ * @param vector {platypus.Vector} The vector whose orientation will be maintained.
249
+ */
250
+ this.owner.triggerEvent('orient-vector', this.orientationVector);
251
+
252
+ this.owner.state.set('reorienting', false);
253
+ },
254
+
255
+ events: {
256
+ "load": function () {
257
+ if (this.loadedOrientationMatrix) {
258
+ this.transform(this.loadedOrientationMatrix);
259
+ } else {
260
+ if (this.scaleX && this.scaleX < 0) {
261
+ this.scaleX = -this.scaleX;
262
+ this.transform('horizontal');
263
+ }
264
+ if (this.scaleY && this.scaleY < 0) {
265
+ this.scaleY = -this.scaleY;
266
+ this.transform('vertical');
267
+ }
268
+ if (this.rotation) {
269
+ if (((this.rotation + 270) % 360) === 0) {
270
+ this.rotation = 0;
271
+ this.transform('rotate-90');
272
+ } else if (((this.rotation + 180) % 360) === 0) {
273
+ this.rotation = 0;
274
+ this.transform('rotate-180');
275
+ } else if (((this.rotation + 90) % 360) === 0) {
276
+ this.rotation = 0;
277
+ this.transform('rotate-270');
278
+ }
279
+ }
280
+ }
281
+ delete this.loadedOrientationMatrix;
282
+ },
283
+
284
+ "handle-logic": function ({delta}) {
285
+ const
286
+ state = this.owner.state;
287
+ let i = this.tweens.length;
288
+
289
+ if (i) {
290
+ const
291
+ finishedTweening = arrayCache.setUp();
292
+
293
+ state.set('reorienting', true);
294
+ identitize(this.matrixTween);
295
+
296
+ while (i--) {
297
+ if (this.updateTween(this.tweens[i], delta)) { // finished tweening
298
+ finishedTweening.push(greenSplice(this.tweens, i));
299
+ }
300
+ }
301
+
302
+ i = this.vectors.length;
303
+ while (i--) {
304
+ this.updateVector(this.vectors[i], this.inverses[i]);
305
+ }
306
+
307
+ i = finishedTweening.length;
308
+ while (i--) {
309
+ const
310
+ tween = finishedTweening[i];
311
+
312
+ this.transform(tween.endMatrix);
313
+ if (tween.anchor) {
314
+ const
315
+ msg = this.relocationMessage;
316
+
317
+ tween.offset.multiply(tween.endMatrix).addVector(tween.anchor);
318
+ msg.position = tween.offset;
319
+ this.owner.triggerEvent('relocate-entity', msg);
320
+ if (tween.recycleOffset) {
321
+ tween.offset.recycle();
322
+ }
323
+ }
324
+ tween.onFinished(tween.endMatrix);
325
+ tween.recycle();
326
+ }
327
+
328
+ arrayCache.recycle(finishedTweening);
329
+ } else if (state.get('reorienting')) {
330
+ identitize(this.matrixTween);
331
+ state.set('reorienting', false);
332
+ }
333
+ },
334
+
335
+ /**
336
+ * On receiving this message, any currently running orientation tweens are immediately completed to give the entity a new stable position.
337
+ *
338
+ * @event platypus.Entity#complete-tweens
339
+ */
340
+ "complete-tweens": function () {
341
+ for (let i = 0; i < this.tweens.length; i++) {
342
+ this.tweens[i].time = this.tweens[i].endTime;
343
+ }
344
+ },
345
+
346
+ /**
347
+ * On receiving this message, any currently running orientation tweens are discarded, returning the entity to its last stable position.
348
+ *
349
+ * @event platypus.Entity#drop-tweens
350
+ */
351
+ "drop-tweens": function () {
352
+ let i = this.tweens.length;
353
+
354
+ while (i--) {
355
+ if (this.tweens[i].offset) {
356
+ this.tweens[i].offset.recycle();
357
+ }
358
+ }
359
+ this.tweens.length = 0;
360
+
361
+ i = this.vectors.length;
362
+ while (i--) {
363
+ this.updateVector(this.vectors[i], this.inverses[i]);
364
+ }
365
+ },
366
+
367
+ "orient-vector": function (vector) {
368
+ const
369
+ aligned = vector.aligned || false;
370
+
371
+ if (vector.vector) {
372
+ vector = vector.vector;
373
+ }
374
+
375
+ if (this.vectors.indexOf(vector) === -1) {
376
+ if (!aligned) {
377
+ vector.multiply(this.matrix);
378
+ }
379
+ this.vectors.push(vector);
380
+ this.inverses.push(Vector.setUp());
381
+ }
382
+ },
383
+
384
+ "remove-vector": function (vector) {
385
+ const
386
+ i = this.vectors.indexOf(vector);
387
+
388
+ if (i >= 0) {
389
+ greenSplice(this.vectors, i);
390
+ greenSplice(this.inverses, i).recycle();
391
+ }
392
+ },
393
+
394
+ /**
395
+ * This message performs a timed transform of the entity by performing the transformation via a prepended matrix multiplication.
396
+ *
397
+ * @event platypus.Entity#tween-transform
398
+ * @param transform {Array|String} A 3x3 @D Array or a string describing a transformation.
399
+ */
400
+ "tween-transform": function (options) {
401
+ this.tweenTransform(options);
402
+ },
403
+
404
+ /**
405
+ * This message performs an immediate transform of the entity by performing the transformation via a prepended matrix multiplication.
406
+ *
407
+ * @event platypus.Entity#transform
408
+ * @param transform {Array|String} A 3x3 @D Array or a string describing a transformation.
409
+ */
410
+ "transform": function (transform) {
411
+ this.transform(transform);
412
+ },
413
+
414
+ /**
415
+ * This message performs an immediate transform of the entity by performing the transformation via a prepended matrix multiplication.
416
+ *
417
+ * @event platypus.Entity#prepend-transform
418
+ * @param transform {Array|String} A 3x3 @D Array or a string describing a transformation.
419
+ */
420
+ "prepend-transform": function (transform) {
421
+ this.transform(transform);
422
+ },
423
+
424
+ /**
425
+ * This message performs an immediate transform of the entity by performing the transformation via an appended matrix multiplication.
426
+ *
427
+ * @event platypus.Entity#append-transform
428
+ * @param transform {Array|String} A 3x3 @D Array or a string describing a transformation.
429
+ */
430
+ "append-transform": function (transform) {
431
+ this.transform(transform, true);
432
+ },
433
+
434
+ /**
435
+ * This message performs an immediate transform of the entity by returning the entity to an identity transform before performing a matrix multiplication.
436
+ *
437
+ * @event platypus.Entity#replace-transform
438
+ * @param transform {Array|String} A 3x3 @D Array or a string describing a transformation.
439
+ */
440
+ "replace-transform": function (transform) {
441
+ if (Array.isArray(transform)) {
442
+ this.replace(transform);
443
+ } else if (typeof transform === 'string') {
444
+ if (matrices[transform]) {
445
+ this.replace(matrices[transform]);
446
+ }
447
+ }
448
+ }
449
+ },
450
+
451
+ methods: {
452
+ transform: function (transform, append) {
453
+ if (Array.isArray(transform)) {
454
+ this.multiply(transform, append);
455
+ } else if (typeof transform === 'string') {
456
+ if (matrices[transform]) {
457
+ this.multiply(matrices[transform], append);
458
+ }
459
+ }
460
+ },
461
+
462
+ multiply: function (m, append) {
463
+ if (append) {
464
+ multiply(this.matrix, m, this.matrix);
465
+ } else {
466
+ multiply(m, this.matrix, this.matrix);
467
+ }
468
+
469
+ for (let i = 0; i < this.vectors.length; i++) {
470
+ this.vectors[i].multiply(m);
471
+ this.inverses[i].multiply(m);
472
+ }
473
+
474
+ /**
475
+ * Once a transform is complete, this event is triggered to notify the entity of the completed transformation.
476
+ *
477
+ * @event platypus.Entity#orientation-updated
478
+ * @param matrix {Array} A 3x3 2D array describing the change in orientation.
479
+ */
480
+ this.owner.triggerEvent('orientation-updated', m);
481
+ },
482
+
483
+ replace: (function () {
484
+ const
485
+ det2 = function (a, b, c, d) {
486
+ return a * d - b * c;
487
+ },
488
+ det3 = function (a) {
489
+ let sum = 0;
490
+
491
+ for (let i = 0; i < 3; i++) {
492
+ sum += a[i][0] * a[(i + 1) % 3][1] * a[(i + 2) % 3][2];
493
+ sum -= a[i][2] * a[(i + 1) % 3][1] * a[(i + 2) % 3][0];
494
+ }
495
+ return sum;
496
+ },
497
+ invert = function (a) {
498
+ const
499
+ arr = arrayCache.setUp(arrayCache.setUp(), arrayCache.setUp(), arrayCache.setUp()),
500
+ inv = 1 / det3(a);
501
+
502
+ arr[0].push(det2(a[1][1], a[1][2], a[2][1], a[2][2]) * inv);
503
+ arr[0].push(det2(a[0][2], a[0][1], a[2][2], a[2][1]) * inv);
504
+ arr[0].push(det2(a[0][1], a[0][2], a[1][1], a[1][2]) * inv);
505
+ arr[1].push(det2(a[1][2], a[1][0], a[2][2], a[2][0]) * inv);
506
+ arr[1].push(det2(a[0][0], a[0][2], a[2][0], a[2][2]) * inv);
507
+ arr[1].push(det2(a[0][2], a[0][0], a[1][2], a[1][0]) * inv);
508
+ arr[2].push(det2(a[1][0], a[1][1], a[2][0], a[2][1]) * inv);
509
+ arr[2].push(det2(a[0][1], a[0][0], a[2][1], a[2][0]) * inv);
510
+ arr[2].push(det2(a[0][0], a[0][1], a[1][0], a[1][1]) * inv);
511
+
512
+ return arr;
513
+ };
514
+
515
+ return function (m) {
516
+ const
517
+ inversion = invert(this.matrix);
518
+
519
+ // We invert the matrix so we can re-orient all vectors for the incoming replacement matrix.
520
+ this.multiply(inversion);
521
+ this.multiply(m);
522
+
523
+ // clean-up
524
+ arrayCache.recycle(inversion, 2);
525
+ };
526
+ }()),
527
+
528
+ updateTween: (function () {
529
+ const
530
+ getMid = function (a, b, t) {
531
+ return (a * (1 - t) + b * t);
532
+ };
533
+
534
+ return function (tween, delta) {
535
+ const
536
+ m = tween.endMatrix;
537
+ let t = 0,
538
+ a = 1, // a c -
539
+ b = 0, // b d -
540
+ c = 0, // - - z
541
+ d = 1,
542
+ z = 1,
543
+ matrix = null,
544
+ angle = 0;
545
+
546
+ if (tween.beforeTick(tween.time)) {
547
+ tween.time += delta;
548
+ }
549
+
550
+ if (tween.time >= tween.endTime) {
551
+ return true;
552
+ }
553
+
554
+ t = tween.tween(tween.time / tween.endTime);
555
+
556
+ if (tween.angle) {
557
+ angle = t * tween.angle;
558
+ a = d = Math.cos(angle);
559
+ b = Math.sin(angle);
560
+ c = -b;
561
+ } else {
562
+ a = getMid(a, m[0][0], t);
563
+ b = getMid(b, m[1][0], t);
564
+ c = getMid(c, m[0][1], t);
565
+ d = getMid(d, m[1][1], t);
566
+ z = getMid(z, m[2][2], t);
567
+ }
568
+
569
+ matrix = arrayCache.setUp(
570
+ arrayCache.setUp(a, c, 0),
571
+ arrayCache.setUp(b, d, 0),
572
+ arrayCache.setUp(0, 0, z)
573
+ );
574
+
575
+ multiply(this.matrixTween, matrix, this.matrixTween);
576
+
577
+ if (tween.anchor) {
578
+ const
579
+ initialOffset = Vector.setUp(tween.offset).multiply(1 - t),
580
+ finalOffset = Vector.setUp(tween.offset).multiply(t);
581
+
582
+ this.owner.triggerEvent('relocate-entity', {
583
+ position: initialOffset.add(finalOffset).multiply(matrix).addVector(tween.anchor)
584
+ });
585
+
586
+ initialOffset.recycle();
587
+ finalOffset.recycle();
588
+ }
589
+
590
+ tween.afterTick(t, matrix);
591
+
592
+ arrayCache.recycle(matrix, 2);
593
+
594
+ return false;
595
+ };
596
+ }()),
597
+
598
+ updateVector: function (vector, inverse) {
599
+ inverse.setVector(vector.add(inverse)); // Inverses are stored to return to the original postion, *but* also allow outside changes on the vectors to be retained. This introduces floating point errors on tweened vectors. - DDD 2/10/2016
600
+ vector.multiply(this.matrixTween);
601
+ inverse.subtractVector(vector);
602
+ },
603
+
604
+ destroy: function () {
605
+ arrayCache.recycle(this.vectors); this.vectors = null;
606
+ arrayCache.recycle(this.inverses); this.inverses = null;
607
+ arrayCache.recycle(this.tweens); this.tweens = null;
608
+ this.orientationVector.recycle(); this.orientationVector = null;
609
+ arrayCache.recycle(this.orientationMatrix, 2);/* this.orientationMatrix = null; - Only has a setter */
610
+ arrayCache.recycle(this.matrix, 2); this.matrix = null;
611
+ arrayCache.recycle(this.matrixTween, 2); this.matrixTween = null;
612
+ this.relocationMessage.recycle(); this.relocationMessage = null;
613
+ }
614
+ },
615
+
616
+ publicMethods: {
617
+ /**
618
+ * This message causes the component to begin tweening the entity's orientation over a span of time into the new orientation.
619
+ *
620
+ * @method platypus.components.Orientation#tweenTransform
621
+ * @param {Object} options A list of key/value pairs describing the tween options.
622
+ * @param {Array} options.matrix A transformation matrix: only required if `transform` is not provided
623
+ * @param {String} options.transform A transformation type: only required if `matrix` is not provided.
624
+ * @param {number} options.time The time over which the tween occurs. 0 makes it instantaneous.
625
+ * @param {platypus.Vector} [options.anchor] The anchor of the orientation change. If not provided, the owner's position is used.
626
+ * @param {platypus.Vector} [options.offset] If an anchor is supplied, this vector describes the entity's distance from the anchor. It defaults to the entity's current position relative to the anchor position.
627
+ * @param {number} [options.angle] Angle in radians to transform. This is only valid for rotations and is derived from the transform if not provided.
628
+ * @param {Function} [options.tween] A function describing the transition. Performs a linear transition by default. See CreateJS Ease for other options.
629
+ * @param {Function} [options.beforeTick] A function that should be processed before each tick as the tween occurs. This function should return `true`, otherwise the tween doesn't take a step.
630
+ * @param {Function} [options.afterTick] A function that should be processed after each tick as the tween occurs.
631
+ * @param {Function} [options.onFinished] A function that should be run once the transition is complete.
632
+ */
633
+ tweenTransform: (function () {
634
+ const
635
+ doNothing = function () {
636
+ // Doing nothing!
637
+ },
638
+ returnTrue = function () {
639
+ return true;
640
+ },
641
+ linearEase = function (t) {
642
+ return t;
643
+ };
644
+
645
+ return function (props) {
646
+ const
647
+ matrix = props.matrix ?? matrices[props.transform],
648
+ tween = Data.setUp(
649
+ "transform", props.transform,
650
+ "anchor", props.anchor,
651
+ "endTime", props.time || 0,
652
+ "time", 0,
653
+ "tween", props.tween || linearEase,
654
+ "onFinished", props.onFinished || doNothing,
655
+ "beforeTick", props.beforeTick || returnTrue,
656
+ "afterTick", props.afterTick || doNothing
657
+ );
658
+ let angle = props.angle || 0;
659
+
660
+ tween.endMatrix = matrix;
661
+
662
+ if (!angle && (props.transform.indexOf('rotate') === 0)) {
663
+ switch (props.transform) {
664
+ case 'rotate-90':
665
+ angle = Math.PI / 2;
666
+ break;
667
+ case 'rotate-180':
668
+ angle = Math.PI;
669
+ break;
670
+ case 'rotate-270':
671
+ angle = -Math.PI / 2;
672
+ break;
673
+ default: {
674
+ const
675
+ arr = greenSplit(props.transform, '-');
676
+
677
+ angle = (arr[1] / 180) * Math.PI;
678
+ arrayCache.recycle(arr);
679
+ break;
680
+ }
681
+ }
682
+ }
683
+ tween.angle = angle;
684
+
685
+ if (props.anchor) {
686
+ tween.offset = props.offset;
687
+ if (!tween.offset) {
688
+ tween.offset = this.owner.position.copy().subtractVector(props.anchor, 2);
689
+ tween.recycleOffset = true;
690
+ }
691
+ }
692
+
693
+ this.tweens.push(tween);
694
+ };
695
+ }())
696
+ }
697
+ });