@vpmedia/phaser 1.0.1 → 1.0.2

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 (107) hide show
  1. package/dist/phaser.cjs.LICENSE.txt +1 -1
  2. package/dist/phaser.js.LICENSE.txt +1 -1
  3. package/package.json +2 -3
  4. package/src/index.js +99 -0
  5. package/src/phaser/core/animation.js +355 -0
  6. package/src/phaser/core/animation_manager.js +238 -0
  7. package/src/phaser/core/animation_parser.js +130 -0
  8. package/src/phaser/core/array_set.js +108 -0
  9. package/src/phaser/core/cache.js +558 -0
  10. package/src/phaser/core/const.js +106 -0
  11. package/src/phaser/core/device.js +67 -0
  12. package/src/phaser/core/device_util.js +386 -0
  13. package/src/phaser/core/dom.js +207 -0
  14. package/src/phaser/core/event_manager.js +243 -0
  15. package/src/phaser/core/factory.js +74 -0
  16. package/src/phaser/core/frame.js +75 -0
  17. package/src/phaser/core/frame_data.js +84 -0
  18. package/src/phaser/core/frame_util.js +31 -0
  19. package/src/phaser/core/game.js +412 -0
  20. package/src/phaser/core/input.js +401 -0
  21. package/src/phaser/core/input_button.js +102 -0
  22. package/src/phaser/core/input_handler.js +687 -0
  23. package/src/phaser/core/input_mouse.js +289 -0
  24. package/src/phaser/core/input_mspointer.js +197 -0
  25. package/src/phaser/core/input_pointer.js +427 -0
  26. package/src/phaser/core/input_touch.js +157 -0
  27. package/src/phaser/core/loader.js +946 -0
  28. package/src/phaser/core/loader_parser.js +105 -0
  29. package/src/phaser/core/raf.js +46 -0
  30. package/src/phaser/core/raf_fb.js +75 -0
  31. package/src/phaser/core/raf_to.js +34 -0
  32. package/src/phaser/core/scale_manager.js +806 -0
  33. package/src/phaser/core/scene.js +66 -0
  34. package/src/phaser/core/scene_manager.js +310 -0
  35. package/src/phaser/core/signal.js +175 -0
  36. package/src/phaser/core/signal_binding.js +69 -0
  37. package/src/phaser/core/sound.js +538 -0
  38. package/src/phaser/core/sound_manager.js +365 -0
  39. package/src/phaser/core/stage.js +108 -0
  40. package/src/phaser/core/time.js +203 -0
  41. package/src/phaser/core/timer.js +276 -0
  42. package/src/phaser/core/timer_event.js +21 -0
  43. package/src/phaser/core/tween.js +329 -0
  44. package/src/phaser/core/tween_data.js +258 -0
  45. package/src/phaser/core/tween_easing.js +316 -0
  46. package/src/phaser/core/tween_manager.js +185 -0
  47. package/src/phaser/core/world.js +18 -0
  48. package/src/phaser/display/bitmap_text.js +322 -0
  49. package/src/phaser/display/button.js +194 -0
  50. package/src/phaser/display/canvas/buffer.js +36 -0
  51. package/src/phaser/display/canvas/graphics.js +227 -0
  52. package/src/phaser/display/canvas/masker.js +39 -0
  53. package/src/phaser/display/canvas/pool.js +121 -0
  54. package/src/phaser/display/canvas/renderer.js +123 -0
  55. package/src/phaser/display/canvas/tinter.js +141 -0
  56. package/src/phaser/display/canvas/util.js +151 -0
  57. package/src/phaser/display/display_object.js +597 -0
  58. package/src/phaser/display/graphics.js +723 -0
  59. package/src/phaser/display/graphics_data.js +27 -0
  60. package/src/phaser/display/graphics_data_util.js +14 -0
  61. package/src/phaser/display/group.js +227 -0
  62. package/src/phaser/display/image.js +288 -0
  63. package/src/phaser/display/sprite_batch.js +15 -0
  64. package/src/phaser/display/sprite_util.js +248 -0
  65. package/src/phaser/display/text.js +1089 -0
  66. package/src/phaser/display/webgl/abstract_filter.js +25 -0
  67. package/src/phaser/display/webgl/base_texture.js +68 -0
  68. package/src/phaser/display/webgl/blend_manager.js +35 -0
  69. package/src/phaser/display/webgl/earcut.js +647 -0
  70. package/src/phaser/display/webgl/earcut_node.js +28 -0
  71. package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
  72. package/src/phaser/display/webgl/filter_manager.js +46 -0
  73. package/src/phaser/display/webgl/filter_texture.js +61 -0
  74. package/src/phaser/display/webgl/graphics.js +618 -0
  75. package/src/phaser/display/webgl/graphics_data.js +42 -0
  76. package/src/phaser/display/webgl/mask_manager.js +36 -0
  77. package/src/phaser/display/webgl/render_texture.js +81 -0
  78. package/src/phaser/display/webgl/renderer.js +234 -0
  79. package/src/phaser/display/webgl/shader/complex.js +74 -0
  80. package/src/phaser/display/webgl/shader/fast.js +97 -0
  81. package/src/phaser/display/webgl/shader/normal.js +225 -0
  82. package/src/phaser/display/webgl/shader/primitive.js +72 -0
  83. package/src/phaser/display/webgl/shader/strip.js +77 -0
  84. package/src/phaser/display/webgl/shader_manager.js +89 -0
  85. package/src/phaser/display/webgl/sprite_batch.js +320 -0
  86. package/src/phaser/display/webgl/stencil_manager.js +170 -0
  87. package/src/phaser/display/webgl/texture.js +117 -0
  88. package/src/phaser/display/webgl/texture_util.js +32 -0
  89. package/src/phaser/display/webgl/util.js +74 -0
  90. package/src/phaser/geom/circle.js +186 -0
  91. package/src/phaser/geom/ellipse.js +65 -0
  92. package/src/phaser/geom/line.js +190 -0
  93. package/src/phaser/geom/matrix.js +147 -0
  94. package/src/phaser/geom/point.js +164 -0
  95. package/src/phaser/geom/polygon.js +141 -0
  96. package/src/phaser/geom/rectangle.js +306 -0
  97. package/src/phaser/geom/rounded_rectangle.js +36 -0
  98. package/src/phaser/geom/util/circle.js +115 -0
  99. package/src/phaser/geom/util/ellipse.js +30 -0
  100. package/src/phaser/geom/util/line.js +130 -0
  101. package/src/phaser/geom/util/matrix.js +48 -0
  102. package/src/phaser/geom/util/point.js +276 -0
  103. package/src/phaser/geom/util/polygon.js +24 -0
  104. package/src/phaser/geom/util/rectangle.js +212 -0
  105. package/src/phaser/geom/util/rounded_rectangle.js +28 -0
  106. package/src/phaser/util/math.js +279 -0
  107. package/src/phaser/util/string.js +26 -0
@@ -0,0 +1,401 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
5
+ */
6
+ import ArraySet from './array_set';
7
+ import Graphics from '../display/graphics';
8
+ import Image from '../display/image';
9
+ import Signal from './signal';
10
+ import Point from '../geom/point';
11
+ import Circle from '../geom/circle';
12
+ import Mouse from './input_mouse';
13
+ import MSPointer from './input_mspointer';
14
+ import Pointer from './input_pointer';
15
+ import Touch from './input_touch';
16
+ import { POINTER_CURSOR, POINTER_CONTACT, MOUSE_TOUCH_COMBINE } from './const';
17
+ import { create, remove } from '../display/canvas/pool';
18
+
19
+ const MAX_POINTERS = 10;
20
+
21
+ export default class {
22
+
23
+ constructor(game) {
24
+ this.game = game;
25
+ this.hitCanvas = null;
26
+ this.hitContext = null;
27
+ this.moveCallbacks = [];
28
+ this.lockCallbacks = [];
29
+ this.customCandidateHandler = null;
30
+ this.customCandidateHandlerContext = null;
31
+ this.pollRate = 0;
32
+ this.enabled = true;
33
+ this.multiInputOverride = MOUSE_TOUCH_COMBINE;
34
+ this.position = null;
35
+ this.speed = null;
36
+ this.circle = null;
37
+ this.scale = null;
38
+ this.maxPointers = 1;
39
+ this.tapRate = 200;
40
+ this.doubleTapRate = 300;
41
+ this.holdRate = 2000;
42
+ this.justPressedRate = 200;
43
+ this.justReleasedRate = 200;
44
+ this.recordPointerHistory = false;
45
+ this.recordRate = 100;
46
+ this.recordLimit = 100;
47
+ this.pointer1 = null;
48
+ this.pointer2 = null;
49
+ this.pointer3 = null;
50
+ this.pointer4 = null;
51
+ this.pointer5 = null;
52
+ this.pointer6 = null;
53
+ this.pointer7 = null;
54
+ this.pointer8 = null;
55
+ this.pointer9 = null;
56
+ this.pointer10 = null;
57
+ this.pointers = [];
58
+ this.activePointer = null;
59
+ this.mousePointer = null;
60
+ this.mouse = null;
61
+ this.touch = null;
62
+ this.mspointer = null;
63
+ this.resetLocked = false;
64
+ this.onDown = null;
65
+ this.onUp = null;
66
+ this.onTap = null;
67
+ this.onHold = null;
68
+ this.minPriorityID = 0;
69
+ this.interactiveItems = new ArraySet();
70
+ this._localPoint = new Point();
71
+ this._pollCounter = 0;
72
+ this._oldPosition = null;
73
+ this._x = 0;
74
+ this._y = 0;
75
+ }
76
+
77
+ boot() {
78
+ this.mousePointer = new Pointer(this.game, 0, POINTER_CURSOR);
79
+ this.addPointer();
80
+ this.addPointer();
81
+ this.mouse = new Mouse(this.game);
82
+ this.touch = new Touch(this.game);
83
+ this.mspointer = new MSPointer(this.game);
84
+ this.onDown = new Signal();
85
+ this.onUp = new Signal();
86
+ this.onTap = new Signal();
87
+ this.onHold = new Signal();
88
+ this.scale = new Point(1, 1);
89
+ this.speed = new Point();
90
+ this.position = new Point();
91
+ this._oldPosition = new Point();
92
+ this.circle = new Circle(0, 0, 44);
93
+ this.activePointer = this.mousePointer;
94
+ this.hitCanvas = create(this, 1, 1);
95
+ this.hitContext = this.hitCanvas.getContext('2d');
96
+ this.mouse.start();
97
+ if (this.game.device.mspointer) {
98
+ this.mspointer.start();
99
+ } else if (this.game.device.touch) {
100
+ this.touch.start();
101
+ }
102
+ this.mousePointer.active = true;
103
+ const scope = this;
104
+ this._onClickTrampoline = event => scope.onClickTrampoline(event);
105
+ this.game.canvas.addEventListener('click', this._onClickTrampoline, false);
106
+ }
107
+
108
+ destroy() {
109
+ this.mouse.stop();
110
+ if (this.game.device.mspointer) {
111
+ this.mspointer.stop();
112
+ } else if (this.game.device.touch) {
113
+ this.touch.stop();
114
+ }
115
+ this.moveCallbacks = [];
116
+ remove(this);
117
+ this.game.canvas.removeEventListener('click', this._onClickTrampoline);
118
+ }
119
+
120
+ setInteractiveCandidateHandler(callback, context) {
121
+ this.customCandidateHandler = callback;
122
+ this.customCandidateHandlerContext = context;
123
+ }
124
+
125
+ addMoveCallback(callback, context) {
126
+ this.moveCallbacks.push({ callback, context });
127
+ }
128
+
129
+ deleteMoveCallback(callback, context) {
130
+ let i = this.moveCallbacks.length;
131
+ while (i) {
132
+ i -= 1;
133
+ if (this.moveCallbacks[i].callback === callback && this.moveCallbacks[i].context === context) {
134
+ this.moveCallbacks.splice(i, 1);
135
+ return;
136
+ }
137
+ }
138
+ }
139
+
140
+ addTouchLockCallback(callback, context, onEnd = false) {
141
+ this.lockCallbacks.push({ callback, context, onEnd });
142
+ }
143
+
144
+ removeTouchLockCallback(callback, context) {
145
+ let i = this.lockCallbacks.length;
146
+ while (i) {
147
+ i -= 1;
148
+ if (this.lockCallbacks[i].callback === callback && this.lockCallbacks[i].context === context) {
149
+ this.lockCallbacks.splice(i, 1);
150
+ return true;
151
+ }
152
+ }
153
+ return false;
154
+ }
155
+
156
+ executeTouchLockCallbacks(onEnd, event) {
157
+ let i = this.lockCallbacks.length;
158
+ while (i) {
159
+ i -= 1;
160
+ const cb = this.lockCallbacks[i];
161
+ if (cb.onEnd === onEnd && cb.callback.call(cb.context, this, event)) {
162
+ this.lockCallbacks.splice(i, 1);
163
+ }
164
+ }
165
+ }
166
+
167
+ addPointer() {
168
+ if (this.pointers.length >= MAX_POINTERS) {
169
+ console.warn('Input.addPointer: Maximum limit of ' + MAX_POINTERS + ' pointers reached.');
170
+ return null;
171
+ }
172
+ const id = this.pointers.length + 1;
173
+ const pointer = new Pointer(this.game, id, POINTER_CONTACT);
174
+ this.pointers.push(pointer);
175
+ this['pointer' + id] = pointer;
176
+ return pointer;
177
+ }
178
+
179
+ update() {
180
+ if (this.pollRate > 0 && this._pollCounter < this.pollRate) {
181
+ this._pollCounter += 1;
182
+ return;
183
+ }
184
+ this.speed.x = this.position.x - this._oldPosition.x;
185
+ this.speed.y = this.position.y - this._oldPosition.y;
186
+ this._oldPosition.copyFrom(this.position);
187
+ this.mousePointer.update();
188
+ for (let i = 0; i < this.pointers.length; i += 1) {
189
+ this.pointers[i].update();
190
+ }
191
+ this._pollCounter = 0;
192
+ }
193
+
194
+ reset(hard = false) {
195
+ if (!this.game.isBooted || this.resetLocked) {
196
+ return;
197
+ }
198
+ this.mousePointer.reset();
199
+ for (let i = 0; i < this.pointers.length; i += 1) {
200
+ this.pointers[i].reset();
201
+ }
202
+ if (this.game.canvas.style.cursor !== 'none') {
203
+ this.game.canvas.style.cursor = 'inherit';
204
+ }
205
+ if (hard) {
206
+ this.onDown.dispose();
207
+ this.onUp.dispose();
208
+ this.onTap.dispose();
209
+ this.onHold.dispose();
210
+ this.onDown = new Signal();
211
+ this.onUp = new Signal();
212
+ this.onTap = new Signal();
213
+ this.onHold = new Signal();
214
+ this.moveCallbacks = [];
215
+ }
216
+ this._pollCounter = 0;
217
+ }
218
+
219
+ resetSpeed(x, y) {
220
+ this._oldPosition.setTo(x, y);
221
+ this.speed.setTo(0, 0);
222
+ }
223
+
224
+ startPointer(event) {
225
+ if (this.maxPointers >= 0 && this.countActivePointers(this.maxPointers) >= this.maxPointers) {
226
+ return null;
227
+ }
228
+ if (!this.pointer1.active) {
229
+ return this.pointer1.start(event);
230
+ }
231
+ if (!this.pointer2.active) {
232
+ return this.pointer2.start(event);
233
+ }
234
+ for (let i = 2; i < this.pointers.length; i += 1) {
235
+ const pointer = this.pointers[i];
236
+ if (!pointer.active) {
237
+ return pointer.start(event);
238
+ }
239
+ }
240
+ return null;
241
+ }
242
+
243
+ updatePointer(event) {
244
+ if (this.pointer1.active && this.pointer1.identifier === event.identifier) {
245
+ return this.pointer1.move(event);
246
+ }
247
+ if (this.pointer2.active && this.pointer2.identifier === event.identifier) {
248
+ return this.pointer2.move(event);
249
+ }
250
+ for (let i = 2; i < this.pointers.length; i += 1) {
251
+ const pointer = this.pointers[i];
252
+ if (pointer.active && pointer.identifier === event.identifier) {
253
+ return pointer.move(event);
254
+ }
255
+ }
256
+ return null;
257
+ }
258
+
259
+ stopPointer(event) {
260
+ if (this.pointer1.active && this.pointer1.identifier === event.identifier) {
261
+ return this.pointer1.stop(event);
262
+ }
263
+ if (this.pointer2.active && this.pointer2.identifier === event.identifier) {
264
+ return this.pointer2.stop(event);
265
+ }
266
+ for (let i = 2; i < this.pointers.length; i += 1) {
267
+ const pointer = this.pointers[i];
268
+ if (pointer.active && pointer.identifier === event.identifier) {
269
+ return pointer.stop(event);
270
+ }
271
+ }
272
+ return null;
273
+ }
274
+
275
+ countActivePointers(limit = this.pointers.length) {
276
+ let count = limit;
277
+ for (let i = 0; i < this.pointers.length && count > 0; i += 1) {
278
+ const pointer = this.pointers[i];
279
+ if (pointer.active) {
280
+ count -= 1;
281
+ }
282
+ }
283
+ return (limit - count);
284
+ }
285
+
286
+ getPointer(isActive = false) {
287
+ for (let i = 0; i < this.pointers.length; i += 1) {
288
+ const pointer = this.pointers[i];
289
+ if (pointer.active === isActive) {
290
+ return pointer;
291
+ }
292
+ }
293
+ return null;
294
+ }
295
+
296
+ getPointerFromIdentifier(identifier) {
297
+ for (let i = 0; i < this.pointers.length; i += 1) {
298
+ const pointer = this.pointers[i];
299
+ if (pointer.identifier === identifier) {
300
+ return pointer;
301
+ }
302
+ }
303
+
304
+ return null;
305
+ }
306
+
307
+ getPointerFromId(pointerId) {
308
+ for (let i = 0; i < this.pointers.length; i += 1) {
309
+ const pointer = this.pointers[i];
310
+ if (pointer.pointerId === pointerId) {
311
+ return pointer;
312
+ }
313
+ }
314
+
315
+ return null;
316
+ }
317
+
318
+ getLocalPosition(displayObject, pointer, output = null) {
319
+ const result = output || new Point();
320
+ const wt = displayObject.worldTransform;
321
+ const id = 1 / (wt.a * wt.d + wt.c * -wt.b);
322
+ return result.setTo(wt.d * id * pointer.x + -wt.c * id * pointer.y + (wt.ty * wt.c - wt.tx * wt.d) * id, wt.a * id * pointer.y + -wt.b * id * pointer.x + (-wt.ty * wt.a + wt.tx * wt.b) * id);
323
+ }
324
+
325
+ hitTest(displayObject, pointer, localPoint) {
326
+ if (!displayObject.worldVisible) {
327
+ return false;
328
+ }
329
+ this.getLocalPosition(displayObject, pointer, this._localPoint);
330
+ localPoint.copyFrom(this._localPoint);
331
+ if (displayObject.hitArea && displayObject.hitArea.contains) {
332
+ return (displayObject.hitArea.contains(this._localPoint.x, this._localPoint.y));
333
+ } else if (displayObject instanceof Image) {
334
+ const width = displayObject.texture.frame.width;
335
+ const height = displayObject.texture.frame.height;
336
+ const x1 = -width * displayObject.anchor.x;
337
+ if (this._localPoint.x >= x1 && this._localPoint.x < x1 + width) {
338
+ const y1 = -height * displayObject.anchor.y;
339
+ if (this._localPoint.y >= y1 && this._localPoint.y < y1 + height) {
340
+ return true;
341
+ }
342
+ }
343
+ } else if (displayObject instanceof Graphics) {
344
+ for (let i = 0; i < displayObject.graphicsData.length; i += 1) {
345
+ const data = displayObject.graphicsData[i];
346
+ if (data.fill && data.shape && data.shape.contains(this._localPoint.x, this._localPoint.y)) {
347
+ // Only deal with fills..
348
+ return true;
349
+ }
350
+ }
351
+ }
352
+ // Didn't hit the parent, does it have any children?
353
+ for (let i = 0; i < displayObject.children.length; i += 1) {
354
+ if (this.hitTest(displayObject.children[i], pointer, localPoint)) {
355
+ return true;
356
+ }
357
+ }
358
+ return false;
359
+ }
360
+
361
+ onClickTrampoline() {
362
+ this.activePointer.processClickTrampolines();
363
+ }
364
+
365
+ get x() {
366
+ return this._x;
367
+ }
368
+
369
+ set x(value) {
370
+ this._x = Math.floor(value);
371
+ }
372
+
373
+ get y() {
374
+ return this._y;
375
+ }
376
+
377
+ set y(value) {
378
+ this._y = Math.floor(value);
379
+ }
380
+
381
+ get pollLocked() {
382
+ return (this.pollRate > 0 && this._pollCounter < this.pollRate);
383
+ }
384
+
385
+ get totalInactivePointers() {
386
+ return this.pointers.length - this.countActivePointers();
387
+ }
388
+
389
+ get totalActivePointers() {
390
+ return this.countActivePointers();
391
+ }
392
+
393
+ get worldX() {
394
+ return this.x;
395
+ }
396
+
397
+ get worldY() {
398
+ return this.y;
399
+ }
400
+
401
+ }
@@ -0,0 +1,102 @@
1
+ import Signal from './signal';
2
+ /**
3
+ * @author Andras Csizmadia <andras@vpmedia.hu>
4
+ * @author Richard Davey <rich@photonstorm.com>
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+
8
+ export default class {
9
+
10
+ constructor(parent, buttonCode) {
11
+ this.parent = parent;
12
+ this.game = parent.game;
13
+ this.event = null;
14
+ this.isDown = false;
15
+ this.isUp = true;
16
+ this.timeDown = 0;
17
+ this.timeUp = 0;
18
+ this.repeats = 0;
19
+ this.altKey = false;
20
+ this.shiftKey = false;
21
+ this.ctrlKey = false;
22
+ this.value = 0;
23
+ this.buttonCode = buttonCode;
24
+ this.onDown = new Signal();
25
+ this.onUp = new Signal();
26
+ this.onFloat = new Signal();
27
+ }
28
+
29
+ start(event, value) {
30
+ if (this.isDown) {
31
+ return;
32
+ }
33
+ this.isDown = true;
34
+ this.isUp = false;
35
+ this.timeDown = this.game.time.time;
36
+ this.repeats = 0;
37
+ this.event = event;
38
+ this.value = value;
39
+ if (event) {
40
+ this.altKey = event.altKey;
41
+ this.shiftKey = event.shiftKey;
42
+ this.ctrlKey = event.ctrlKey;
43
+ }
44
+ this.onDown.dispatch(this, value);
45
+ }
46
+
47
+ stop(event, value) {
48
+ if (this.isUp) {
49
+ return;
50
+ }
51
+ this.isDown = false;
52
+ this.isUp = true;
53
+ this.timeUp = this.game.time.time;
54
+ this.event = event;
55
+ this.value = value;
56
+ if (event) {
57
+ this.altKey = event.altKey;
58
+ this.shiftKey = event.shiftKey;
59
+ this.ctrlKey = event.ctrlKey;
60
+ }
61
+ this.onUp.dispatch(this, value);
62
+ }
63
+
64
+ padFloat(value) {
65
+ this.value = value;
66
+ this.onFloat.dispatch(this, value);
67
+ }
68
+
69
+ justPressed(duration = 250) {
70
+ return (this.isDown && (this.timeDown + duration) > this.game.time.time);
71
+ }
72
+
73
+ justReleased(duration = 250) {
74
+ return (this.isUp && (this.timeUp + duration) > this.game.time.time);
75
+ }
76
+
77
+ reset() {
78
+ this.isDown = false;
79
+ this.isUp = true;
80
+ this.timeDown = this.game.time.time;
81
+ this.repeats = 0;
82
+ this.altKey = false;
83
+ this.shiftKey = false;
84
+ this.ctrlKey = false;
85
+ }
86
+
87
+ destroy() {
88
+ this.onDown.dispose();
89
+ this.onUp.dispose();
90
+ this.onFloat.dispose();
91
+ this.parent = null;
92
+ this.game = null;
93
+ }
94
+
95
+ get duration() {
96
+ if (this.isUp) {
97
+ return -1;
98
+ }
99
+ return this.game.time.time - this.timeDown;
100
+ }
101
+
102
+ }