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.
- package/README.md +968 -0
- package/dist/types/imports/BitmapText.d.ts +79 -0
- package/dist/types/imports/Color.d.ts +17 -0
- package/dist/types/imports/Drawable.d.ts +157 -0
- package/dist/types/imports/Emerald.d.ts +73 -0
- package/dist/types/imports/FPSCounter.d.ts +19 -0
- package/dist/types/imports/GLUtils.d.ts +6 -0
- package/dist/types/imports/Instance.d.ts +87 -0
- package/dist/types/imports/InstancedTexture.d.ts +230 -0
- package/dist/types/imports/Physics.d.ts +139 -0
- package/dist/types/imports/Scene.d.ts +39 -0
- package/dist/types/imports/Shaders.d.ts +4 -0
- package/dist/types/imports/Shapes.d.ts +25 -0
- package/dist/types/imports/Storage.d.ts +46 -0
- package/dist/types/imports/Texture.d.ts +19 -0
- package/dist/types/imports/Time.d.ts +22 -0
- package/dist/types/imports/Transform.d.ts +41 -0
- package/dist/types/imports/components/BoxCollider.d.ts +41 -0
- package/dist/types/imports/components/BoxColliderDebug.d.ts +19 -0
- package/dist/types/imports/components/CircleCollider.d.ts +39 -0
- package/dist/types/imports/components/CircleColliderDebug.d.ts +19 -0
- package/dist/types/imports/components/Collider.d.ts +53 -0
- package/dist/types/imports/components/GameObject.d.ts +72 -0
- package/dist/types/imports/components/RigidBody.d.ts +104 -0
- package/dist/types/imports/lights/DirectionalLight.d.ts +26 -0
- package/dist/types/imports/lights/PointLight.d.ts +18 -0
- package/dist/types/imports/managers/AudioManager.d.ts +60 -0
- package/dist/types/imports/managers/CameraManager.d.ts +35 -0
- package/dist/types/imports/managers/EventManager.d.ts +187 -0
- package/dist/types/imports/managers/GLManager.d.ts +47 -0
- package/dist/types/imports/managers/IDManager.d.ts +21 -0
- package/dist/types/imports/managers/SceneManager.d.ts +22 -0
- package/dist/types/imports/particlesystem/Particle.d.ts +42 -0
- package/dist/types/imports/particlesystem/ParticleSettings.d.ts +49 -0
- package/dist/types/imports/particlesystem/Particles.d.ts +71 -0
- package/dist/types/index.d.ts +32 -0
- package/imports/BitmapText.js +245 -0
- package/imports/Color.js +18 -0
- package/imports/Drawable.js +550 -0
- package/imports/Emerald.js +459 -0
- package/imports/FPSCounter.js +43 -0
- package/imports/GLUtils.js +67 -0
- package/imports/Instance.js +187 -0
- package/imports/InstancedTexture.js +856 -0
- package/imports/Physics.js +242 -0
- package/imports/Scene.js +79 -0
- package/imports/Shaders.js +165 -0
- package/imports/Shapes.js +129 -0
- package/imports/Storage.js +63 -0
- package/imports/Texture.js +67 -0
- package/imports/Time.js +28 -0
- package/imports/Transform.js +59 -0
- package/imports/components/BoxCollider.js +67 -0
- package/imports/components/BoxColliderDebug.js +38 -0
- package/imports/components/CircleCollider.js +67 -0
- package/imports/components/CircleColliderDebug.js +36 -0
- package/imports/components/Collider.js +51 -0
- package/imports/components/GameObject.js +160 -0
- package/imports/components/RigidBody.js +169 -0
- package/imports/lights/DirectionalLight.js +68 -0
- package/imports/lights/PointLight.js +17 -0
- package/imports/managers/AudioManager.js +146 -0
- package/imports/managers/CameraManager.js +60 -0
- package/imports/managers/EventManager.js +479 -0
- package/imports/managers/GLManager.js +65 -0
- package/imports/managers/IDManager.js +32 -0
- package/imports/managers/SceneManager.js +27 -0
- package/imports/managers/ShaderManager.js +133 -0
- package/imports/particlesystem/Particle.js +75 -0
- package/imports/particlesystem/ParticleSettings.js +49 -0
- package/imports/particlesystem/Particles.js +226 -0
- package/index.js +67 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,968 @@
|
|
|
1
|
+
# Emerald
|
|
2
|
+
|
|
3
|
+
Emerald is a comprehensive 2D graphics engine that can help you create games easier than ever.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Emerald](#emerald)
|
|
8
|
+
- [Table of Contents](#table-of-contents)
|
|
9
|
+
- [Getting Started](#getting-started)
|
|
10
|
+
- [Usage](#usage)
|
|
11
|
+
- [Basic Setup](#basic-setup)
|
|
12
|
+
- [Set the background color for the engine](#set-the-background-color-for-the-engine)
|
|
13
|
+
- [Drawing the scene](#drawing-the-scene)
|
|
14
|
+
- [Scene](#scene)
|
|
15
|
+
- [Adding and removing items from the scene](#adding-and-removing-items-from-the-scene)
|
|
16
|
+
- [Set Active Scene](#set-active-scene)
|
|
17
|
+
- [Game Objects](#game-objects)
|
|
18
|
+
- [Creating a new GameObject](#creating-a-new-gameobject)
|
|
19
|
+
- [Components](#components)
|
|
20
|
+
- [Texture](#texture)
|
|
21
|
+
- [InstancedTexture](#instancedtexture)
|
|
22
|
+
- [Square2D](#square2d)
|
|
23
|
+
- [Triangle2D](#triangle2d)
|
|
24
|
+
- [Circle2D](#circle2d)
|
|
25
|
+
- [RigidBody](#rigidbody)
|
|
26
|
+
- [BoxCollider](#boxcollider)
|
|
27
|
+
- [CircleCollider](#circlecollider)
|
|
28
|
+
- [Object methods](#object-methods)
|
|
29
|
+
- [Position](#position)
|
|
30
|
+
- [Rotation](#rotation)
|
|
31
|
+
- [Scale](#scale)
|
|
32
|
+
- [Change color](#change-color)
|
|
33
|
+
- [Set texture frame](#set-texture-frame)
|
|
34
|
+
- [Animations](#animations)
|
|
35
|
+
- [Instance System](#instance-system)
|
|
36
|
+
- [Creating Instances](#creating-instances)
|
|
37
|
+
- [Instance Management](#instance-management)
|
|
38
|
+
- [Instance Events](#instance-events)
|
|
39
|
+
- [Physics Engine](#physics-engine)
|
|
40
|
+
- [Setting up Physics](#setting-up-physics)
|
|
41
|
+
- [Physics Bodies](#physics-bodies)
|
|
42
|
+
- [Collision Detection](#collision-detection)
|
|
43
|
+
- [Collision Events](#collision-events)
|
|
44
|
+
- [Particle System](#particle-system)
|
|
45
|
+
- [Particle Settings](#particle-settings)
|
|
46
|
+
- [Creating Particle Systems](#creating-particle-systems)
|
|
47
|
+
- [Particle System Methods](#particle-system-methods)
|
|
48
|
+
- [Lighting System](#lighting-system)
|
|
49
|
+
- [Ambient Light](#ambient-light)
|
|
50
|
+
- [Point Light](#point-light)
|
|
51
|
+
- [Directional Light](#directional-light)
|
|
52
|
+
- [Text Rendering](#text-rendering)
|
|
53
|
+
- [BitmapText](#bitmaptext)
|
|
54
|
+
- [EventManager](#eventmanager)
|
|
55
|
+
- [Keyboard Events](#keyboard-events)
|
|
56
|
+
- [Mouse Events](#mouse-events)
|
|
57
|
+
- [Object Events](#object-events)
|
|
58
|
+
- [Event Cleanup](#event-cleanup)
|
|
59
|
+
- [AudioManager](#audiomanager)
|
|
60
|
+
- [Adding Audio](#adding-audio)
|
|
61
|
+
- [Playing Audio](#playing-audio)
|
|
62
|
+
- [Audio Control](#audio-control)
|
|
63
|
+
- [Camera](#camera)
|
|
64
|
+
- [FPSCounter](#fpscounter)
|
|
65
|
+
- [Scene Management](#scene-management)
|
|
66
|
+
- [Time Management](#time-management)
|
|
67
|
+
- [Advanced Features](#advanced-features)
|
|
68
|
+
- [Resize Handling](#resize-handling)
|
|
69
|
+
|
|
70
|
+
## Getting Started
|
|
71
|
+
|
|
72
|
+
To get started with Emerald, you need to have a canvas element in your HTML and import the necessary classes.
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Basic Setup
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
import { Emerald } from "./emerald/Emerald";
|
|
80
|
+
import { Scene } from "./emerald/Scene";
|
|
81
|
+
import { Color } from "./emerald/Color";
|
|
82
|
+
import SceneManager from "./emerald/managers/SceneManager";
|
|
83
|
+
|
|
84
|
+
const emerald = new Emerald(canvas); // You should pass your own canvas element here
|
|
85
|
+
const scene = new Scene();
|
|
86
|
+
SceneManager.setScene(scene);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Set the background color for the engine
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
emerald.setBackgroundColor(color); // color = new Color(r, g, b, a = 255);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Drawing the scene
|
|
96
|
+
|
|
97
|
+
To draw items in the screen you need some sort of animation loop. I use `window.requestAnimationFrame` for this. Here is a basic example:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
let lastTime = 0;
|
|
101
|
+
const animate = (currentTime) => {
|
|
102
|
+
const deltaTime = (currentTime - lastTime) / 1000;
|
|
103
|
+
lastTime = currentTime;
|
|
104
|
+
emerald.drawScene(scene, deltaTime); // You need this line to tell the engine what to draw
|
|
105
|
+
window.requestAnimationFrame(animate);
|
|
106
|
+
};
|
|
107
|
+
animate(0);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Scene
|
|
111
|
+
|
|
112
|
+
Emerald has multiple scenes support. In order to render any object it has to be added to the scene using the `add` method.
|
|
113
|
+
|
|
114
|
+
### Adding and removing items from the scene
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// Adding an object to the scene
|
|
118
|
+
scene.add(gameObject);
|
|
119
|
+
|
|
120
|
+
// Removing an object from the scene
|
|
121
|
+
scene.remove(gameObject);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Set Active Scene
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
// When changing a scene you should deactivate current scene to not mess up the event manager.
|
|
128
|
+
|
|
129
|
+
// Activate Scene
|
|
130
|
+
scene.setIsActive(true);
|
|
131
|
+
|
|
132
|
+
// Deactivate Scene
|
|
133
|
+
scene.setIsActive(false);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Game Objects
|
|
137
|
+
|
|
138
|
+
### Creating a new GameObject
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
import GameObject from "./emerald/components/GameObject";
|
|
142
|
+
import { Vector3, Vector2 } from "./emerald/Physics";
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
ARGUMENTS:
|
|
146
|
+
1. name: string = Name of the new GameObject
|
|
147
|
+
2. position: Vector3 = Position of the new GameObject
|
|
148
|
+
3. rotation: number = Rotation of the new GameObject
|
|
149
|
+
4. scale: Vector2 = Scale of the new GameObject
|
|
150
|
+
*/
|
|
151
|
+
const gameObject = new GameObject(name, position, rotation, scale);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
This will create a new empty GameObject. At this stage you will not see anything on the screen until you add some components.
|
|
155
|
+
|
|
156
|
+
### Components
|
|
157
|
+
|
|
158
|
+
There are currently 8 components: Texture, InstancedTexture, Square2D, Circle2D, Triangle2D, RigidBody, BoxCollider, CircleCollider
|
|
159
|
+
|
|
160
|
+
#### Texture
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
import { Texture } from "./emerald/Texture";
|
|
164
|
+
|
|
165
|
+
/*
|
|
166
|
+
ARGUMENTS:
|
|
167
|
+
1. texturePath = Specify the path for the texture that you want to use.
|
|
168
|
+
2. frameWidth: number = The width of each frame.
|
|
169
|
+
3. frameHeight: number = The height of each frame.
|
|
170
|
+
4. framesPerRow: number = How many frames are in one row in your spritesheet.
|
|
171
|
+
5. totalFrames: number = How many total frames does your spritesheet have.
|
|
172
|
+
6. animationSpeed: number = Speed of change of every frame.
|
|
173
|
+
7. autoPlay: boolean = Specify if you want the animation to play automatically. If you don't want any animation then pass false for it.
|
|
174
|
+
8. pixelart: boolean = Specify whether the texture should be rendered in pixel art style. (THIS IS OPTIONAL. If you don't specify it then it will be defaulted to true)
|
|
175
|
+
9. useLighting: boolean = Specify whether the texture should react to lighting or not. If you don't want any lighting then pass false for it. (THIS IS OPTIONAL. If you don't specify it then it will be defaulted to true)
|
|
176
|
+
*/
|
|
177
|
+
const texture = new Texture(
|
|
178
|
+
texturePath,
|
|
179
|
+
frameWidth,
|
|
180
|
+
frameHeight,
|
|
181
|
+
framesPerRow,
|
|
182
|
+
totalFrames,
|
|
183
|
+
animationSpeed,
|
|
184
|
+
autoPlay,
|
|
185
|
+
(pixelart = true),
|
|
186
|
+
(useLighting = true)
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Add the texture to a game object
|
|
190
|
+
gameObject.addComponent(texture);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+

|
|
194
|
+
|
|
195
|
+
#### InstancedTexture
|
|
196
|
+
|
|
197
|
+
InstancedTexture is perfect for rendering many objects with the same texture efficiently, such as tiles, particles, or repeating elements.
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
import { InstancedTexture } from "./emerald/InstancedTexture";
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
ARGUMENTS:
|
|
204
|
+
1. texturePath = Specify the path for the texture that you want to use.
|
|
205
|
+
2. instanceCount: number = How many instances of the texture you want to create.
|
|
206
|
+
3. frameWidth: number = The width of each frame.
|
|
207
|
+
4. frameHeight: number = The height of each frame.
|
|
208
|
+
5. framesPerRow: number = How many frames are in one row in your spritesheet.
|
|
209
|
+
6. totalFrames: number = How many total frames does your spritesheet have.
|
|
210
|
+
7. animationSpeed: number = Speed of change of every frame.
|
|
211
|
+
8. autoPlay: boolean = Specify if you want the animation to play automatically. If you don't want any animation then pass false for it.
|
|
212
|
+
9. pixelart: boolean = Specify whether the texture should be rendered in pixel art style. (THIS IS OPTIONAL. If you don't specify it then it will be defaulted to true)
|
|
213
|
+
10. useLighting: boolean = Specify whether the texture should react to lighting or not. If you don't want any lighting then pass false for it. (THIS IS OPTIONAL. If you don't specify it then it will be defaulted to true)
|
|
214
|
+
*/
|
|
215
|
+
const instancedTexture = new InstancedTexture(
|
|
216
|
+
texturePath,
|
|
217
|
+
instanceCount,
|
|
218
|
+
frameWidth,
|
|
219
|
+
frameHeight,
|
|
220
|
+
framesPerRow,
|
|
221
|
+
totalFrames,
|
|
222
|
+
animationSpeed,
|
|
223
|
+
autoPlay,
|
|
224
|
+
(pixelart = true),
|
|
225
|
+
(useLighting = true)
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
// Add the instanced texture to a game object
|
|
229
|
+
gameObject.addComponent(instancedTexture);
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+

|
|
233
|
+
|
|
234
|
+
#### Square2D
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
import { Square2D } from "./emerald/Shapes";
|
|
238
|
+
|
|
239
|
+
let square = new Square2D();
|
|
240
|
+
gameObject.addComponent(square);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+

|
|
244
|
+
|
|
245
|
+
#### Triangle2D
|
|
246
|
+
|
|
247
|
+
```javascript
|
|
248
|
+
import { Triangle2D } from "./emerald/Shapes";
|
|
249
|
+
|
|
250
|
+
let triangle = new Triangle2D();
|
|
251
|
+
gameObject.addComponent(triangle);
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+

|
|
255
|
+
|
|
256
|
+
#### Circle2D
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
import { Circle2D } from "./emerald/Shapes";
|
|
260
|
+
|
|
261
|
+
/*
|
|
262
|
+
ARGUMENTS:
|
|
263
|
+
1. segments = number of segments that the circle will have. Default is 32.
|
|
264
|
+
*/
|
|
265
|
+
let circle = new Circle2D(segments);
|
|
266
|
+
gameObject.addComponent(circle);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+

|
|
270
|
+
|
|
271
|
+
#### RigidBody
|
|
272
|
+
|
|
273
|
+
RigidBody is a component that allows you to add physics to your game objects. However, it won't work until you create a Physics instance at the top of your code.
|
|
274
|
+
|
|
275
|
+
```javascript
|
|
276
|
+
import RigidBody from "./emerald/components/RigidBody";
|
|
277
|
+
import { Physics, Vector2 } from "./emerald/Physics";
|
|
278
|
+
|
|
279
|
+
// Create physics engine first
|
|
280
|
+
const physics = new Physics(-70, 32, 2); // gravity, scale, velocityThreshold
|
|
281
|
+
|
|
282
|
+
/*
|
|
283
|
+
ARGUMENTS:
|
|
284
|
+
1. physics: Physics = Instance of the Physics class that you created at the top of your code.
|
|
285
|
+
2. type: string = Type of the rigid body. It can be "dynamic", "kinematic", or "static".
|
|
286
|
+
3. position: Vector2 = Position of the rigid body is Vector2 because it doesn't need any Z index.
|
|
287
|
+
4. fixedRotation: boolean = Specify whether the rigid body should have a fixed rotation or not. Default is false.
|
|
288
|
+
5. parentObject: GameObject = (OPTIONAL) If you want to attach the rigid body to a GameObject you can pass it here. If you don't want to attach it to any GameObject then pass null.
|
|
289
|
+
6. offset: Vector2 = (OPTIONAL) Offset from the GameObject's position.
|
|
290
|
+
*/
|
|
291
|
+
const rigidBody = new RigidBody(
|
|
292
|
+
physics,
|
|
293
|
+
"dynamic",
|
|
294
|
+
new Vector2(0, 0),
|
|
295
|
+
false,
|
|
296
|
+
gameObject,
|
|
297
|
+
new Vector2(0, 0)
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
gameObject.addComponent(rigidBody);
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### BoxCollider
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
import BoxCollider from "./emerald/components/BoxCollider";
|
|
307
|
+
|
|
308
|
+
/*
|
|
309
|
+
ARGUMENTS:
|
|
310
|
+
1. rigidBody: RigidBody = The rigid body component that this collider will be attached to.
|
|
311
|
+
2. size: Vector2 = Size of the box collider.
|
|
312
|
+
3. density: number = Density of the collider.
|
|
313
|
+
4. friction: number = Friction of the collider.
|
|
314
|
+
5. restitution: number = Restitution (bounciness) of the collider.
|
|
315
|
+
6. isSensor: boolean = Whether this collider is a sensor (triggers events but doesn't collide physically).
|
|
316
|
+
7. parentObject: GameObject = (OPTIONAL) Parent GameObject.
|
|
317
|
+
*/
|
|
318
|
+
const boxCollider = new BoxCollider(
|
|
319
|
+
rigidBody,
|
|
320
|
+
new Vector2(1, 1),
|
|
321
|
+
1,
|
|
322
|
+
0.3,
|
|
323
|
+
0.1,
|
|
324
|
+
false,
|
|
325
|
+
gameObject
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
gameObject.addComponent(boxCollider);
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+

|
|
332
|
+
|
|
333
|
+
The `BoxCollider` is specifically made bigger than the `Square2D` component in this image to demonstrate how it works. You can adjust the size of the collider to fit your needs.
|
|
334
|
+
|
|
335
|
+
#### CircleCollider
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
import CircleCollider from "./emerald/components/CircleCollider";
|
|
339
|
+
|
|
340
|
+
/*
|
|
341
|
+
ARGUMENTS:
|
|
342
|
+
1. rigidBody: RigidBody = The rigid body component that this collider will be attached to.
|
|
343
|
+
2. radius: number = Radius of the circle collider.
|
|
344
|
+
3. density: number = Density of the collider.
|
|
345
|
+
4. friction: number = Friction of the collider.
|
|
346
|
+
5. restitution: number = Restitution (bounciness) of the collider.
|
|
347
|
+
6. isSensor: boolean = Whether this collider is a sensor.
|
|
348
|
+
7. parentObject: GameObject = (OPTIONAL) Parent GameObject.
|
|
349
|
+
*/
|
|
350
|
+
const circleCollider = new CircleCollider(
|
|
351
|
+
rigidBody,
|
|
352
|
+
1.5,
|
|
353
|
+
1,
|
|
354
|
+
0.3,
|
|
355
|
+
0.8,
|
|
356
|
+
false,
|
|
357
|
+
gameObject
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
gameObject.addComponent(circleCollider);
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+

|
|
364
|
+
|
|
365
|
+
The `CircleCollider` is specifically made bigger than the `Circle2D` component in this image to demonstrate how it works. You can adjust the radius of the collider to fit your needs.
|
|
366
|
+
|
|
367
|
+
## Object methods
|
|
368
|
+
|
|
369
|
+
### Position
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
// Set position
|
|
373
|
+
gameObject.transform.position.x = 100;
|
|
374
|
+
gameObject.transform.position.y = 200;
|
|
375
|
+
gameObject.transform.position.z = 0;
|
|
376
|
+
|
|
377
|
+
// Or set all at once
|
|
378
|
+
gameObject.transform.position = new Vector3(100, 200, 0);
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+

|
|
382
|
+
|
|
383
|
+
### Rotation
|
|
384
|
+
|
|
385
|
+
```javascript
|
|
386
|
+
// Set rotation (in radians)
|
|
387
|
+
gameObject.transform.rotation = Math.PI / 4; // 45 degrees
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+

|
|
391
|
+
|
|
392
|
+
### Scale
|
|
393
|
+
|
|
394
|
+
```javascript
|
|
395
|
+
// Set scale
|
|
396
|
+
gameObject.transform.scale.x = 2;
|
|
397
|
+
gameObject.transform.scale.y = 2;
|
|
398
|
+
|
|
399
|
+
// Or set both at once
|
|
400
|
+
gameObject.transform.scale = new Vector2(2, 2);
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+

|
|
404
|
+
|
|
405
|
+
### Change color
|
|
406
|
+
|
|
407
|
+
```javascript
|
|
408
|
+
// For textures
|
|
409
|
+
const texture = gameObject.getComponent(Texture);
|
|
410
|
+
texture.setColor(new Color(255, 0, 0)); // Red
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+

|
|
414
|
+
|
|
415
|
+
### Set texture frame
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
// For animated textures
|
|
419
|
+
const texture = gameObject.getComponent(Texture);
|
|
420
|
+
texture.setFrame(2); // Set to frame 2
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Animations
|
|
424
|
+
|
|
425
|
+
```javascript
|
|
426
|
+
// Play animation
|
|
427
|
+
texture.playAnimation([0, 1, 2, 3], 200); // frames array, speed in ms
|
|
428
|
+
|
|
429
|
+
// Stop animation
|
|
430
|
+
texture.stopAnimation();
|
|
431
|
+
|
|
432
|
+
// Check if playing
|
|
433
|
+
if (texture.isPlaying) {
|
|
434
|
+
// Animation is currently playing
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+

|
|
439
|
+
|
|
440
|
+
## Instance System
|
|
441
|
+
|
|
442
|
+
The Instance system allows you to efficiently manage multiple copies of the same object.
|
|
443
|
+
|
|
444
|
+
### Creating Instances
|
|
445
|
+
|
|
446
|
+
```javascript
|
|
447
|
+
import Instance from "./emerald/Instance";
|
|
448
|
+
|
|
449
|
+
// Create an instance
|
|
450
|
+
const instance = new Instance(
|
|
451
|
+
"InstanceName",
|
|
452
|
+
new Vector3(x, y, z),
|
|
453
|
+
new Vector2(width, height),
|
|
454
|
+
rotation,
|
|
455
|
+
frame
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
// Add to InstancedTexture
|
|
459
|
+
const instancedTexture = gameObject.getComponent(InstancedTexture);
|
|
460
|
+
instancedTexture.addInstance(instance);
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Instance Management
|
|
464
|
+
|
|
465
|
+
```javascript
|
|
466
|
+
// Remove instance
|
|
467
|
+
instancedTexture.removeInstance(instanceId);
|
|
468
|
+
|
|
469
|
+
// Get instance by ID
|
|
470
|
+
const instance = instancedTexture.getInstanceWithId(instanceId);
|
|
471
|
+
|
|
472
|
+
// Get instance at position
|
|
473
|
+
const instance = instancedTexture.getInstanceAtPosition(position, tolerance);
|
|
474
|
+
|
|
475
|
+
// Clear all instances
|
|
476
|
+
instancedTexture.clearInstances();
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Instance Events
|
|
480
|
+
|
|
481
|
+
```javascript
|
|
482
|
+
// Add click event to specific instance
|
|
483
|
+
instancedTexture.addInstanceClickEvent(instanceId, (event) => {
|
|
484
|
+
console.log("Instance clicked!");
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
// Add hover events to specific instance
|
|
488
|
+
instancedTexture.addInstanceHoverEvent(
|
|
489
|
+
instanceId,
|
|
490
|
+
(event) => console.log("Mouse entered"),
|
|
491
|
+
(event) => console.log("Mouse left")
|
|
492
|
+
);
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
## Physics Engine
|
|
496
|
+
|
|
497
|
+
Emerald includes a comprehensive physics engine built on top of Planck.js.
|
|
498
|
+
|
|
499
|
+
### Setting up Physics
|
|
500
|
+
|
|
501
|
+
```javascript
|
|
502
|
+
import { Physics } from "./emerald/Physics";
|
|
503
|
+
|
|
504
|
+
/*
|
|
505
|
+
ARGUMENTS:
|
|
506
|
+
1. gravity: number = Gravity force (negative for downward)
|
|
507
|
+
2. scale: number = Scale factor for physics units to pixels
|
|
508
|
+
3. velocityThreshold: number = Minimum velocity threshold
|
|
509
|
+
*/
|
|
510
|
+
const physics = new Physics(-70, 32, 2);
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Physics Bodies
|
|
514
|
+
|
|
515
|
+
```javascript
|
|
516
|
+
// Get the physics body from a RigidBody component
|
|
517
|
+
const body = rigidBody.getBody();
|
|
518
|
+
|
|
519
|
+
// Set velocity
|
|
520
|
+
body.setLinearVelocity(new Vector2(10, 0));
|
|
521
|
+
|
|
522
|
+
// Get velocity
|
|
523
|
+
const velocity = body.getLinearVelocity();
|
|
524
|
+
|
|
525
|
+
// Get position
|
|
526
|
+
const position = body.getPosition();
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### Collision Detection
|
|
530
|
+
|
|
531
|
+
```javascript
|
|
532
|
+
// Handle collision enter
|
|
533
|
+
physics.onCollisionEnter((bodyA, bodyB, contact) => {
|
|
534
|
+
console.log("Collision started!");
|
|
535
|
+
|
|
536
|
+
// Get collision normal
|
|
537
|
+
const normal = contact.getWorldManifold().normal;
|
|
538
|
+
//normal.y = -1 when player is on the ground
|
|
539
|
+
//normal.y = 1 when player hits the ceiling
|
|
540
|
+
//normal.x = -1 when player hits the left wall
|
|
541
|
+
//normal.x = 1 when player hits the right wall
|
|
542
|
+
|
|
543
|
+
// Check if bodies are sensors
|
|
544
|
+
const fixtureA = contact.getFixtureA();
|
|
545
|
+
const fixtureB = contact.getFixtureB();
|
|
546
|
+
if (fixtureA.isSensor() || fixtureB.isSensor()) {
|
|
547
|
+
// Handle sensor collision
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
// Handle collision exit
|
|
552
|
+
physics.onCollisionExit((bodyA, bodyB, contact) => {
|
|
553
|
+
console.log("Collision ended!");
|
|
554
|
+
});
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Collision Events
|
|
558
|
+
|
|
559
|
+
```javascript
|
|
560
|
+
// Process physics in your update loop
|
|
561
|
+
const animate = (currentTime) => {
|
|
562
|
+
physics.process(deltaTime);
|
|
563
|
+
};
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## Particle System
|
|
567
|
+
|
|
568
|
+
Emerald includes a powerful particle system for creating visual effects.
|
|
569
|
+
|
|
570
|
+

|
|
571
|
+
|
|
572
|
+
### Particle Settings
|
|
573
|
+
|
|
574
|
+
```javascript
|
|
575
|
+
import ParticleSettings from "./emerald/particlesystem/ParticleSettings";
|
|
576
|
+
|
|
577
|
+
const particleSettings = new ParticleSettings({
|
|
578
|
+
lifetime: 1.2,
|
|
579
|
+
velocity: new Vector2(200, 300),
|
|
580
|
+
gravity: new Vector2(0, -400),
|
|
581
|
+
amount: 16,
|
|
582
|
+
direction: new Vector2(0, 1), // upward
|
|
583
|
+
spread: Math.PI * 2,
|
|
584
|
+
emissionRate: Infinity, // one-shot emission
|
|
585
|
+
frame: 0,
|
|
586
|
+
offset: 5,
|
|
587
|
+
rotation: 0,
|
|
588
|
+
scale: new Vector2(5, 5),
|
|
589
|
+
animation: { frames: [0, 1, 2], speed: 200 },
|
|
590
|
+
});
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Creating Particle Systems
|
|
594
|
+
|
|
595
|
+
```javascript
|
|
596
|
+
import Particles from "./emerald/particlesystem/Particles";
|
|
597
|
+
|
|
598
|
+
/*
|
|
599
|
+
ARGUMENTS:
|
|
600
|
+
1. name: string = Name of the particle system
|
|
601
|
+
2. texturePath: string = Path to the texture
|
|
602
|
+
3. frameWidth: number = Width of each frame
|
|
603
|
+
4. frameHeight: number = Height of each frame
|
|
604
|
+
5. framesPerRow: number = Frames per row in spritesheet
|
|
605
|
+
6. totalFrames: number = Total frames in spritesheet
|
|
606
|
+
7. duration: number = Duration of the effect
|
|
607
|
+
8. settings: ParticleSettings = Particle settings object
|
|
608
|
+
*/
|
|
609
|
+
const particles = new Particles(
|
|
610
|
+
"explosion",
|
|
611
|
+
texturePath,
|
|
612
|
+
16,
|
|
613
|
+
16,
|
|
614
|
+
9,
|
|
615
|
+
27,
|
|
616
|
+
1.2,
|
|
617
|
+
particleSettings
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
// Add to scene
|
|
621
|
+
scene.add(particles.gameObject);
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Particle System Methods
|
|
625
|
+
|
|
626
|
+
```javascript
|
|
627
|
+
// Play particle effect at position
|
|
628
|
+
particles.play(new Vector3(x, y, z));
|
|
629
|
+
|
|
630
|
+
// Stop particle system
|
|
631
|
+
particles.stop();
|
|
632
|
+
|
|
633
|
+
// Reset particle system
|
|
634
|
+
particles.reset();
|
|
635
|
+
|
|
636
|
+
// Update particles (call in your animation loop)
|
|
637
|
+
particles.update(deltaTime);
|
|
638
|
+
|
|
639
|
+
// Check if active
|
|
640
|
+
if (particles.active) {
|
|
641
|
+
// Particles are currently active
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## Lighting System
|
|
646
|
+
|
|
647
|
+
Emerald supports ambient, point, and directional lighting.
|
|
648
|
+
|
|
649
|
+
### Ambient Light
|
|
650
|
+
|
|
651
|
+
```javascript
|
|
652
|
+
// Set ambient light
|
|
653
|
+
emerald.setAmbientLight(new Vector3(0.3, 0.3, 0.3)); // RGB values 0-1
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Point Light
|
|
657
|
+
|
|
658
|
+
```javascript
|
|
659
|
+
import PointLight from "./emerald/lights/PointLight";
|
|
660
|
+
|
|
661
|
+
/*
|
|
662
|
+
ARGUMENTS:
|
|
663
|
+
1. position: Vector2 = Position of the light
|
|
664
|
+
2. color: Color = Color of the light
|
|
665
|
+
3. intensity: number = Light intensity
|
|
666
|
+
4. radius: number = Light radius
|
|
667
|
+
*/
|
|
668
|
+
const pointLight = new PointLight(
|
|
669
|
+
new Vector2(100, 0),
|
|
670
|
+
new Color(255, 204, 153),
|
|
671
|
+
1.5,
|
|
672
|
+
400
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
// Add to engine
|
|
676
|
+
emerald.addPointLight(pointLight);
|
|
677
|
+
|
|
678
|
+
// Update position
|
|
679
|
+
pointLight.position.x = newX;
|
|
680
|
+
pointLight.position.y = newY;
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
### Directional Light
|
|
684
|
+
|
|
685
|
+
```javascript
|
|
686
|
+
import DirectionalLight from "./emerald/lights/DirectionalLight";
|
|
687
|
+
|
|
688
|
+
/*
|
|
689
|
+
ARGUMENTS:
|
|
690
|
+
1. position: Vector2 = Position of the light
|
|
691
|
+
2. direction: Vector2 = Direction vector
|
|
692
|
+
3. color: Color = Color of the light
|
|
693
|
+
4. intensity: number = Light intensity
|
|
694
|
+
5. width: number = Width of the light beam
|
|
695
|
+
*/
|
|
696
|
+
const directionalLight = new DirectionalLight(
|
|
697
|
+
new Vector2(0, 300),
|
|
698
|
+
new Vector2(0, -1), // pointing down
|
|
699
|
+
new Color(255, 255, 255),
|
|
700
|
+
3.0,
|
|
701
|
+
200
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
// Add to engine
|
|
705
|
+
emerald.addDirectionalLight(directionalLight);
|
|
706
|
+
|
|
707
|
+
// Rotate direction
|
|
708
|
+
const angle = 0.1;
|
|
709
|
+
const newX =
|
|
710
|
+
directionalLight.direction.x * Math.cos(angle) -
|
|
711
|
+
directionalLight.direction.y * Math.sin(angle);
|
|
712
|
+
const newY =
|
|
713
|
+
directionalLight.direction.x * Math.sin(angle) +
|
|
714
|
+
directionalLight.direction.y * Math.cos(angle);
|
|
715
|
+
directionalLight.direction.x = newX;
|
|
716
|
+
directionalLight.direction.y = newY;
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
## Text Rendering
|
|
720
|
+
|
|
721
|
+
### BitmapText
|
|
722
|
+
|
|
723
|
+
Emerald supports bitmap font rendering using the BitmapText component. This allows you to display text with custom fonts and styles.
|
|
724
|
+
|
|
725
|
+

|
|
726
|
+
|
|
727
|
+
```javascript
|
|
728
|
+
import BitmapText from "./emerald/BitmapText";
|
|
729
|
+
|
|
730
|
+
/*
|
|
731
|
+
ARGUMENTS:
|
|
732
|
+
1. text: string = Text to display
|
|
733
|
+
2. texturePath: string = Path to bitmap font texture
|
|
734
|
+
3. letters: string = String containing all available characters
|
|
735
|
+
4. letterSpacing: number = Spacing between letters
|
|
736
|
+
5. frameWidth: number = Width of each character frame
|
|
737
|
+
6. frameHeight: number = Height of each character frame
|
|
738
|
+
7. framesPerRow: number = Characters per row in font texture
|
|
739
|
+
8. totalFrames: number = Total character frames
|
|
740
|
+
9. pixelArt: boolean = Whether to use pixel art rendering
|
|
741
|
+
10. fontSize: number = Font size
|
|
742
|
+
11. color: Color = Text color
|
|
743
|
+
12. position: Vector3 = Text position
|
|
744
|
+
13. rotation: number = Text rotation
|
|
745
|
+
14. useLighting: boolean = Whether text should react to lighting
|
|
746
|
+
*/
|
|
747
|
+
const bitmapText = new BitmapText(
|
|
748
|
+
"Hello World!",
|
|
749
|
+
fontTexturePath,
|
|
750
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.",
|
|
751
|
+
16,
|
|
752
|
+
32,
|
|
753
|
+
32,
|
|
754
|
+
10,
|
|
755
|
+
95,
|
|
756
|
+
true,
|
|
757
|
+
24,
|
|
758
|
+
new Color(255, 255, 255),
|
|
759
|
+
new Vector3(0, 200, 0),
|
|
760
|
+
0,
|
|
761
|
+
false
|
|
762
|
+
);
|
|
763
|
+
|
|
764
|
+
// Add to scene
|
|
765
|
+
scene.add(bitmapText.gameObject);
|
|
766
|
+
|
|
767
|
+
// Update text
|
|
768
|
+
bitmapText.setText("New Text!");
|
|
769
|
+
bitmapText.setColor(new Color(255, 0, 0));
|
|
770
|
+
bitmapText.setFontSize(32);
|
|
771
|
+
bitmapText.setLetterSpacing(20);
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
## EventManager
|
|
775
|
+
|
|
776
|
+
Emerald supports keyboard, mouse, click, and hover events. All events are handled using the built-in EventManager class.
|
|
777
|
+
|
|
778
|
+

|
|
779
|
+
|
|
780
|
+
```javascript
|
|
781
|
+
import EventManager from "./emerald/managers/EventManager";
|
|
782
|
+
|
|
783
|
+
let eventManager = new EventManager(canvas, scene, emerald.camera);
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
### Keyboard Events
|
|
787
|
+
|
|
788
|
+
```javascript
|
|
789
|
+
// Key down events
|
|
790
|
+
eventManager.addKeyDown("w", () => {
|
|
791
|
+
console.log("W key pressed");
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
// Key up events
|
|
795
|
+
eventManager.addKeyUp("w", () => {
|
|
796
|
+
console.log("W key released");
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
// Check if key is currently pressed
|
|
800
|
+
if (eventManager.isKeyPressed("w")) {
|
|
801
|
+
// W key is currently held down
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Remove key events
|
|
805
|
+
eventManager.removeKeyDown("w", callbackFunction);
|
|
806
|
+
eventManager.removeKeyUp("w", callbackFunction);
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
### Mouse Events
|
|
810
|
+
|
|
811
|
+
```javascript
|
|
812
|
+
// Get mouse position
|
|
813
|
+
const mousePos = eventManager.getMousePosition();
|
|
814
|
+
console.log(mousePos.x, mousePos.y);
|
|
815
|
+
|
|
816
|
+
// Check if camera was moved
|
|
817
|
+
if (eventManager.wasCameraMoved()) {
|
|
818
|
+
// Camera was moved by dragging
|
|
819
|
+
eventManager.resetCameraMoved();
|
|
820
|
+
}
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
### Object Events
|
|
824
|
+
|
|
825
|
+
```javascript
|
|
826
|
+
// Click events
|
|
827
|
+
eventManager.addClickEvent(gameObject, (event, object) => {
|
|
828
|
+
console.log("Object clicked!");
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
// Hover events
|
|
832
|
+
eventManager.addHoverEvent(
|
|
833
|
+
gameObject,
|
|
834
|
+
(event) => {
|
|
835
|
+
console.log("Mouse entered object");
|
|
836
|
+
},
|
|
837
|
+
(event) => {
|
|
838
|
+
console.log("Mouse left object");
|
|
839
|
+
}
|
|
840
|
+
);
|
|
841
|
+
|
|
842
|
+
// Remove events
|
|
843
|
+
eventManager.removeClickEvent(gameObject, callbackFunction);
|
|
844
|
+
eventManager.removeHoverEvent(gameObject, enterCallback, leaveCallback);
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
### Event Cleanup
|
|
848
|
+
|
|
849
|
+
```javascript
|
|
850
|
+
// Clean up all events when done
|
|
851
|
+
eventManager.clean();
|
|
852
|
+
|
|
853
|
+
// Change scene
|
|
854
|
+
eventManager.changeScene(newScene);
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
## AudioManager
|
|
858
|
+
|
|
859
|
+
Emerald includes a comprehensive audio management system.
|
|
860
|
+
|
|
861
|
+
### Adding Audio
|
|
862
|
+
|
|
863
|
+
```javascript
|
|
864
|
+
import AudioManager from "./emerald/managers/AudioManager";
|
|
865
|
+
|
|
866
|
+
const audioManager = new AudioManager();
|
|
867
|
+
|
|
868
|
+
// Add audio files
|
|
869
|
+
audioManager.add("path/to/sound.wav", "soundName");
|
|
870
|
+
audioManager.add("path/to/music.mp3", "backgroundMusic");
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### Playing Audio
|
|
874
|
+
|
|
875
|
+
```javascript
|
|
876
|
+
// Play audio
|
|
877
|
+
audioManager.play("soundName");
|
|
878
|
+
|
|
879
|
+
// Play exclusively (stops all other audio first)
|
|
880
|
+
audioManager.playExclusive("soundName");
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
### Audio Control
|
|
884
|
+
|
|
885
|
+
```javascript
|
|
886
|
+
// Stop specific audio
|
|
887
|
+
audioManager.stop("soundName");
|
|
888
|
+
|
|
889
|
+
// Stop all audio
|
|
890
|
+
audioManager.stopAll();
|
|
891
|
+
|
|
892
|
+
// Remove audio
|
|
893
|
+
audioManager.remove("soundName");
|
|
894
|
+
|
|
895
|
+
// Get audio object
|
|
896
|
+
const sound = audioManager.getSound("soundName");
|
|
897
|
+
```
|
|
898
|
+
|
|
899
|
+
## Camera
|
|
900
|
+
|
|
901
|
+
The engine has simple controls for the camera. The camera is stored in the emerald variable.
|
|
902
|
+
|
|
903
|
+
```javascript
|
|
904
|
+
// Set camera position
|
|
905
|
+
emerald.camera.setPosition(x, y, z);
|
|
906
|
+
|
|
907
|
+
// Access camera transform directly
|
|
908
|
+
emerald.camera.transform.position.x = 100;
|
|
909
|
+
emerald.camera.transform.position.y = 200;
|
|
910
|
+
emerald.camera.transform.scale.x = 1.5;
|
|
911
|
+
emerald.camera.transform.scale.y = 1.5;
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
## FPSCounter
|
|
915
|
+
|
|
916
|
+
Emerald has a built-in FPS counter.
|
|
917
|
+
|
|
918
|
+
```javascript
|
|
919
|
+
import { FPSCounter } from "./emerald/FPSCounter";
|
|
920
|
+
|
|
921
|
+
let fpsCounter = new FPSCounter();
|
|
922
|
+
|
|
923
|
+
const animate = (currentTime) => {
|
|
924
|
+
emerald.drawScene(scene, deltaTime);
|
|
925
|
+
fpsCounter.update(); // Call this in your animation loop
|
|
926
|
+
window.requestAnimationFrame(animate);
|
|
927
|
+
};
|
|
928
|
+
animate();
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
## Scene Management
|
|
932
|
+
|
|
933
|
+
```javascript
|
|
934
|
+
import SceneManager from "./emerald/managers/SceneManager";
|
|
935
|
+
|
|
936
|
+
// Set active scene
|
|
937
|
+
SceneManager.setScene(scene);
|
|
938
|
+
|
|
939
|
+
// Get current scene
|
|
940
|
+
const currentScene = SceneManager.getScene();
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
## Time Management
|
|
944
|
+
|
|
945
|
+
```javascript
|
|
946
|
+
import Time from "./emerald/Time";
|
|
947
|
+
|
|
948
|
+
// Get delta time
|
|
949
|
+
const deltaTime = Time.deltaTime;
|
|
950
|
+
|
|
951
|
+
// Time is automatically updated when you call emerald.drawScene()
|
|
952
|
+
// You can also manually set it
|
|
953
|
+
Time.setDeltaTime(deltaTime);
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
## Advanced Features
|
|
957
|
+
|
|
958
|
+
### Resize Handling
|
|
959
|
+
|
|
960
|
+
```javascript
|
|
961
|
+
// Handle window resize
|
|
962
|
+
const handleResize = () => {
|
|
963
|
+
const { width, height } = getCanvasDimensions();
|
|
964
|
+
emerald.resize(width, height);
|
|
965
|
+
};
|
|
966
|
+
|
|
967
|
+
window.addEventListener("resize", handleResize);
|
|
968
|
+
```
|