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,242 @@
1
+ import * as planck from "planck";
2
+
3
+ /**
4
+ * @class Physics
5
+ * @description Represents the physics engine
6
+ * @param {number} gravity - The gravity of the physics engine
7
+ * @param {number} scale - The scale of the physics engine
8
+ * @param {number} velocityThreshold - The velocity threshold of the physics engine
9
+ */
10
+ class Physics {
11
+ constructor(gravity, scale, velocityThreshold = 0.1) {
12
+ this.world = new planck.World({
13
+ gravity: new planck.Vec2(0, gravity),
14
+ });
15
+ planck.Settings.velocityThreshold = velocityThreshold;
16
+ this.gravity = gravity;
17
+ this.scale = scale;
18
+ }
19
+
20
+ /**
21
+ * @method createBody
22
+ * @description Creates a body in the physics engine
23
+ * @param {string} type - The type of the body
24
+ * @param {Vector2} position - The position of the body
25
+ * @param {boolean} fixedRotation - Whether the body should have a fixed rotation
26
+ * @param {boolean} attachFixture - Whether the body should have a fixture
27
+ * @param {Vector2} fixtureSize - The size of the fixture
28
+ * @param {number} density - The density of the fixture
29
+ * @param {number} friction - The friction of the fixture
30
+ * @param {number} restitution - The restitution of the fixture
31
+ * @returns {Body} - The body
32
+ */
33
+ createBody(
34
+ type,
35
+ position = new Vector2(0, 0),
36
+ fixedRotation = false,
37
+ attachFixture = true,
38
+ fixtureSize = new Vector2(1, 1),
39
+ density = 0,
40
+ friction = 0,
41
+ restitution = 0
42
+ ) {
43
+ const bodyRef = this.world.createBody({
44
+ type: type,
45
+ position: new planck.Vec2(
46
+ position.x / this.scale,
47
+ position.y / this.scale
48
+ ),
49
+ fixedRotation: fixedRotation,
50
+ });
51
+
52
+ if (attachFixture) {
53
+ bodyRef.createFixture(new planck.Box(fixtureSize.x, fixtureSize.y), {
54
+ density: density,
55
+ friction: friction,
56
+ restitution: restitution,
57
+ });
58
+ }
59
+
60
+ return bodyRef;
61
+ }
62
+
63
+ /**
64
+ * @method onCollisionEnter
65
+ * @description Handles the collision enter event
66
+ * @param {Function} callback - The callback function to handle the collision enter event
67
+ */
68
+ onCollisionEnter(callback) {
69
+ this.world.on("begin-contact", (contact) => {
70
+ const fixtureA = contact.getFixtureA();
71
+ const fixtureB = contact.getFixtureB();
72
+
73
+ const bodyA = fixtureA.getBody();
74
+ const bodyB = fixtureB.getBody();
75
+
76
+ callback(bodyA, bodyB, contact);
77
+ });
78
+ }
79
+
80
+ /**
81
+ * @method onCollisionExit
82
+ * @description Handles the collision exit event
83
+ * @param {Function} callback - The callback function to handle the collision exit event
84
+ */
85
+ onCollisionExit(callback) {
86
+ this.world.on("end-contact", (contact) => {
87
+ const fixtureA = contact.getFixtureA();
88
+ const fixtureB = contact.getFixtureB();
89
+
90
+ const bodyA = fixtureA.getBody();
91
+ const bodyB = fixtureB.getBody();
92
+
93
+ callback(bodyA, bodyB, contact);
94
+ });
95
+ }
96
+
97
+ /**
98
+ * @method process
99
+ * @description Processes the physics engine
100
+ * @param {number} dt - The delta time
101
+ */
102
+ process(dt) {
103
+ this.world.step(dt);
104
+ }
105
+
106
+ /**
107
+ * @method clear
108
+ * @description Clears the physics engine objects and resets the gravity
109
+ */
110
+ clear() {
111
+ this.world = new planck.World({
112
+ gravity: new planck.Vec2(0, this.gravity),
113
+ });
114
+ }
115
+
116
+ /**
117
+ * @method getGravity
118
+ * @description Returns the gravity of the physics engine
119
+ * @returns {number} - The gravity of the physics engine
120
+ */
121
+ getGravity() {
122
+ return this.gravity;
123
+ }
124
+
125
+ /**
126
+ * @method getScale
127
+ * @description Returns the scale of the physics engine
128
+ * @returns {number} - The scale of the physics engine
129
+ */
130
+ getScale() {
131
+ return this.scale;
132
+ }
133
+
134
+ /**
135
+ * @method scheduleAction
136
+ * @description Schedules an action to be executed as soon as possible
137
+ * @param {Function} callback - The callback function to execute
138
+ */
139
+ static scheduleAction(callback) {
140
+ if (typeof callback === "function") {
141
+ setTimeout(() => {
142
+ callback();
143
+ }, 0);
144
+ }
145
+ }
146
+ }
147
+
148
+ /**
149
+ * @class Vector2
150
+ * @description Represents a 2D vector
151
+ * @param {number} x - The x coordinate of the vector
152
+ * @param {number} y - The y coordinate of the vector
153
+ */
154
+ class Vector2 {
155
+ constructor(x, y) {
156
+ return new planck.Vec2(x, y);
157
+ }
158
+
159
+ /**
160
+ * @method equals
161
+ * @description Checks if the vector is equal to another vector
162
+ * @param {Vector2} other - The other vector
163
+ * @returns {boolean} - True if the vector is equal to the other vector
164
+ */
165
+ equals(other) {
166
+ if (!other) return false;
167
+ if (!(other instanceof Vector2)) return false;
168
+ return this.x === other.x && this.y === other.y;
169
+ }
170
+
171
+ /**
172
+ * @method getX
173
+ * @description Returns the x coordinate of the vector
174
+ * @returns {number} - The x coordinate of the vector
175
+ */
176
+ getX() {
177
+ return this.x;
178
+ }
179
+
180
+ /**
181
+ * @method getY
182
+ * @description Returns the y coordinate of the vector
183
+ * @returns {number} - The y coordinate of the vector
184
+ */
185
+ getY() {
186
+ return this.y;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * @class Vector3
192
+ * @description Represents a 3D vector
193
+ * @param {number} x - The x coordinate of the vector
194
+ * @param {number} y - The y coordinate of the vector
195
+ * @param {number} z - The z coordinate of the vector
196
+ */
197
+ class Vector3 {
198
+ constructor(x, y, z) {
199
+ return new planck.Vec3(x, y, z);
200
+ }
201
+
202
+ /**
203
+ * @method equals
204
+ * @description Checks if the vector is equal to another vector
205
+ * @param {Vector3} other - The other vector
206
+ * @returns {boolean} - True if the vector is equal to the other vector
207
+ */
208
+ equals(other) {
209
+ if (!other) return false;
210
+ if (!(other instanceof Vector3)) return false;
211
+ return this.x === other.x && this.y === other.y && this.z === other.z;
212
+ }
213
+
214
+ /**
215
+ * @method getX
216
+ * @description Returns the x coordinate of the vector
217
+ * @returns {number} - The x coordinate of the vector
218
+ */
219
+ getX() {
220
+ return this.x;
221
+ }
222
+
223
+ /**
224
+ * @method getY
225
+ * @description Returns the y coordinate of the vector
226
+ * @returns {number} - The y coordinate of the vector
227
+ */
228
+ getY() {
229
+ return this.y;
230
+ }
231
+
232
+ /**
233
+ * @method getZ
234
+ * @description Returns the z coordinate of the vector
235
+ * @returns {number} - The z coordinate of the vector
236
+ */
237
+ getZ() {
238
+ return this.z;
239
+ }
240
+ }
241
+
242
+ export { Physics, Vector2, Vector3 };
@@ -0,0 +1,79 @@
1
+ import GameObject from "./components/GameObject.js";
2
+
3
+ /**
4
+ * @class Scene
5
+ * @description Represents a scene
6
+ * @param {Array} objects - The objects in the scene
7
+ */
8
+ class Scene {
9
+ constructor(objects = []) {
10
+ this.objects = objects;
11
+ }
12
+
13
+ /**
14
+ * @method add
15
+ * @description Adds an object to the scene
16
+ * @param {GameObject} object - The object to add
17
+ */
18
+ add(object) {
19
+ if (!(object instanceof GameObject)) {
20
+ throw new Error("Object is not a GameObject");
21
+ }
22
+ object.setIsActive(true);
23
+ if (!this.objects.some((obj) => obj.id === object.id)) {
24
+ this.objects.push(object);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * @method remove
30
+ * @description Removes an object from the scene
31
+ * @param {GameObject} object - The object to remove
32
+ */
33
+ remove(object) {
34
+ if (!(object instanceof GameObject)) {
35
+ throw new Error("Object is not a GameObject");
36
+ }
37
+ object.setIsActive(false);
38
+ this.objects = this.objects.filter((obj) => obj?.id !== object?.id);
39
+ }
40
+
41
+ /**
42
+ * @method setIsActive
43
+ * @description Sets the active state of the scene
44
+ * @param {boolean} bool - The active state
45
+ */
46
+ setIsActive(bool) {
47
+ for (let object of this.objects) {
48
+ this.setActiveRecursive(object, bool);
49
+ }
50
+ }
51
+
52
+ /**
53
+ * @method setActiveRecursive
54
+ * @description Sets the active state of the scene recursively
55
+ * @param {Object} object - The object to set the active state of
56
+ * @param {boolean} bool - The active state
57
+ */
58
+ setActiveRecursive(object, bool) {
59
+ object.setIsActive(bool);
60
+ }
61
+
62
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator
63
+ [Symbol.iterator]() {
64
+ let index = -1;
65
+ const data = this.objects;
66
+
67
+ return {
68
+ next: () => ({ value: data[++index], done: !(index in data) }),
69
+ };
70
+ }
71
+
72
+ forEach(callback) {
73
+ for (const obj of this.objects) {
74
+ callback(obj);
75
+ }
76
+ }
77
+ }
78
+
79
+ export default Scene;
@@ -0,0 +1,165 @@
1
+ const STANDARD_VERTEX_SHADER = `
2
+ attribute vec4 aVertexPosition;
3
+ attribute vec2 aTextureCoord;
4
+
5
+ // Instance matrix (each row as a separate attribute)
6
+ attribute vec4 aInstanceMatrix0;
7
+ attribute vec4 aInstanceMatrix1;
8
+ attribute vec4 aInstanceMatrix2;
9
+ attribute vec4 aInstanceMatrix3;
10
+
11
+ // Per-instance texture coordinates (one for each vertex of the quad)
12
+ attribute vec2 aInstanceTexCoord0;
13
+ attribute vec2 aInstanceTexCoord1;
14
+ attribute vec2 aInstanceTexCoord2;
15
+ attribute vec2 aInstanceTexCoord3;
16
+
17
+ uniform mat4 uModelViewMatrix;
18
+ uniform mat4 uInstancedModelViewMatrix;
19
+ uniform mat4 uProjectionMatrix;
20
+ uniform bool useInstances;
21
+
22
+ varying highp vec2 vTexCoord;
23
+ varying vec2 vFragPos;
24
+
25
+ void main() {
26
+ // Construct the instance matrix
27
+ mat4 instanceMatrix = mat4(
28
+ aInstanceMatrix0,
29
+ aInstanceMatrix1,
30
+ aInstanceMatrix2,
31
+ aInstanceMatrix3
32
+ );
33
+
34
+ // Apply the instance-specific transform, then the global transforms
35
+ if(useInstances) {
36
+ gl_Position = uProjectionMatrix * uInstancedModelViewMatrix * instanceMatrix * aVertexPosition;
37
+ vFragPos = (uInstancedModelViewMatrix * instanceMatrix * aVertexPosition).xy;
38
+
39
+ // Use per-instance texture coordinates based on vertex index
40
+ // Vertex order: top-right, top-left, bottom-right, bottom-left
41
+ int vertexIndex = int(aVertexPosition.x > 0.0 ? (aVertexPosition.y > 0.0 ? 0 : 2) : (aVertexPosition.y > 0.0 ? 1 : 3));
42
+
43
+ if(vertexIndex == 0) {
44
+ vTexCoord = aInstanceTexCoord0;
45
+ } else if(vertexIndex == 1) {
46
+ vTexCoord = aInstanceTexCoord1;
47
+ } else if(vertexIndex == 2) {
48
+ vTexCoord = aInstanceTexCoord2;
49
+ } else {
50
+ vTexCoord = aInstanceTexCoord3;
51
+ }
52
+ } else {
53
+ gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
54
+ vFragPos = (uModelViewMatrix * aVertexPosition).xy;
55
+ vTexCoord = aTextureCoord;
56
+ }
57
+ }
58
+ `;
59
+
60
+ const STANDARD_FRAGMENT_SHADER = `
61
+ #ifdef GL_ES
62
+ precision highp float;
63
+ #endif
64
+ uniform bool useTexture;
65
+ uniform vec4 uColor;
66
+ uniform sampler2D uSampler;
67
+ uniform float uOpacity; // Global opacity multiplier per GameObject
68
+
69
+ uniform vec2 uLightPosition[4]; // Support up to 4 lights
70
+ uniform vec3 uLightColor[4]; // RGB colors for each light
71
+ uniform float uLightIntensity[4]; // Intensity of each light
72
+ uniform float uLightRadius[4]; // Radius of each light
73
+ uniform int uActiveLights; // Number of active lights
74
+
75
+ // Directional lights
76
+ uniform vec2 uDirLightPosition[4]; // Position of directional lights
77
+ uniform vec2 uDirLightDirection[4]; // Direction of directional lights
78
+ uniform vec3 uDirLightColor[4]; // RGB colors for each directional light
79
+ uniform float uDirLightIntensity[4]; // Intensity of each directional light
80
+ uniform float uDirLightWidth[4]; // Width of each directional light beam
81
+ uniform int uActiveDirLights; // Number of active directional lights
82
+
83
+ uniform vec3 uAmbientLightValues; // Ambient light values
84
+ uniform bool uUseLighting; // Whether to apply lighting to this object
85
+
86
+ varying vec2 vTexCoord;
87
+ varying vec2 vFragPos;
88
+
89
+ void main() {
90
+ vec4 ambientLight = vec4(uAmbientLightValues.xyz, 1.0); // Move ambient light here
91
+
92
+ vec4 texColor;
93
+ if (useTexture) {
94
+ texColor = texture2D(uSampler, vTexCoord);
95
+ // Discard only fully or nearly fully transparent texels to keep soft edges
96
+ if (texColor.a < 0.01) discard;
97
+ // Apply color tint to texture
98
+ texColor *= uColor;
99
+ } else {
100
+ texColor = uColor;
101
+ }
102
+
103
+ // Start with ambient light
104
+ vec3 lighting = ambientLight.rgb;
105
+
106
+ // Calculate contribution from each point light
107
+ for(int i = 0; i < 4; i++) {
108
+ if(i >= uActiveLights) break;
109
+
110
+ float distance = length(uLightPosition[i] - vFragPos);
111
+
112
+ // Check if fragment is within light radius
113
+ if(distance < uLightRadius[i]) {
114
+ // Calculate attenuation (falloff)
115
+ float attenuation = 1.0 - distance / uLightRadius[i];
116
+
117
+ // Add this light's contribution
118
+ lighting += uLightColor[i] * attenuation * uLightIntensity[i];
119
+ }
120
+ }
121
+
122
+ // Calculate contribution from each directional light
123
+ for(int i = 0; i < 4; i++) {
124
+ if(i >= uActiveDirLights) break;
125
+
126
+ vec2 lightPos = uDirLightPosition[i];
127
+ vec2 lightDir = normalize(uDirLightDirection[i]);
128
+ vec2 toFrag = vFragPos - lightPos;
129
+
130
+ // Check if fragment is in front of the light
131
+ float projection = dot(toFrag, lightDir);
132
+ if(projection < 0.0) continue;
133
+
134
+ // Calculate perpendicular distance from light beam center
135
+ float perpDistance = abs(dot(toFrag, vec2(-lightDir.y, lightDir.x)));
136
+
137
+ // Check if fragment is within light beam width
138
+ if(perpDistance > uDirLightWidth[i] * 0.5) continue;
139
+
140
+ // Simplified lighting without shadows for now
141
+ float widthFactor = 1.0 - (perpDistance / (uDirLightWidth[i] * 0.5));
142
+
143
+ // Optional: Add distance attenuation
144
+ float distance = length(toFrag);
145
+ float maxDistance = 1000.0; // Maximum effective distance
146
+ float distanceFactor = max(0.0, 1.0 - (distance / maxDistance));
147
+
148
+ // Add this directional light's contribution
149
+ lighting += uDirLightColor[i] * uDirLightIntensity[i] * widthFactor * distanceFactor;
150
+ }
151
+
152
+ // Apply lighting to texture color only if lighting is enabled
153
+ vec4 outColor;
154
+ if (uUseLighting) {
155
+ outColor = vec4(texColor.rgb * lighting, texColor.a);
156
+ } else {
157
+ outColor = texColor;
158
+ }
159
+ // Apply global opacity multiplier
160
+ outColor.a *= clamp(uOpacity, 0.0, 1.0);
161
+ gl_FragColor = outColor;
162
+ }
163
+ `;
164
+
165
+ export { STANDARD_VERTEX_SHADER, STANDARD_FRAGMENT_SHADER };
@@ -0,0 +1,129 @@
1
+ import { initVertexBuffer } from "./GLUtils.js";
2
+ import Drawable from "./Drawable.js";
3
+ import GLManager from "./managers/GLManager.js";
4
+
5
+ /**
6
+ * @class Square2D
7
+ * @description Represents a square 2D shape
8
+ */
9
+ class Square2D extends Drawable {
10
+ constructor() {
11
+ const vertices = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
12
+ const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
13
+ const textureCoordinates = [
14
+ 1.0,
15
+ 1.0, // Top-right
16
+ 0.0,
17
+ 1.0, // Top-left
18
+ 1.0,
19
+ 0.0, // Bottom-right
20
+ 0.0,
21
+ 0.0, // Bottom-left
22
+ ];
23
+ const texCoordBuffer = initVertexBuffer(
24
+ GLManager.getGL(),
25
+ textureCoordinates
26
+ );
27
+
28
+ super(
29
+ GLManager.getGL(),
30
+ GLManager.getProgramInfo(),
31
+ verticesBuffer,
32
+ texCoordBuffer,
33
+ vertices,
34
+ false,
35
+ "",
36
+ 0,
37
+ 0,
38
+ 0,
39
+ 0,
40
+ 0,
41
+ false
42
+ );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @class Triangle2D
48
+ * @description Represents a triangle 2D shape
49
+ */
50
+ class Triangle2D extends Drawable {
51
+ constructor() {
52
+ const vertices = [0.0, 1.0, 1.0, -1.0, -1.0, -1.0];
53
+ const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
54
+
55
+ const textureCoordinates = [0.5, 1.0, 1.0, 0.0, 0.0, 0.0];
56
+ const texCoordBuffer = initVertexBuffer(
57
+ GLManager.getGL(),
58
+ textureCoordinates
59
+ );
60
+
61
+ super(
62
+ GLManager.getGL(),
63
+ GLManager.getProgramInfo(),
64
+ verticesBuffer,
65
+ texCoordBuffer,
66
+ vertices,
67
+ false,
68
+ "",
69
+ 0,
70
+ 0,
71
+ 0,
72
+ 0,
73
+ 0,
74
+ false
75
+ );
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @class Circle2D
81
+ * @description Represents a circle 2D shape
82
+ * @param {number} segments - The number of segments to use to draw the circle
83
+ */
84
+ class Circle2D extends Drawable {
85
+ constructor(segments = 32) {
86
+ const radius = 1.0;
87
+ const vertices = [];
88
+ const textureCoordinates = [];
89
+
90
+ // Add center vertex
91
+ vertices.push(0, 0);
92
+ textureCoordinates.push(0.5, 0.5);
93
+
94
+ // Add perimeter vertices
95
+ for (let i = 0; i <= segments; i++) {
96
+ const angle = (i * 2 * Math.PI) / segments;
97
+ const x = radius * Math.cos(angle);
98
+ const y = radius * Math.sin(angle);
99
+ vertices.push(x, y);
100
+ textureCoordinates.push((x / radius + 1) / 2, (y / radius + 1) / 2);
101
+ }
102
+
103
+ const verticesBuffer = initVertexBuffer(GLManager.getGL(), vertices);
104
+ const texCoordBuffer = initVertexBuffer(
105
+ GLManager.getGL(),
106
+ textureCoordinates
107
+ );
108
+
109
+ super(
110
+ GLManager.getGL(),
111
+ GLManager.getProgramInfo(),
112
+ verticesBuffer,
113
+ texCoordBuffer,
114
+ vertices,
115
+ false,
116
+ "",
117
+ 0,
118
+ 0,
119
+ 0,
120
+ 0,
121
+ 0,
122
+ false,
123
+ true,
124
+ false
125
+ );
126
+ }
127
+ }
128
+
129
+ export { Square2D, Triangle2D, Circle2D };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @class Storage
3
+ * @description Manages the storage of the game
4
+ */
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
+ }
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
+ }
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
+ }
53
+
54
+ /**
55
+ * @method clearSessionStorage
56
+ * @description Clears session storage
57
+ */
58
+ static clearSessionStorage() {
59
+ sessionStorage.clear();
60
+ }
61
+ }
62
+
63
+ export default Storage;