@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,365 @@
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 Signal from './signal';
8
+ import Sound from './sound';
9
+
10
+ export default class {
11
+
12
+ constructor(game) {
13
+ this.game = game;
14
+ this.onSoundDecode = new Signal();
15
+ this.onVolumeChange = new Signal();
16
+ this.onMute = new Signal();
17
+ this.onUnMute = new Signal();
18
+ this.context = null;
19
+ this.baseLatency = 0; // https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/baseLatency
20
+ this.usingWebAudio = false;
21
+ this.usingAudioTag = false;
22
+ this.noAudio = false;
23
+ this.connectToMaster = true;
24
+ this.touchLocked = false;
25
+ this.muteOnPause = true;
26
+ this._codeMuted = false;
27
+ this._muted = false;
28
+ this._unlockSource = null;
29
+ this._volume = 1;
30
+ this._sounds = [];
31
+ this._watchList = new ArraySet();
32
+ this._watching = false;
33
+ this._watchCallback = null;
34
+ this._watchContext = null;
35
+ }
36
+
37
+ boot() {
38
+ if (window.PhaserRegistry && window.PhaserRegistry.audioContext) {
39
+ this.context = window.PhaserRegistry.audioContext;
40
+ } else if (window.AudioContext) {
41
+ try {
42
+ this.context = new window.AudioContext();
43
+ } catch (error) {
44
+ this.context = null;
45
+ this.usingWebAudio = false;
46
+ this.touchLocked = false;
47
+ }
48
+ } else if (window.webkitAudioContext) {
49
+ try {
50
+ /* eslint-disable new-cap */
51
+ this.context = new window.webkitAudioContext();
52
+ } catch (error) {
53
+ this.context = null;
54
+ this.usingWebAudio = false;
55
+ this.touchLocked = false;
56
+ }
57
+ }
58
+ if (this.context === null || (this.context && this.context.createGain === undefined && this.context.createGainNode === undefined)) {
59
+ // No Web Audio support - how about legacy Audio?
60
+ if (window.Audio === undefined) {
61
+ this.noAudio = true;
62
+ return;
63
+ }
64
+ this.usingAudioTag = true;
65
+ } else {
66
+ this.usingWebAudio = true;
67
+ this.baseLatency = this.context.baseLatency || (256 / (this.context.sampleRate || 44100));
68
+ if (this.context.createGain === undefined) {
69
+ this.masterGain = this.context.createGainNode();
70
+ } else {
71
+ this.masterGain = this.context.createGain();
72
+ }
73
+ this.masterGain.gain.value = 1;
74
+ this.masterGain.connect(this.context.destination);
75
+ if (this.context.state === 'suspended') {
76
+ this.game.input.onUp.addOnce(this.resumeWebAudio, this);
77
+ }
78
+ }
79
+ if (!this.noAudio && !this.game.device.cocoonJS && (this.game.device.iOS || this.game.device.android)) {
80
+ this.game.input.addTouchLockCallback(this.unlock, this, true);
81
+ this.touchLocked = true;
82
+ }
83
+ }
84
+
85
+ resumeWebAudio() {
86
+ if (this.usingWebAudio && this.context.state === 'suspended') {
87
+ this.context.resume();
88
+ }
89
+ }
90
+
91
+ unlock() {
92
+ if (this.noAudio || !this.touchLocked || this._unlockSource !== null) {
93
+ return true;
94
+ }
95
+ // Global override (mostly for Audio Tag testing)
96
+ if (this.usingAudioTag) {
97
+ this.touchLocked = false;
98
+ this._unlockSource = null;
99
+ } else if (this.usingWebAudio) {
100
+ // Create empty buffer and play it
101
+ // The SoundManager.update loop captures the state of it and then resets touchLocked to false
102
+ const buffer = this.context.createBuffer(1, 1, 22050);
103
+ this._unlockSource = this.context.createBufferSource();
104
+ this._unlockSource.buffer = buffer;
105
+ this._unlockSource.connect(this.context.destination);
106
+ if (this._unlockSource.start === undefined) {
107
+ this._unlockSource.noteOn(0);
108
+ } else {
109
+ this._unlockSource.start(0);
110
+ }
111
+ this.resumeWebAudio();
112
+ }
113
+ // We can remove the event because we've done what we needed (started the unlock sound playing)
114
+ return true;
115
+ }
116
+
117
+ stopAll() {
118
+ if (this.noAudio) {
119
+ return;
120
+ }
121
+ for (let i = 0; i < this._sounds.length; i += 1) {
122
+ if (this._sounds[i]) {
123
+ this._sounds[i].stop();
124
+ }
125
+ }
126
+ }
127
+
128
+ pauseAll() {
129
+ if (this.noAudio) {
130
+ return;
131
+ }
132
+ for (let i = 0; i < this._sounds.length; i += 1) {
133
+ if (this._sounds[i]) {
134
+ this._sounds[i].pause();
135
+ }
136
+ }
137
+ }
138
+
139
+ resumeAll() {
140
+ if (this.noAudio) {
141
+ return;
142
+ }
143
+ for (let i = 0; i < this._sounds.length; i += 1) {
144
+ if (this._sounds[i]) {
145
+ this._sounds[i].resume();
146
+ }
147
+ }
148
+ }
149
+
150
+ decode(key, sound = null) {
151
+ const soundData = this.game.cache.getSoundData(key);
152
+ if (soundData) {
153
+ if (this.game.cache.isSoundDecoded(key) === false) {
154
+ this.game.cache.updateSound(key, 'isDecoding', true);
155
+ const scope = this;
156
+ try {
157
+ this.context.decodeAudioData(soundData, (buffer) => {
158
+ if (buffer) {
159
+ scope.game.cache.decodedSound(key, buffer);
160
+ scope.onSoundDecode.dispatch(key, sound);
161
+ }
162
+ });
163
+ } catch (e) {
164
+ // pass
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ setDecodedCallback(files, callback, callbackContext) {
171
+ if (typeof files === 'string') {
172
+ files = [files];
173
+ }
174
+ this._watchList.reset();
175
+ for (let i = 0; i < files.length; i += 1) {
176
+ if (files[i] instanceof Sound) {
177
+ if (!this.game.cache.isSoundDecoded(files[i].key)) {
178
+ this._watchList.add(files[i].key);
179
+ }
180
+ } else if (!this.game.cache.isSoundDecoded(files[i])) {
181
+ this._watchList.add(files[i]);
182
+ }
183
+ }
184
+ // All decoded already?
185
+ if (this._watchList.total === 0) {
186
+ this._watching = false;
187
+ callback.call(callbackContext);
188
+ } else {
189
+ this._watching = true;
190
+ this._watchCallback = callback;
191
+ this._watchContext = callbackContext;
192
+ }
193
+ }
194
+
195
+ update() {
196
+ if (this.noAudio) {
197
+ return;
198
+ }
199
+ if (this.touchLocked && this._unlockSource !== null && (this._unlockSource.playbackState === this._unlockSource.PLAYING_STATE || this._unlockSource.playbackState === this._unlockSource.FINISHED_STATE)) {
200
+ this.touchLocked = false;
201
+ this._unlockSource = null;
202
+ this.resumeWebAudio();
203
+ } else if (this.usingWebAudio && this.context.state === 'interrupted') {
204
+ this.context.resume();
205
+ }
206
+ for (let i = 0; i < this._sounds.length; i += 1) {
207
+ this._sounds[i].update();
208
+ }
209
+ if (this._watching) {
210
+ let key = this._watchList.first;
211
+ while (key) {
212
+ if (this.game.cache.isSoundDecoded(key)) {
213
+ this._watchList.remove(key);
214
+ }
215
+ key = this._watchList.next;
216
+ }
217
+ if (this._watchList.total === 0) {
218
+ this._watching = false;
219
+ this._watchCallback.call(this._watchContext);
220
+ }
221
+ }
222
+ }
223
+
224
+ add(key, volume = 1, loop = false, connect = this.connectToMaster) {
225
+ const sound = new Sound(this.game, key, volume, loop, connect);
226
+ this._sounds.push(sound);
227
+ return sound;
228
+ }
229
+
230
+ remove(sound) {
231
+ let i = this._sounds.length;
232
+ while (i) {
233
+ i -= 1;
234
+ if (this._sounds[i] === sound) {
235
+ this._sounds[i].destroy(false);
236
+ this._sounds.splice(i, 1);
237
+ return true;
238
+ }
239
+ }
240
+ return false;
241
+ }
242
+
243
+ removeByKey(key) {
244
+ let i = this._sounds.length;
245
+ let removed = 0;
246
+ while (i) {
247
+ i -= 1;
248
+ if (this._sounds[i].key === key) {
249
+ this._sounds[i].destroy(false);
250
+ this._sounds.splice(i, 1);
251
+ removed += 1;
252
+ }
253
+ }
254
+ return removed;
255
+ }
256
+
257
+ play(key, volume = 1, loop = false) {
258
+ if (this.noAudio) {
259
+ return null;
260
+ }
261
+ const sound = this.add(key, volume, loop);
262
+ sound.play();
263
+ return sound;
264
+ }
265
+
266
+ setMute() {
267
+ if (this._muted) {
268
+ return;
269
+ }
270
+ this._muted = true;
271
+ if (this.usingWebAudio) {
272
+ this._muteVolume = this.masterGain.gain.value;
273
+ this.masterGain.gain.value = 0;
274
+ }
275
+ // Loop through sounds
276
+ for (let i = 0; i < this._sounds.length; i += 1) {
277
+ if (this._sounds[i].usingAudioTag) {
278
+ this._sounds[i].mute = true;
279
+ }
280
+ }
281
+ this.onMute.dispatch();
282
+ }
283
+
284
+ unsetMute() {
285
+ if (!this._muted || this._codeMuted) {
286
+ return;
287
+ }
288
+ this._muted = false;
289
+ if (this.usingWebAudio) {
290
+ this.masterGain.gain.value = this._muteVolume;
291
+ }
292
+ // Loop through sounds
293
+ for (let i = 0; i < this._sounds.length; i += 1) {
294
+ if (this._sounds[i].usingAudioTag) {
295
+ this._sounds[i].mute = false;
296
+ }
297
+ }
298
+ this.onUnMute.dispatch();
299
+ }
300
+
301
+ destroy() {
302
+ this.stopAll();
303
+ for (let i = 0; i < this._sounds.length; i += 1) {
304
+ if (this._sounds[i]) {
305
+ this._sounds[i].destroy();
306
+ }
307
+ }
308
+ this._sounds = [];
309
+ this.onSoundDecode.dispose();
310
+ if (this.context) {
311
+ if (window.PhaserRegistry) {
312
+ window.PhaserRegistry.audioContext = this.context;
313
+ } else if (this.context.close) {
314
+ this.context.close();
315
+ }
316
+ }
317
+ }
318
+
319
+ get mute() {
320
+ return this._muted;
321
+ }
322
+
323
+ set mute(value) {
324
+ if (value || false) {
325
+ if (this._muted) {
326
+ return;
327
+ }
328
+ this._codeMuted = true;
329
+ this.setMute();
330
+ } else {
331
+ if (!this._muted) {
332
+ return;
333
+ }
334
+ this._codeMuted = false;
335
+ this.unsetMute();
336
+ }
337
+ }
338
+
339
+ get volume() {
340
+ return this._volume;
341
+ }
342
+
343
+ set volume(value) {
344
+ if (value < 0) {
345
+ value = 0;
346
+ } else if (value > 1) {
347
+ value = 1;
348
+ }
349
+ if (this._volume !== value) {
350
+ this._volume = value;
351
+ if (this.usingWebAudio) {
352
+ this.masterGain.gain.value = value;
353
+ } else {
354
+ // Loop through the sound cache and change the volume of all html audio tags
355
+ for (let i = 0; i < this._sounds.length; i += 1) {
356
+ if (this._sounds[i].usingAudioTag) {
357
+ this._sounds[i].updateGlobalVolume(value);
358
+ }
359
+ }
360
+ }
361
+ this.onVolumeChange.dispatch(value);
362
+ }
363
+ }
364
+
365
+ }
@@ -0,0 +1,108 @@
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 Matrix from '../geom/matrix';
7
+ import DisplayObject from '../display/display_object';
8
+ import { setUserSelect, setTouchAction } from '../display/canvas/util';
9
+ import { valueToColor } from '../util/math';
10
+ import { SCALE_LINEAR, SCALE_NEAREST } from './const';
11
+
12
+ export default class extends DisplayObject {
13
+
14
+ constructor(game) {
15
+ super();
16
+ this.game = game;
17
+ this.name = '_stage_root';
18
+ this.worldTransform = new Matrix();
19
+ this.currentRenderOrderID = 0;
20
+ this._bgColor = {
21
+ r: 0,
22
+ g: 0,
23
+ b: 0,
24
+ a: 0,
25
+ color: 0,
26
+ rgba: '#000000',
27
+ };
28
+ if (!game.config.transparent) {
29
+ // transparent = 0,0,0,0 - otherwise r,g,b,1
30
+ this._bgColor.a = 1;
31
+ }
32
+ if (game.config.backgroundColor && !this.game.config.transparent) {
33
+ this.setBackgroundColor(game.config.backgroundColor);
34
+ }
35
+ }
36
+
37
+ setBackgroundColor(color) {
38
+ if (this.game.config.transparent) {
39
+ return;
40
+ }
41
+ valueToColor(color, this._bgColor);
42
+ // For gl.clearColor (canvas uses _bgColor.rgba)
43
+ this._bgColor.r /= 255;
44
+ this._bgColor.g /= 255;
45
+ this._bgColor.b /= 255;
46
+ this._bgColor.a = 1;
47
+ }
48
+
49
+ boot() {
50
+ setUserSelect(this.game.canvas, 'none');
51
+ setTouchAction(this.game.canvas, 'none');
52
+ }
53
+
54
+ preUpdate() {
55
+ this.currentRenderOrderID = 0;
56
+ // This can't loop in reverse, we need the renderOrderID to be in sequence
57
+ for (let i = 0; i < this.children.length; i += 1) {
58
+ this.children[i].preUpdate();
59
+ }
60
+ }
61
+
62
+ update() {
63
+ let i = this.children.length;
64
+ while (i) {
65
+ i -= 1;
66
+ this.children[i].update();
67
+ }
68
+ }
69
+
70
+ postUpdate() {
71
+ for (let i = 0; i < this.children.length; i += 1) {
72
+ this.children[i].postUpdate();
73
+ }
74
+ this.updateTransform();
75
+ }
76
+
77
+ updateTransform() {
78
+ this.worldAlpha = 1;
79
+ for (let i = 0; i < this.children.length; i += 1) {
80
+ this.children[i].updateTransform();
81
+ }
82
+ }
83
+
84
+ destroy() {
85
+ this.exists = false;
86
+ this.game = null;
87
+ this.worldTransform = null;
88
+ this._bgColor = null;
89
+ }
90
+
91
+ get backgroundColor() {
92
+ return this._bgColor.color;
93
+ }
94
+
95
+ set backgroundColor(value) {
96
+ this.setBackgroundColor(value);
97
+ }
98
+
99
+ get smoothed() {
100
+ return window.PhaserRegistry.TEXTURE_SCALE_MODE === SCALE_LINEAR;
101
+ }
102
+
103
+ set smoothed(value) {
104
+ window.PhaserRegistry.TEXTURE_SCALE_MODE = value ? SCALE_LINEAR : SCALE_NEAREST;
105
+ }
106
+
107
+
108
+ }
@@ -0,0 +1,203 @@
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 Timer from './timer';
7
+
8
+ export default class {
9
+
10
+ constructor(game) {
11
+ this.game = game;
12
+ this.time = 0;
13
+ this.prevTime = 0;
14
+ this.now = 0;
15
+ this.elapsed = 0;
16
+ this.elapsedMS = 0;
17
+ this.physicsElapsed = 1 / 60;
18
+ this.physicsElapsedMS = (1 / 60) * 1000;
19
+ this.desiredFpsMult = 1.0 / 60;
20
+ this._desiredFps = 60;
21
+ this.suggestedFps = this.desiredFps;
22
+ this.slowMotion = 1.0;
23
+ this.advancedTiming = false;
24
+ this.frames = 0;
25
+ this.fps = 0;
26
+ this.fpsMin = 1000;
27
+ this.fpsMax = 0;
28
+ this.msMin = 1000;
29
+ this.msMax = 0;
30
+ this.pauseDuration = 0;
31
+ this.timeToCall = 0;
32
+ this.timeExpected = 0;
33
+ this.events = new Timer(this.game, false);
34
+ this._frameCount = 0;
35
+ this._elapsedAccumulator = 0;
36
+ this._started = 0;
37
+ this._timeLastSecond = 0;
38
+ this._pauseStarted = 0;
39
+ this._justResumed = false;
40
+ this._timers = [];
41
+ }
42
+
43
+ boot() {
44
+ this._started = Date.now();
45
+ this.time = Date.now();
46
+ this.events.start();
47
+ this.timeExpected = this.time;
48
+ }
49
+
50
+ add(timer) {
51
+ this._timers.push(timer);
52
+ return timer;
53
+ }
54
+
55
+ create(autoDestroy = true) {
56
+ const timer = new Timer(this.game, autoDestroy);
57
+ this._timers.push(timer);
58
+ return timer;
59
+ }
60
+
61
+ removeAll() {
62
+ for (let i = 0; i < this._timers.length; i += 1) {
63
+ this._timers[i].destroy();
64
+ }
65
+ this._timers = [];
66
+ this.events.removeAll();
67
+ }
68
+
69
+ refresh() {
70
+ const previousDateNow = this.time;
71
+ // this.time always holds a Date.now value
72
+ this.time = Date.now();
73
+ // Adjust accordingly.
74
+ this.elapsedMS = this.time - previousDateNow;
75
+ }
76
+
77
+ update(time) {
78
+ const previousDateNow = this.time;
79
+ // this.time always holds a Date.now value
80
+ this.time = Date.now();
81
+ // Adjust accordingly.
82
+ this.elapsedMS = this.time - previousDateNow;
83
+ // 'now' is currently still holding the time of the last call, move it into prevTime
84
+ this.prevTime = this.now;
85
+ // update 'now' to hold the current time
86
+ // this.now may hold the RAF high resolution time value if RAF is available (otherwise it also holds Date.now)
87
+ this.now = time;
88
+ // elapsed time between previous call and now - this could be a high resolution value
89
+ this.elapsed = this.now - this.prevTime;
90
+ if (this.game.raf._isSetTimeOut) {
91
+ // console.log('Time isSet', this._desiredFps, 'te', this.timeExpected, 'time', time);
92
+ // time to call this function again in ms in case we're using timers instead of RequestAnimationFrame to update the game
93
+ this.timeToCall = Math.floor(Math.max(0, (1000.0 / this._desiredFps) - (this.timeExpected - time)));
94
+ // time when the next call is expected if using timers
95
+ this.timeExpected = time + this.timeToCall;
96
+ // console.log('Time expect', this.timeExpected);
97
+ }
98
+ if (this.advancedTiming) {
99
+ this.updateAdvancedTiming();
100
+ }
101
+ // Paused but still running?
102
+ if (!this.game.paused) {
103
+ // Our internal Phaser.Timer
104
+ this.events.update(this.time);
105
+ if (this._timers.length) {
106
+ this.updateTimers();
107
+ }
108
+ }
109
+ }
110
+
111
+ updateTimers() {
112
+ let i = 0;
113
+ let len = this._timers.length;
114
+ while (i < len) {
115
+ if (this._timers[i].update(this.time)) {
116
+ i += 1;
117
+ } else {
118
+ // Timer requests to be removed
119
+ this._timers.splice(i, 1);
120
+ len -= 1;
121
+ }
122
+ }
123
+ }
124
+
125
+ updateAdvancedTiming() {
126
+ // count the number of time.update calls
127
+ this._frameCount += 1;
128
+ this._elapsedAccumulator += this.elapsed;
129
+ // occasionally recalculate the suggestedFps based on the accumulated elapsed time
130
+ if (this._frameCount >= this._desiredFps * 2) {
131
+ // this formula calculates suggestedFps in multiples of 5 fps
132
+ this.suggestedFps = Math.floor(200 / (this._elapsedAccumulator / this._frameCount)) * 5;
133
+ this._frameCount = 0;
134
+ this._elapsedAccumulator = 0;
135
+ }
136
+ this.msMin = Math.min(this.msMin, this.elapsed);
137
+ this.msMax = Math.max(this.msMax, this.elapsed);
138
+ this.frames += 1;
139
+ if (this.now > this._timeLastSecond + 1000) {
140
+ this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond));
141
+ this.fpsMin = Math.min(this.fpsMin, this.fps);
142
+ this.fpsMax = Math.max(this.fpsMax, this.fps);
143
+ this._timeLastSecond = this.now;
144
+ this.frames = 0;
145
+ }
146
+ }
147
+
148
+ gamePaused() {
149
+ this._pauseStarted = Date.now();
150
+ this.events.pause();
151
+ let i = this._timers.length;
152
+ while (i) {
153
+ i -= 1;
154
+ this._timers[i]._pause();
155
+ }
156
+ }
157
+
158
+ gameResumed() {
159
+ this.time = Date.now();
160
+ this.pauseDuration = this.time - this._pauseStarted;
161
+ this.events.resume();
162
+ let i = this._timers.length;
163
+ while (i) {
164
+ i -= 1;
165
+ this._timers[i]._resume();
166
+ }
167
+ }
168
+
169
+ totalElapsedSeconds() {
170
+ return (this.time - this._started) * 0.001;
171
+ }
172
+
173
+ elapsedSince(since) {
174
+ return this.time - since;
175
+ }
176
+
177
+ elapsedSecondsSince(since) {
178
+ return (this.time - since) * 0.001;
179
+ }
180
+
181
+ reset() {
182
+ this._started = this.time;
183
+ this.removeAll();
184
+ }
185
+
186
+ destroy() {
187
+ this.reset();
188
+ }
189
+
190
+ get desiredFps() {
191
+ return this._desiredFps;
192
+ }
193
+
194
+ set desiredFps(value) {
195
+ this._desiredFps = value;
196
+ // Set the physics elapsed time... this will always be 1 / this.desiredFps
197
+ // because we're using fixed time steps in game.update
198
+ this.physicsElapsed = 1 / value;
199
+ this.physicsElapsedMS = this.physicsElapsed * 1000;
200
+ this.desiredFpsMult = 1.0 / value;
201
+ }
202
+
203
+ }