emeraldengine 2.2.0 → 3.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 (162) hide show
  1. package/README.md +2359 -968
  2. package/dist/types/index.d.ts +72 -32
  3. package/dist/types/src/Animator.d.ts +50 -0
  4. package/dist/types/{BitmapText.d.ts → src/BitmapText.d.ts} +19 -21
  5. package/dist/types/src/Camera.d.ts +122 -0
  6. package/dist/types/src/CameraController.d.ts +107 -0
  7. package/dist/types/src/CanvasText.d.ts +91 -0
  8. package/dist/types/src/CollisionLayers.d.ts +58 -0
  9. package/dist/types/{Color.d.ts → src/Color.d.ts} +5 -6
  10. package/dist/types/src/Coroutine.d.ts +111 -0
  11. package/dist/types/src/DebugOverlay.d.ts +86 -0
  12. package/dist/types/src/Drawable.d.ts +271 -0
  13. package/dist/types/src/Easing.d.ts +22 -0
  14. package/dist/types/src/Emerald.d.ts +420 -0
  15. package/dist/types/src/EmeraldDB.d.ts +159 -0
  16. package/dist/types/{FPSCounter.d.ts → src/FPSCounter.d.ts} +1 -3
  17. package/dist/types/src/GLUtils.d.ts +4 -0
  18. package/dist/types/{Instance.d.ts → src/Instance.d.ts} +37 -15
  19. package/dist/types/{InstancedTexture.d.ts → src/InstancedTexture.d.ts} +60 -23
  20. package/dist/types/src/Interpolator.d.ts +66 -0
  21. package/dist/types/src/Material.d.ts +87 -0
  22. package/dist/types/src/MathUtils.d.ts +80 -0
  23. package/dist/types/src/ParticleEmitter.d.ts +131 -0
  24. package/dist/types/{Physics.d.ts → src/Physics.d.ts} +88 -20
  25. package/dist/types/src/Pool.d.ts +53 -0
  26. package/dist/types/src/PostEffects.d.ts +68 -0
  27. package/dist/types/src/PostProcessor.d.ts +124 -0
  28. package/dist/types/src/RenderTarget.d.ts +56 -0
  29. package/dist/types/src/Scene.d.ts +62 -0
  30. package/dist/types/src/ScreenEffects.d.ts +111 -0
  31. package/dist/types/src/Serializer.d.ts +86 -0
  32. package/dist/types/src/Shaders.d.ts +2 -0
  33. package/dist/types/{Shapes.d.ts → src/Shapes.d.ts} +4 -6
  34. package/dist/types/src/SpatialGrid.d.ts +50 -0
  35. package/dist/types/src/SpriteBatch.d.ts +89 -0
  36. package/dist/types/src/StateMachine.d.ts +59 -0
  37. package/dist/types/src/Storage.d.ts +89 -0
  38. package/dist/types/{Texture.d.ts → src/Texture.d.ts} +3 -4
  39. package/dist/types/src/TextureAtlas.d.ts +55 -0
  40. package/dist/types/src/Tilemap.d.ts +91 -0
  41. package/dist/types/src/Time.d.ts +53 -0
  42. package/dist/types/src/Timer.d.ts +54 -0
  43. package/dist/types/src/Transform.d.ts +94 -0
  44. package/dist/types/src/Tween.d.ts +81 -0
  45. package/dist/types/src/UI.d.ts +121 -0
  46. package/dist/types/src/components/Behaviour.d.ts +71 -0
  47. package/dist/types/{components → src/components}/BoxCollider.d.ts +14 -14
  48. package/dist/types/src/components/BoxColliderDebug.d.ts +15 -0
  49. package/dist/types/{components → src/components}/CircleCollider.d.ts +14 -12
  50. package/dist/types/src/components/CircleColliderDebug.d.ts +15 -0
  51. package/dist/types/src/components/Collider.d.ts +96 -0
  52. package/dist/types/src/components/GameObject.d.ts +135 -0
  53. package/dist/types/src/components/RigidBody.d.ts +183 -0
  54. package/dist/types/src/importers/Aseprite.d.ts +79 -0
  55. package/dist/types/src/importers/TiledMap.d.ts +62 -0
  56. package/dist/types/{lights → src/lights}/DirectionalLight.d.ts +7 -9
  57. package/dist/types/{lights → src/lights}/PointLight.d.ts +6 -9
  58. package/dist/types/src/managers/AssetManager.d.ts +116 -0
  59. package/dist/types/src/managers/AudioManager.d.ts +259 -0
  60. package/dist/types/{managers → src/managers}/CameraManager.d.ts +8 -8
  61. package/dist/types/{managers → src/managers}/EventManager.d.ts +46 -32
  62. package/dist/types/src/managers/GLManager.d.ts +84 -0
  63. package/dist/types/src/managers/GLState.d.ts +37 -0
  64. package/dist/types/src/managers/IDManager.d.ts +31 -0
  65. package/dist/types/src/managers/InputManager.d.ts +290 -0
  66. package/dist/types/src/managers/NetworkManager.d.ts +93 -0
  67. package/dist/types/src/managers/RenderStats.d.ts +34 -0
  68. package/dist/types/src/managers/SceneManager.d.ts +44 -0
  69. package/dist/types/src/managers/ShaderManager.d.ts +55 -0
  70. package/dist/types/src/managers/TextureManager.d.ts +102 -0
  71. package/dist/types/src/particlesystem/Particle.d.ts +64 -0
  72. package/dist/types/{particlesystem → src/particlesystem}/ParticleSettings.d.ts +32 -24
  73. package/dist/types/{particlesystem → src/particlesystem}/Particles.d.ts +20 -12
  74. package/index.js +72 -0
  75. package/package.json +74 -60
  76. package/src/Animator.js +95 -0
  77. package/src/BitmapText.js +6 -5
  78. package/src/Camera.js +183 -0
  79. package/src/CameraController.js +192 -0
  80. package/src/CanvasText.js +281 -0
  81. package/src/CollisionLayers.js +86 -0
  82. package/src/Color.js +18 -18
  83. package/src/Coroutine.js +259 -0
  84. package/src/DebugOverlay.js +246 -0
  85. package/src/Drawable.js +842 -555
  86. package/src/Easing.js +57 -0
  87. package/src/Emerald.js +1150 -459
  88. package/src/EmeraldDB.js +328 -0
  89. package/src/FPSCounter.js +43 -43
  90. package/src/GLUtils.js +60 -67
  91. package/src/Instance.js +41 -5
  92. package/src/InstancedTexture.js +251 -118
  93. package/src/Interpolator.js +124 -0
  94. package/src/Material.js +202 -0
  95. package/src/MathUtils.js +133 -0
  96. package/src/ParticleEmitter.js +284 -0
  97. package/src/Physics.js +186 -5
  98. package/src/Pool.js +85 -0
  99. package/src/PostEffects.js +296 -0
  100. package/src/PostProcessor.js +304 -0
  101. package/src/RenderTarget.js +134 -0
  102. package/src/Scene.js +115 -83
  103. package/src/ScreenEffects.js +266 -0
  104. package/src/Serializer.js +131 -0
  105. package/src/Shaders.js +150 -165
  106. package/src/Shapes.js +118 -129
  107. package/src/SpatialGrid.js +111 -0
  108. package/src/SpriteBatch.js +299 -0
  109. package/src/StateMachine.js +82 -0
  110. package/src/Storage.js +175 -47
  111. package/src/Texture.js +58 -67
  112. package/src/TextureAtlas.js +96 -0
  113. package/src/Tilemap.js +274 -0
  114. package/src/Time.js +51 -6
  115. package/src/Timer.js +99 -0
  116. package/src/Transform.js +100 -7
  117. package/src/Tween.js +160 -0
  118. package/src/UI.js +394 -0
  119. package/src/components/Behaviour.js +90 -0
  120. package/src/components/BoxCollider.js +22 -3
  121. package/src/components/CircleCollider.js +19 -3
  122. package/src/components/CircleColliderDebug.js +24 -24
  123. package/src/components/Collider.js +140 -34
  124. package/src/components/GameObject.js +130 -21
  125. package/src/components/RigidBody.js +123 -2
  126. package/src/importers/Aseprite.js +142 -0
  127. package/src/importers/TiledMap.js +158 -0
  128. package/src/lights/DirectionalLight.js +6 -15
  129. package/src/lights/PointLight.js +4 -4
  130. package/src/managers/AssetManager.js +239 -0
  131. package/src/managers/AudioManager.js +565 -146
  132. package/src/managers/EventManager.js +488 -477
  133. package/src/managers/GLManager.js +57 -0
  134. package/src/managers/GLState.js +70 -0
  135. package/src/managers/IDManager.js +24 -2
  136. package/src/managers/InputManager.js +779 -0
  137. package/src/managers/NetworkManager.js +178 -0
  138. package/src/managers/RenderStats.js +34 -0
  139. package/src/managers/SceneManager.js +30 -0
  140. package/src/managers/ShaderManager.js +0 -2
  141. package/src/managers/TextureManager.js +218 -0
  142. package/src/particlesystem/Particle.js +82 -7
  143. package/src/particlesystem/ParticleSettings.js +21 -3
  144. package/src/particlesystem/Particles.js +80 -31
  145. package/dist/types/Drawable.d.ts +0 -157
  146. package/dist/types/Emerald.d.ts +0 -73
  147. package/dist/types/GLUtils.d.ts +0 -6
  148. package/dist/types/Scene.d.ts +0 -39
  149. package/dist/types/Shaders.d.ts +0 -4
  150. package/dist/types/Storage.d.ts +0 -46
  151. package/dist/types/Time.d.ts +0 -22
  152. package/dist/types/Transform.d.ts +0 -41
  153. package/dist/types/components/BoxColliderDebug.d.ts +0 -19
  154. package/dist/types/components/CircleColliderDebug.d.ts +0 -19
  155. package/dist/types/components/Collider.d.ts +0 -53
  156. package/dist/types/components/GameObject.d.ts +0 -72
  157. package/dist/types/components/RigidBody.d.ts +0 -104
  158. package/dist/types/managers/AudioManager.d.ts +0 -60
  159. package/dist/types/managers/GLManager.d.ts +0 -47
  160. package/dist/types/managers/IDManager.d.ts +0 -21
  161. package/dist/types/managers/SceneManager.d.ts +0 -22
  162. package/dist/types/particlesystem/Particle.d.ts +0 -42
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @class StateMachine
3
+ * @description A lightweight finite state machine for entity AI, animation
4
+ * states, game flow, etc. Each state can define `enter`, `update(dt)`, and
5
+ * `exit` handlers. Drive it from a Behaviour's update().
6
+ *
7
+ * @example
8
+ * const fsm = new StateMachine();
9
+ * fsm.add("idle", {
10
+ * update: (dt, sm) => { if (seesPlayer) sm.set("chase"); },
11
+ * });
12
+ * fsm.add("chase", {
13
+ * enter: () => playRoarSound(),
14
+ * update: (dt, sm) => moveTowardPlayer(dt),
15
+ * });
16
+ * fsm.set("idle");
17
+ * // in update(dt): fsm.update(dt);
18
+ */
19
+ class StateMachine {
20
+ constructor() {
21
+ this.states = new Map();
22
+ this.current = null;
23
+ this.currentName = null;
24
+ this.previousName = null;
25
+ }
26
+
27
+ /**
28
+ * @method add
29
+ * @description Registers a state.
30
+ * @param {string} name - State name
31
+ * @param {{enter?:Function, update?:Function, exit?:Function}} handlers
32
+ * @returns {StateMachine} - this
33
+ */
34
+ add(name, handlers) {
35
+ this.states.set(name, handlers || {});
36
+ return this;
37
+ }
38
+
39
+ /**
40
+ * @method set
41
+ * @description Transitions to a state, running exit/enter handlers. Re-entering
42
+ * the same state is a no-op unless `force` is true.
43
+ * @param {string} name - Target state name
44
+ * @param {boolean} [force] - Allow re-entering the current state
45
+ * @returns {StateMachine} - this
46
+ */
47
+ set(name, force = false) {
48
+ if (this.currentName === name && !force) return this;
49
+ if (!this.states.has(name)) {
50
+ console.warn(`[StateMachine] > Unknown state "${name}"`);
51
+ return this;
52
+ }
53
+
54
+ if (this.current && this.current.exit) this.current.exit(this);
55
+ this.previousName = this.currentName;
56
+ this.currentName = name;
57
+ this.current = this.states.get(name);
58
+ if (this.current.enter) this.current.enter(this);
59
+ return this;
60
+ }
61
+
62
+ /**
63
+ * @method update
64
+ * @description Runs the current state's update handler.
65
+ * @param {number} dt - Seconds since the last frame
66
+ */
67
+ update(dt) {
68
+ if (this.current && this.current.update) this.current.update(dt, this);
69
+ }
70
+
71
+ /**
72
+ * @method is
73
+ * @description Whether the given state is current.
74
+ * @param {string} name
75
+ * @returns {boolean}
76
+ */
77
+ is(name) {
78
+ return this.currentName === name;
79
+ }
80
+ }
81
+
82
+ export default StateMachine;
package/src/Storage.js CHANGED
@@ -3,61 +3,189 @@
3
3
  * @description Manages the storage of the game
4
4
  */
5
5
  class Storage {
6
- /**
7
- * @method writeToLocalStorage
8
- * @description Writes to local storage
9
- * @param {string} key - The key to write to
10
- * @param {any} value - The value to write to
11
- */
12
- static writeToLocalStorage(key, value) {
13
- localStorage.setItem(key, JSON.stringify(value));
14
- }
6
+ /**
7
+ * @method writeToLocalStorage
8
+ * @description Writes to local storage
9
+ * @param {string} key - The key to write to
10
+ * @param {any} value - The value to write to
11
+ */
12
+ static writeToLocalStorage(key, value) {
13
+ localStorage.setItem(key, JSON.stringify(value));
14
+ }
15
15
 
16
- /**
17
- * @method readFromLocalStorage
18
- * @description Reads from local storage
19
- * @param {string} key - The key to read from
20
- * @returns {any} - The value read from local storage
21
- */
22
- static readFromLocalStorage(key) {
23
- return JSON.parse(localStorage.getItem(key));
24
- }
16
+ /**
17
+ * @method readFromLocalStorage
18
+ * @description Reads from local storage
19
+ * @param {string} key - The key to read from
20
+ * @returns {any} - The value read from local storage
21
+ */
22
+ static readFromLocalStorage(key) {
23
+ return JSON.parse(localStorage.getItem(key));
24
+ }
25
+
26
+ /**
27
+ * @method clearLocalStorage
28
+ * @description Clears local storage
29
+ */
30
+ static clearLocalStorage() {
31
+ localStorage.clear();
32
+ }
33
+
34
+ /**
35
+ * @method writeToSessionStorage
36
+ * @description Writes to session storage
37
+ * @param {string} key - The key to write to
38
+ * @param {any} value - The value to write to
39
+ */
40
+ static writeToSessionStorage(key, value) {
41
+ sessionStorage.setItem(key, JSON.stringify(value));
42
+ }
43
+
44
+ /**
45
+ * @method readFromSessionStorage
46
+ * @description Reads from session storage
47
+ * @param {string} key - The key to read from
48
+ * @returns {any} - The value read from session storage
49
+ */
50
+ static readFromSessionStorage(key) {
51
+ return JSON.parse(sessionStorage.getItem(key));
52
+ }
25
53
 
26
- /**
27
- * @method clearLocalStorage
28
- * @description Clears local storage
29
- */
30
- static clearLocalStorage() {
31
- localStorage.clear();
54
+ /**
55
+ * @method clearSessionStorage
56
+ * @description Clears session storage
57
+ */
58
+ static clearSessionStorage() {
59
+ sessionStorage.clear();
60
+ }
61
+
62
+ /**
63
+ * @method save
64
+ * @description Writes a versioned save under `key`. The payload is wrapped in
65
+ * an envelope `{ v, t, data }` so it can be migrated later, and the previous
66
+ * value is mirrored to `key + ".bak"` for corruption recovery. Quota and
67
+ * serialization errors are caught and reported rather than thrown.
68
+ * @param {string} key - The storage key
69
+ * @param {any} data - The data to persist (must be JSON-serializable)
70
+ * @param {Object} [options] - { version = 1, backup = true }
71
+ * @returns {boolean} - Whether the write succeeded
72
+ */
73
+ static save(key, data, options = {}) {
74
+ const version = options.version ?? 1;
75
+ let serialized;
76
+ try {
77
+ serialized = JSON.stringify({ v: version, t: Date.now(), data });
78
+ } catch (e) {
79
+ console.warn(`[Storage] Could not serialize save "${key}":`, e);
80
+ return false;
81
+ }
82
+ try {
83
+ if (options.backup !== false) {
84
+ const prev = localStorage.getItem(key);
85
+ if (prev != null) {
86
+ try {
87
+ localStorage.setItem(key + ".bak", prev);
88
+ } catch (_) {}
89
+ }
90
+ }
91
+ localStorage.setItem(key, serialized);
92
+ return true;
93
+ } catch (e) {
94
+ console.warn(`[Storage] Failed to save "${key}" (quota exceeded?):`, e);
95
+ return false;
32
96
  }
97
+ }
33
98
 
34
- /**
35
- * @method writeToSessionStorage
36
- * @description Writes to session storage
37
- * @param {string} key - The key to write to
38
- * @param {any} value - The value to write to
39
- */
40
- static writeToSessionStorage(key, value) {
41
- sessionStorage.setItem(key, JSON.stringify(value));
99
+ /**
100
+ * @method _unwrap
101
+ * @description Parses a stored string into a `{ v, data }` envelope, treating
102
+ * a plain (pre-versioning) value as version 0. Returns undefined for missing
103
+ * data and throws for malformed JSON.
104
+ * @private
105
+ */
106
+ static _unwrap(raw) {
107
+ if (raw == null) return undefined;
108
+ const parsed = JSON.parse(raw);
109
+ if (
110
+ parsed &&
111
+ typeof parsed === "object" &&
112
+ "v" in parsed &&
113
+ "data" in parsed
114
+ ) {
115
+ return parsed;
42
116
  }
117
+ return { v: 0, data: parsed };
118
+ }
119
+
120
+ /**
121
+ * @method load
122
+ * @description Reads a versioned save written by `save`. If the primary value
123
+ * is corrupt it falls back to the `.bak` copy; if that fails too it returns
124
+ * `fallback`. When the stored version differs from `version` and a `migrate`
125
+ * function is given, the data is upgraded (and rewritten unless disabled).
126
+ * @param {string} key - The storage key
127
+ * @param {Object} [options] - { version = 1, fallback = null, migrate, rewrite = true }
128
+ * @returns {any} - The (possibly migrated) saved data, or `fallback`
129
+ */
130
+ static load(key, options = {}) {
131
+ const version = options.version ?? 1;
132
+ const fallback = options.fallback ?? null;
133
+ const migrate = options.migrate || null;
43
134
 
44
- /**
45
- * @method readFromSessionStorage
46
- * @description Reads from session storage
47
- * @param {string} key - The key to read from
48
- * @returns {any} - The value read from session storage
49
- */
50
- static readFromSessionStorage(key) {
51
- return JSON.parse(sessionStorage.getItem(key));
135
+ let env;
136
+ try {
137
+ env = Storage._unwrap(localStorage.getItem(key));
138
+ } catch (e) {
139
+ try {
140
+ env = Storage._unwrap(localStorage.getItem(key + ".bak"));
141
+ if (env !== undefined) {
142
+ console.warn(
143
+ `[Storage] "${key}" was corrupt; recovered from backup.`
144
+ );
145
+ }
146
+ } catch (_) {
147
+ env = undefined;
148
+ }
52
149
  }
150
+ if (env === undefined) return fallback;
53
151
 
54
- /**
55
- * @method clearSessionStorage
56
- * @description Clears session storage
57
- */
58
- static clearSessionStorage() {
59
- sessionStorage.clear();
152
+ let data = env.data;
153
+ if (env.v !== version && migrate) {
154
+ try {
155
+ data = migrate(data, env.v, version);
156
+ } catch (e) {
157
+ console.warn(`[Storage] Migration failed for "${key}":`, e);
158
+ return fallback;
159
+ }
160
+ if (options.rewrite !== false) {
161
+ Storage.save(key, data, { version, backup: false });
162
+ }
60
163
  }
164
+ return data;
165
+ }
166
+
167
+ /**
168
+ * @method hasSave
169
+ * @description Returns whether a save (or its backup) exists for `key`.
170
+ * @param {string} key - The storage key
171
+ * @returns {boolean}
172
+ */
173
+ static hasSave(key) {
174
+ return (
175
+ localStorage.getItem(key) != null ||
176
+ localStorage.getItem(key + ".bak") != null
177
+ );
178
+ }
179
+
180
+ /**
181
+ * @method removeSave
182
+ * @description Deletes a save and its backup.
183
+ * @param {string} key - The storage key
184
+ */
185
+ static removeSave(key) {
186
+ localStorage.removeItem(key);
187
+ localStorage.removeItem(key + ".bak");
188
+ }
61
189
  }
62
190
 
63
- export default Storage;
191
+ export default Storage;
package/src/Texture.js CHANGED
@@ -1,67 +1,58 @@
1
- import { initVertexBuffer } from "./GLUtils.js";
2
- import Drawable from "./Drawable.js";
3
- import GLManager from "./managers/GLManager.js";
4
-
5
- /**
6
- * @class Texture
7
- * @description Represents a texture component
8
- * @param {string} texturePath - The path to the texture
9
- * @param {number} frameWidth - The width of the frame
10
- * @param {number} frameHeight - The height of the frame
11
- * @param {number} framesPerRow - The number of frames per row
12
- * @param {number} totalFrames - The total number of frames
13
- * @param {number} animationSpeed - The speed of the animation
14
- * @param {boolean} autoPlay - Whether the animation should play automatically
15
- * @param {boolean} pixelart - Whether the texture is a pixel art texture
16
- * @param {boolean} useLighting - Whether the texture should react to lighting
17
- */
18
- class Texture extends Drawable {
19
- constructor(
20
- texturePath = {},
21
- frameWidth = 0,
22
- frameHeight = 0,
23
- framesPerRow = 1,
24
- totalFrames = 1,
25
- animationSpeed = 1000,
26
- autoPlay = true,
27
- pixelart = true,
28
- useLighting = true
29
- ) {
30
- const vertices = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
31
- const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
32
- const textureCoordinates = [
33
- 1.0,
34
- 1.0, // Top-right
35
- 0.0,
36
- 1.0, // Top-left
37
- 1.0,
38
- 0.0, // Bottom-right
39
- 0.0,
40
- 0.0, // Bottom-left
41
- ];
42
- const texCoordBuffer = initVertexBuffer(
43
- GLManager.getGL(),
44
- textureCoordinates
45
- );
46
-
47
- super(
48
- GLManager.getGL(),
49
- GLManager.getProgramInfo(),
50
- verticesBuffer,
51
- texCoordBuffer,
52
- vertices,
53
- true,
54
- texturePath,
55
- frameWidth,
56
- frameHeight,
57
- framesPerRow,
58
- totalFrames,
59
- animationSpeed,
60
- autoPlay,
61
- pixelart,
62
- useLighting
63
- );
64
- }
65
- }
66
-
67
- export default Texture;
1
+ import { initVertexBuffer } from "./GLUtils.js";
2
+ import Drawable from "./Drawable.js";
3
+ import GLManager from "./managers/GLManager.js";
4
+
5
+ /**
6
+ * @class Texture
7
+ * @description Represents a texture component
8
+ * @param {string} texturePath - The path to the texture
9
+ * @param {number} frameWidth - The width of the frame
10
+ * @param {number} frameHeight - The height of the frame
11
+ * @param {number} framesPerRow - The number of frames per row
12
+ * @param {number} totalFrames - The total number of frames
13
+ * @param {number} animationSpeed - The speed of the animation
14
+ * @param {boolean} autoPlay - Whether the animation should play automatically
15
+ * @param {boolean} pixelart - Whether the texture is a pixel art texture
16
+ * @param {boolean} useLighting - Whether the texture should react to lighting
17
+ */
18
+ class Texture extends Drawable {
19
+ constructor(
20
+ texturePath = {},
21
+ frameWidth = 0,
22
+ frameHeight = 0,
23
+ framesPerRow = 1,
24
+ totalFrames = 1,
25
+ animationSpeed = 1000,
26
+ autoPlay = true,
27
+ pixelart = true,
28
+ useLighting = true
29
+ ) {
30
+ const vertices = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
31
+ const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
32
+ const textureCoordinates = [1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0];
33
+ const texCoordBuffer = initVertexBuffer(
34
+ GLManager.getGL(),
35
+ textureCoordinates
36
+ );
37
+
38
+ super(
39
+ GLManager.getGL(),
40
+ GLManager.getProgramInfo(),
41
+ verticesBuffer,
42
+ texCoordBuffer,
43
+ vertices,
44
+ true,
45
+ texturePath,
46
+ frameWidth,
47
+ frameHeight,
48
+ framesPerRow,
49
+ totalFrames,
50
+ animationSpeed,
51
+ autoPlay,
52
+ pixelart,
53
+ useLighting
54
+ );
55
+ }
56
+ }
57
+
58
+ export default Texture;
@@ -0,0 +1,96 @@
1
+ import TextureManager from "./managers/TextureManager.js";
2
+
3
+ /**
4
+ * @class TextureAtlas
5
+ * @description Loads a packed sprite atlas (image + frame rectangles) and applies
6
+ * named frames to Drawables as normalized UV regions. Accepts TexturePacker
7
+ * JSON (hash or array `frames`) or a plain `{ name: {x,y,w,h} }` map.
8
+ *
9
+ * @example
10
+ * const atlas = await TextureAtlas.load("sheet.png", sheetJson, true);
11
+ * const sprite = new Texture(atlas.texturePath, 0, 0, 1, 1, 0, false, true);
12
+ * obj.addComponent(sprite);
13
+ * atlas.applyTo(sprite, "player_idle_0");
14
+ */
15
+ class TextureAtlas {
16
+ constructor(texturePath, frames, width, height) {
17
+ this.texturePath = texturePath;
18
+ this.frames = frames;
19
+ this.width = width;
20
+ this.height = height;
21
+ }
22
+
23
+ /**
24
+ * @method load
25
+ * @description Loads the atlas image (caching its GL texture) and parses frames.
26
+ * @param {string} texturePath
27
+ * @param {Object} atlasJson - Atlas description
28
+ * @param {boolean} [pixelart] - Filter mode for the cached texture
29
+ * @returns {Promise<TextureAtlas>}
30
+ */
31
+ static async load(texturePath, atlasJson, pixelart = false) {
32
+ const image = await TextureManager.loadImage(texturePath);
33
+ await TextureManager.getTexture(texturePath, pixelart);
34
+ const w = image.width;
35
+ const h = image.height;
36
+ return new TextureAtlas(texturePath, TextureAtlas._parse(atlasJson), w, h);
37
+ }
38
+
39
+ /** @private */
40
+ static _parse(json) {
41
+ const out = {};
42
+ if (json && json.frames) {
43
+ if (Array.isArray(json.frames)) {
44
+ for (const f of json.frames) out[f.filename] = f.frame;
45
+ } else {
46
+ for (const name in json.frames) out[name] = json.frames[name].frame;
47
+ }
48
+ } else if (json) {
49
+ for (const name in json) out[name] = json[name];
50
+ }
51
+ return out;
52
+ }
53
+
54
+ /**
55
+ * @method getFrame
56
+ * @description Returns the pixel rect { x, y, w, h } for a frame name.
57
+ */
58
+ getFrame(name) {
59
+ return this.frames[name] || null;
60
+ }
61
+
62
+ /**
63
+ * @method getRegion
64
+ * @description Returns the normalized UV region for a frame name.
65
+ * @returns {{left,top,right,bottom}|null}
66
+ */
67
+ getRegion(name) {
68
+ const f = this.frames[name];
69
+ if (!f) return null;
70
+ return {
71
+ left: f.x / this.width,
72
+ top: f.y / this.height,
73
+ right: (f.x + f.w) / this.width,
74
+ bottom: (f.y + f.h) / this.height,
75
+ };
76
+ }
77
+
78
+ /**
79
+ * @method applyTo
80
+ * @description Applies a frame's UV region to a Drawable.
81
+ * @param {Drawable} drawable
82
+ * @param {string} name - Frame name
83
+ * @returns {TextureAtlas} - this
84
+ */
85
+ applyTo(drawable, name) {
86
+ const r = this.getRegion(name);
87
+ if (r) {
88
+ drawable.setRegion(r.left, r.top, r.right, r.bottom);
89
+ } else {
90
+ console.warn(`[TextureAtlas] > Unknown frame "${name}"`);
91
+ }
92
+ return this;
93
+ }
94
+ }
95
+
96
+ export default TextureAtlas;