emeraldengine 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +968 -0
  2. package/dist/types/imports/BitmapText.d.ts +79 -0
  3. package/dist/types/imports/Color.d.ts +17 -0
  4. package/dist/types/imports/Drawable.d.ts +157 -0
  5. package/dist/types/imports/Emerald.d.ts +73 -0
  6. package/dist/types/imports/FPSCounter.d.ts +19 -0
  7. package/dist/types/imports/GLUtils.d.ts +6 -0
  8. package/dist/types/imports/Instance.d.ts +87 -0
  9. package/dist/types/imports/InstancedTexture.d.ts +230 -0
  10. package/dist/types/imports/Physics.d.ts +139 -0
  11. package/dist/types/imports/Scene.d.ts +39 -0
  12. package/dist/types/imports/Shaders.d.ts +4 -0
  13. package/dist/types/imports/Shapes.d.ts +25 -0
  14. package/dist/types/imports/Storage.d.ts +46 -0
  15. package/dist/types/imports/Texture.d.ts +19 -0
  16. package/dist/types/imports/Time.d.ts +22 -0
  17. package/dist/types/imports/Transform.d.ts +41 -0
  18. package/dist/types/imports/components/BoxCollider.d.ts +41 -0
  19. package/dist/types/imports/components/BoxColliderDebug.d.ts +19 -0
  20. package/dist/types/imports/components/CircleCollider.d.ts +39 -0
  21. package/dist/types/imports/components/CircleColliderDebug.d.ts +19 -0
  22. package/dist/types/imports/components/Collider.d.ts +53 -0
  23. package/dist/types/imports/components/GameObject.d.ts +72 -0
  24. package/dist/types/imports/components/RigidBody.d.ts +104 -0
  25. package/dist/types/imports/lights/DirectionalLight.d.ts +26 -0
  26. package/dist/types/imports/lights/PointLight.d.ts +18 -0
  27. package/dist/types/imports/managers/AudioManager.d.ts +60 -0
  28. package/dist/types/imports/managers/CameraManager.d.ts +35 -0
  29. package/dist/types/imports/managers/EventManager.d.ts +187 -0
  30. package/dist/types/imports/managers/GLManager.d.ts +47 -0
  31. package/dist/types/imports/managers/IDManager.d.ts +21 -0
  32. package/dist/types/imports/managers/SceneManager.d.ts +22 -0
  33. package/dist/types/imports/particlesystem/Particle.d.ts +42 -0
  34. package/dist/types/imports/particlesystem/ParticleSettings.d.ts +49 -0
  35. package/dist/types/imports/particlesystem/Particles.d.ts +71 -0
  36. package/dist/types/index.d.ts +32 -0
  37. package/imports/BitmapText.js +245 -0
  38. package/imports/Color.js +18 -0
  39. package/imports/Drawable.js +550 -0
  40. package/imports/Emerald.js +459 -0
  41. package/imports/FPSCounter.js +43 -0
  42. package/imports/GLUtils.js +67 -0
  43. package/imports/Instance.js +187 -0
  44. package/imports/InstancedTexture.js +856 -0
  45. package/imports/Physics.js +242 -0
  46. package/imports/Scene.js +79 -0
  47. package/imports/Shaders.js +165 -0
  48. package/imports/Shapes.js +129 -0
  49. package/imports/Storage.js +63 -0
  50. package/imports/Texture.js +67 -0
  51. package/imports/Time.js +28 -0
  52. package/imports/Transform.js +59 -0
  53. package/imports/components/BoxCollider.js +67 -0
  54. package/imports/components/BoxColliderDebug.js +38 -0
  55. package/imports/components/CircleCollider.js +67 -0
  56. package/imports/components/CircleColliderDebug.js +36 -0
  57. package/imports/components/Collider.js +51 -0
  58. package/imports/components/GameObject.js +160 -0
  59. package/imports/components/RigidBody.js +169 -0
  60. package/imports/lights/DirectionalLight.js +68 -0
  61. package/imports/lights/PointLight.js +17 -0
  62. package/imports/managers/AudioManager.js +146 -0
  63. package/imports/managers/CameraManager.js +60 -0
  64. package/imports/managers/EventManager.js +479 -0
  65. package/imports/managers/GLManager.js +65 -0
  66. package/imports/managers/IDManager.js +32 -0
  67. package/imports/managers/SceneManager.js +27 -0
  68. package/imports/managers/ShaderManager.js +133 -0
  69. package/imports/particlesystem/Particle.js +75 -0
  70. package/imports/particlesystem/ParticleSettings.js +49 -0
  71. package/imports/particlesystem/Particles.js +226 -0
  72. package/index.js +67 -0
  73. package/package.json +38 -0
@@ -0,0 +1,479 @@
1
+ import Scene from "../Scene.js";
2
+ import InstancedTexture from "../InstancedTexture.js";
3
+
4
+ /**
5
+ * @class EventManager
6
+ * @description Manages the events for the game
7
+ * @param {HTMLCanvasElement} canvas - The canvas element
8
+ * @param {Scene} scene - The scene
9
+ * @param {Camera} camera - The camera
10
+ */
11
+ class EventManager {
12
+ constructor(canvas, scene, camera) {
13
+ this.scene = scene;
14
+ this.camera = camera;
15
+ this.canvas = canvas;
16
+ this.keyDownListeners = new Map();
17
+ this.keyUpListeners = new Map();
18
+ this.clickListeners = new Map();
19
+ this.canvasWidth = canvas.width;
20
+ this.canvasHeight = canvas.height;
21
+ this.hoverListeners = new Map();
22
+ this.lastHoveredObject = null;
23
+ this.lastHoveredInstance = null;
24
+ this.pressedKeys = new Map();
25
+ this.mousePosition = { x: 0, y: 0 };
26
+ this.boundHandleMouseMove = this.handleMouseMove.bind(this);
27
+ this.boundHandleKeyDown = this.handleKeyDown.bind(this);
28
+ this.boundHandleKeyUp = this.handleKeyUp.bind(this);
29
+ this.boundHandleClick = this.handleClick.bind(this);
30
+
31
+ this.boundHandleMouseDown = this.handleMouseDown.bind(this);
32
+ this.boundHandleMouseUp = this.handleMouseUp.bind(this);
33
+
34
+ // Camera dragging state
35
+ this.isDragging = false;
36
+ this.dragStartX = 0;
37
+ this.dragStartY = 0;
38
+ this.initialCameraX = this.camera.transform.position.x;
39
+ this.initialCameraY = this.camera.transform.position.y;
40
+ this.cameraWasMoved = false;
41
+
42
+ window.addEventListener("mousemove", this.boundHandleMouseMove);
43
+ window.addEventListener("keydown", this.boundHandleKeyDown);
44
+ window.addEventListener("keyup", this.boundHandleKeyUp);
45
+ window.addEventListener("click", this.boundHandleClick);
46
+ window.addEventListener("mousedown", this.boundHandleMouseDown);
47
+ window.addEventListener("mouseup", this.boundHandleMouseUp);
48
+ }
49
+
50
+ /**
51
+ * @method addKeyDown
52
+ * @description Adds a key down event listener
53
+ * @param {string} key - The key to listen for
54
+ * @param {function} func - The function to call when the key is pressed
55
+ */
56
+ addKeyDown(key, func) {
57
+ if (!this.keyDownListeners.has(key.length <= 1 ? key.toLowerCase() : key)) {
58
+ this.keyDownListeners.set(
59
+ key.length <= 1 ? key.toLowerCase() : key,
60
+ new Set()
61
+ );
62
+ }
63
+ this.keyDownListeners
64
+ .get(key.length <= 1 ? key.toLowerCase() : key)
65
+ .add(func);
66
+ }
67
+
68
+ /**
69
+ * @method addKeyUp
70
+ * @description Adds a key up event listener
71
+ * @param {string} key - The key to listen for
72
+ * @param {function} func - The function to call when the key is released
73
+ */
74
+ addKeyUp(key, func) {
75
+ if (!this.keyUpListeners.has(key.length <= 1 ? key.toLowerCase() : key)) {
76
+ this.keyUpListeners.set(
77
+ key.length <= 1 ? key.toLowerCase() : key,
78
+ new Set()
79
+ );
80
+ }
81
+ this.keyUpListeners
82
+ .get(key.length <= 1 ? key.toLowerCase() : key)
83
+ .add(func);
84
+ }
85
+
86
+ /**
87
+ * @method removeKeyDown
88
+ * @description Removes a key down event listener
89
+ * @param {string} key - The key to remove the listener for
90
+ * @param {function} func - The function to remove
91
+ */
92
+ removeKeyDown(key, func) {
93
+ if (this.keyDownListeners.has(key.length <= 1 ? key.toLowerCase() : key)) {
94
+ this.keyDownListeners
95
+ .get(key.length <= 1 ? key.toLowerCase() : key)
96
+ .delete(func);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * @method removeKeyUp
102
+ * @description Removes a key up event listener
103
+ * @param {string} key - The key to remove the listener for
104
+ * @param {function} func - The function to remove
105
+ */
106
+ removeKeyUp(key, func) {
107
+ if (this.keyUpListeners.has(key.length <= 1 ? key.toLowerCase() : key)) {
108
+ this.keyUpListeners
109
+ .get(key.length <= 1 ? key.toLowerCase() : key)
110
+ .delete(func);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * @method handleKeyDown
116
+ * @description Handles a key down event
117
+ * @param {KeyboardEvent} event - The keyboard event
118
+ */
119
+ handleKeyDown(event) {
120
+ this.pressedKeys.set(
121
+ event.key.length <= 1 ? event.key.toLowerCase() : event.key,
122
+ true
123
+ );
124
+ const listeners = this.keyDownListeners.get(
125
+ event.key.length <= 1 ? event.key.toLowerCase() : event.key
126
+ );
127
+ if (listeners) {
128
+ listeners.forEach((func) => func(event));
129
+ }
130
+ }
131
+
132
+ /**
133
+ * @method handleKeyUp
134
+ * @description Handles a key up event
135
+ * @param {KeyboardEvent} event - The keyboard event
136
+ */
137
+ handleKeyUp(event) {
138
+ this.pressedKeys.set(
139
+ event.key.length <= 1 ? event.key.toLowerCase() : event.key,
140
+ false
141
+ );
142
+ const listeners = this.keyUpListeners.get(
143
+ event.key.length <= 1 ? event.key.toLowerCase() : event.key
144
+ );
145
+ if (listeners) {
146
+ listeners.forEach((func) => func(event));
147
+ }
148
+ }
149
+
150
+ /**
151
+ * @method isKeyPressed
152
+ * @description Checks if a key is pressed
153
+ * @param {string} key - The key to check
154
+ * @returns {boolean} - True if the key is pressed
155
+ */
156
+ isKeyPressed(key) {
157
+ return (
158
+ this.pressedKeys.get(key.length <= 1 ? key.toLowerCase() : key) || false
159
+ );
160
+ }
161
+
162
+ /**
163
+ * @method addClickEvent
164
+ * @description Adds a click event listener
165
+ * @param {GameObject} object - The object to listen for
166
+ * @param {function} func - The function to call when the object is clicked
167
+ */
168
+ addClickEvent(object, func) {
169
+ if (!this.clickListeners.has(object.id)) {
170
+ this.clickListeners.set(object.id, new Set());
171
+ }
172
+ this.clickListeners.get(object.id).add(func);
173
+ }
174
+
175
+ /**
176
+ * @method handleClick
177
+ * @description Handles a click event
178
+ * @param {MouseEvent} event - The mouse event
179
+ */
180
+ handleClick(event) {
181
+ const canvas = event.target;
182
+ const rect = canvas.getBoundingClientRect();
183
+
184
+ // Calculate click position relative to the canvas
185
+ const canvasX = event.clientX - rect.left;
186
+ const canvasY = event.clientY - rect.top;
187
+
188
+ // Convert to world coordinates
189
+ const worldX =
190
+ canvasX - this.canvasWidth / 2 - this.camera.transform.position.x;
191
+ const worldY =
192
+ this.canvasHeight / 2 - canvasY - this.camera.transform.position.y;
193
+
194
+ this.scene.objects.forEach((sceneObject) => {
195
+ if (!sceneObject.isActive) return; // Skip inactive objects
196
+ // Check if the object has an InstancedTexture component
197
+ let instanceHandled = false;
198
+ if (
199
+ sceneObject.getComponent &&
200
+ sceneObject.getComponent(InstancedTexture)
201
+ ) {
202
+ const instancedTexture = sceneObject.getComponent(InstancedTexture);
203
+ instanceHandled = instancedTexture.handleInstanceClick(
204
+ event,
205
+ worldX,
206
+ worldY
207
+ );
208
+ }
209
+
210
+ // If no instance handled the click, check the object itself
211
+ if (
212
+ !instanceHandled &&
213
+ this.isPointInObject(worldX, worldY, sceneObject)
214
+ ) {
215
+ const listeners = this.clickListeners.get(sceneObject.id);
216
+ if (listeners) {
217
+ listeners.forEach((func) => func(event, sceneObject));
218
+ }
219
+ }
220
+
221
+ });
222
+ }
223
+
224
+ /**
225
+ * @method removeClickEvent
226
+ * @description Removes a click event listener
227
+ * @param {GameObject} object - The object to remove the listener for
228
+ * @param {function} func - The function to remove
229
+ */
230
+ removeClickEvent(object, func) {
231
+ if (this.clickListeners.has(object.id)) {
232
+ this.clickListeners.get(object.id).delete(func);
233
+ }
234
+ }
235
+
236
+ /**
237
+ * @method isPointInObject
238
+ * @description Checks if a point is in an object
239
+ * @param {number} x - The x coordinate of the point
240
+ * @param {number} y - The y coordinate of the point
241
+ * @param {GameObject} object - The object to check
242
+ * @returns {boolean} - True if the point is in the object
243
+ */
244
+ isPointInObject(x, y, object) {
245
+ const left = object.transform.position.x - object.transform.scale.x;
246
+ const right = object.transform.position.x + object.transform.scale.x;
247
+ const top = object.transform.position.y + object.transform.scale.y;
248
+ const bottom = object.transform.position.y - object.transform.scale.y;
249
+ return x >= left && x <= right && y >= bottom && y <= top;
250
+ }
251
+
252
+ /**
253
+ * @method addHoverEvent
254
+ * @description Adds a hover event listener
255
+ * @param {GameObject} object - The object to listen for
256
+ * @param {function} enterFunc - The function to call when the object is hovered
257
+ * @param {function} leaveFunc - The function to call when the object is no longer hovered
258
+ */
259
+ addHoverEvent(object, enterFunc, leaveFunc) {
260
+ if (!this.hoverListeners.has(object.id)) {
261
+ this.hoverListeners.set(object.id, {
262
+ enter: new Set(),
263
+ leave: new Set(),
264
+ });
265
+ }
266
+ this.hoverListeners.get(object.id).enter.add(enterFunc);
267
+ this.hoverListeners.get(object.id).leave.add(leaveFunc);
268
+ }
269
+
270
+ /**
271
+ * @method removeHoverEvent
272
+ * @description Removes a hover event listener
273
+ * @param {GameObject} object - The object to remove the listener for
274
+ * @param {function} enterFunc - The function to remove
275
+ * @param {function} leaveFunc - The function to remove
276
+ */
277
+ removeHoverEvent(object, enterFunc, leaveFunc) {
278
+ if (this.hoverListeners.has(object.id)) {
279
+ const listeners = this.hoverListeners.get(object.id);
280
+ listeners.enter.delete(enterFunc);
281
+ listeners.leave.delete(leaveFunc);
282
+ }
283
+ }
284
+
285
+ /**
286
+ * @method handleMouseDown
287
+ * @description Handles a mouse down event
288
+ * @param {MouseEvent} event - The mouse event
289
+ */
290
+ handleMouseDown(event) {
291
+ if (event.button === 1) {
292
+ event.preventDefault();
293
+ this.isDragging = true;
294
+ this.dragStartX = event.clientX;
295
+ this.dragStartY = event.clientY;
296
+ this.initialCameraX = this.camera.transform.position.x;
297
+ this.initialCameraY = this.camera.transform.position.y;
298
+ this.canvas.style.cursor = "grabbing";
299
+ }
300
+ }
301
+
302
+ /**
303
+ * @method handleMouseUp
304
+ * @description Handles a mouse up event
305
+ * @param {MouseEvent} event - The mouse event
306
+ */
307
+ handleMouseUp(event) {
308
+ if (event.button === 1 && this.isDragging) {
309
+ this.isDragging = false;
310
+ this.canvas.style.cursor = "default";
311
+ this.cameraWasMoved = true;
312
+ }
313
+ }
314
+
315
+ /**
316
+ * @method handleMouseMove
317
+ * @description Handles a mouse move event
318
+ * @param {MouseEvent} event - The mouse event
319
+ */
320
+ handleMouseMove(event) {
321
+ const rect = this.canvas.getBoundingClientRect();
322
+
323
+ // Calculate mouse position relative to the canvas
324
+ const canvasX = event.clientX - rect.left;
325
+ const canvasY = event.clientY - rect.top;
326
+
327
+ // Convert to world coordinates
328
+ const worldX =
329
+ canvasX - this.canvasWidth / 2 - this.camera.transform.position.x;
330
+ const worldY =
331
+ this.canvasHeight / 2 - canvasY - this.camera.transform.position.y;
332
+ this.mousePosition.x = worldX;
333
+ this.mousePosition.y = worldY;
334
+ let hoveredObject = null;
335
+ let hoveredInstance = null;
336
+
337
+ this.scene.objects.forEach((sceneObject) => {
338
+ if (!sceneObject.isActive) return; // Skip inactive objects
339
+
340
+ // Check if the object has an InstancedTexture component
341
+ if (
342
+ sceneObject.getComponent &&
343
+ sceneObject.getComponent(InstancedTexture)
344
+ ) {
345
+ const instancedTexture = sceneObject.getComponent(InstancedTexture);
346
+ const instanceAtPoint = instancedTexture.getInstanceAtPoint(
347
+ worldX,
348
+ worldY
349
+ );
350
+ if (instanceAtPoint) {
351
+ hoveredInstance = instanceAtPoint;
352
+ hoveredObject = sceneObject; // Also set the parent object as hovered
353
+ }
354
+ }
355
+
356
+ // If no instance was hovered, check the object itself
357
+ if (
358
+ !hoveredInstance &&
359
+ this.isPointInObject(worldX, worldY, sceneObject)
360
+ ) {
361
+ hoveredObject = sceneObject;
362
+ }
363
+ });
364
+
365
+ // Handle instance hover events
366
+ if (hoveredInstance !== this.lastHoveredInstance) {
367
+ if (this.lastHoveredInstance) {
368
+ const parent = this.lastHoveredInstance.parent;
369
+ if (parent && parent instanceof InstancedTexture) {
370
+ parent.handleInstanceHover(
371
+ event,
372
+ worldX,
373
+ worldY,
374
+ this.lastHoveredInstance
375
+ );
376
+ }
377
+ }
378
+
379
+ if (hoveredInstance) {
380
+ const parent = hoveredInstance.parent;
381
+ if (parent && parent instanceof InstancedTexture) {
382
+ parent.handleInstanceHover(
383
+ event,
384
+ worldX,
385
+ worldY,
386
+ this.lastHoveredInstance
387
+ );
388
+ }
389
+ }
390
+
391
+ this.lastHoveredInstance = hoveredInstance;
392
+ }
393
+
394
+ // Handle object hover events
395
+ if (hoveredObject !== this.lastHoveredObject) {
396
+ // Always trigger leave event if we had a previously hovered object
397
+ if (this.lastHoveredObject && this.lastHoveredObject.isActive) {
398
+ const leaveListeners = this.hoverListeners.get(
399
+ this.lastHoveredObject.id
400
+ );
401
+ if (leaveListeners) {
402
+ leaveListeners.leave.forEach((func) =>
403
+ func(event, this.lastHoveredObject)
404
+ );
405
+ }
406
+ }
407
+
408
+ // Only trigger enter event if we're not hovering over an instance
409
+ if (hoveredObject && hoveredObject.isActive && !hoveredInstance) {
410
+ const enterListeners = this.hoverListeners.get(hoveredObject.id);
411
+ if (enterListeners) {
412
+ enterListeners.enter.forEach((func) => func(event, hoveredObject));
413
+ }
414
+ }
415
+
416
+ this.lastHoveredObject = hoveredObject;
417
+ }
418
+ }
419
+
420
+ /**
421
+ * @method getMousePosition
422
+ * @description Returns the mouse position
423
+ * @returns {Object} - The mouse position
424
+ */
425
+ getMousePosition() {
426
+ return this.mousePosition;
427
+ }
428
+
429
+ /**
430
+ * @method wasCameraMoved
431
+ * @description Checks if the camera was moved
432
+ * @returns {boolean} - True if the camera was moved
433
+ */
434
+ wasCameraMoved() {
435
+ return this.cameraWasMoved;
436
+ }
437
+
438
+ /**
439
+ * @method resetCameraMoved
440
+ * @description Resets the camera moved flag
441
+ */
442
+ resetCameraMoved() {
443
+ this.cameraWasMoved = false;
444
+ }
445
+
446
+ /**
447
+ * @method changeScene
448
+ * @description Changes the scene
449
+ * @param {Scene} scene - The scene to change to
450
+ */
451
+ changeScene(scene) {
452
+ if (scene instanceof Scene) {
453
+ this.scene = scene;
454
+ } else {
455
+ console.error(
456
+ "[EventManager] > Specified argument is not an instance of Scene class"
457
+ );
458
+ }
459
+ }
460
+
461
+ /**
462
+ * @method clean
463
+ * @description Cleans up the event manager
464
+ */
465
+ clean() {
466
+ window.removeEventListener("mousemove", this.boundHandleMouseMove);
467
+ window.removeEventListener("keydown", this.boundHandleKeyDown);
468
+ window.removeEventListener("keyup", this.boundHandleKeyUp);
469
+ window.removeEventListener("click", this.boundHandleClick);
470
+ window.removeEventListener("mousedown", this.boundHandleMouseDown);
471
+ window.removeEventListener("mouseup", this.boundHandleMouseUp);
472
+ this.pressedKeys.clear();
473
+ this.keyDownListeners.clear();
474
+ this.lastHoveredObject = null;
475
+ this.lastHoveredInstance = null;
476
+ }
477
+ }
478
+
479
+ export default EventManager;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * @class GLManager
3
+ * @description Manages the WebGL context for the game
4
+ */
5
+ class GLManager {
6
+ static gl = null;
7
+ static programInfo = null;
8
+ static canvas = null;
9
+
10
+ /**
11
+ * @method setGL
12
+ * @description Sets the WebGL context
13
+ * @param {WebGLRenderingContext} gl - The WebGL context
14
+ */
15
+ static setGL(gl) {
16
+ this.gl = gl;
17
+ }
18
+
19
+ /**
20
+ * @method setProgramInfo
21
+ * @description Sets the program info
22
+ * @param {Object} programInfo - The program info
23
+ */
24
+ static setProgramInfo(programInfo) {
25
+ this.programInfo = programInfo;
26
+ }
27
+
28
+ /**
29
+ * @method setCanvas
30
+ * @description Sets the canvas
31
+ * @param {HTMLCanvasElement} canvas - The canvas
32
+ */
33
+ static setCanvas(canvas) {
34
+ this.canvas = canvas;
35
+ }
36
+
37
+ /**
38
+ * @method getGL
39
+ * @description Returns the WebGL context
40
+ * @returns {WebGLRenderingContext} - The WebGL context
41
+ */
42
+ static getGL() {
43
+ return this.gl;
44
+ }
45
+
46
+ /**
47
+ * @method getProgramInfo
48
+ * @description Returns the program info
49
+ * @returns {Object} - The program info
50
+ */
51
+ static getProgramInfo() {
52
+ return this.programInfo;
53
+ }
54
+
55
+ /**
56
+ * @method getCanvas
57
+ * @description Returns the canvas
58
+ * @returns {HTMLCanvasElement} - The canvas
59
+ */
60
+ static getCanvas() {
61
+ return this.canvas;
62
+ }
63
+ }
64
+
65
+ export default GLManager;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @class IDManager
3
+ * @description Manages the IDs for the game
4
+ */
5
+ class IDManager {
6
+ static existingIDs = new Set();
7
+
8
+ /**
9
+ * @method generateID
10
+ * @description Generates a random ID
11
+ * @returns {string} - The random ID
12
+ */
13
+ static generateID() {
14
+ return Math.random().toString(36).substring(2, 10);
15
+ }
16
+
17
+ /**
18
+ * @method generateUniqueID
19
+ * @description Generates a unique ID
20
+ * @returns {string} - The unique ID
21
+ */
22
+ static generateUniqueID() {
23
+ let id;
24
+ do {
25
+ id = this.generateID();
26
+ } while (this.existingIDs.has(id));
27
+ this.existingIDs.add(id);
28
+ return id;
29
+ }
30
+ }
31
+
32
+ export default IDManager;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @class SceneManager
3
+ * @description Manages the scene for the game
4
+ */
5
+ class SceneManager {
6
+ static scene = null;
7
+
8
+ /**
9
+ * @method setScene
10
+ * @description Sets the scene
11
+ * @param {Scene} scene - The scene to set
12
+ */
13
+ static setScene(scene) {
14
+ this.scene = scene;
15
+ }
16
+
17
+ /**
18
+ * @method getScene
19
+ * @description Returns the scene
20
+ * @returns {Scene} - The scene
21
+ */
22
+ static getScene() {
23
+ return this.scene;
24
+ }
25
+ }
26
+
27
+ export default SceneManager;