emeraldengine 2.2.1 → 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.
- package/README.md +2359 -968
- package/dist/types/index.d.ts +72 -32
- package/dist/types/src/Animator.d.ts +50 -0
- package/dist/types/{BitmapText.d.ts → src/BitmapText.d.ts} +19 -21
- package/dist/types/src/Camera.d.ts +122 -0
- package/dist/types/src/CameraController.d.ts +107 -0
- package/dist/types/src/CanvasText.d.ts +91 -0
- package/dist/types/src/CollisionLayers.d.ts +58 -0
- package/dist/types/{Color.d.ts → src/Color.d.ts} +5 -6
- package/dist/types/src/Coroutine.d.ts +111 -0
- package/dist/types/src/DebugOverlay.d.ts +86 -0
- package/dist/types/src/Drawable.d.ts +271 -0
- package/dist/types/src/Easing.d.ts +22 -0
- package/dist/types/src/Emerald.d.ts +420 -0
- package/dist/types/src/EmeraldDB.d.ts +159 -0
- package/dist/types/{FPSCounter.d.ts → src/FPSCounter.d.ts} +1 -3
- package/dist/types/src/GLUtils.d.ts +4 -0
- package/dist/types/{Instance.d.ts → src/Instance.d.ts} +37 -15
- package/dist/types/{InstancedTexture.d.ts → src/InstancedTexture.d.ts} +60 -23
- package/dist/types/src/Interpolator.d.ts +66 -0
- package/dist/types/src/Material.d.ts +87 -0
- package/dist/types/src/MathUtils.d.ts +80 -0
- package/dist/types/src/ParticleEmitter.d.ts +131 -0
- package/dist/types/{Physics.d.ts → src/Physics.d.ts} +88 -20
- package/dist/types/src/Pool.d.ts +53 -0
- package/dist/types/src/PostEffects.d.ts +68 -0
- package/dist/types/src/PostProcessor.d.ts +124 -0
- package/dist/types/src/RenderTarget.d.ts +56 -0
- package/dist/types/src/Scene.d.ts +62 -0
- package/dist/types/src/ScreenEffects.d.ts +111 -0
- package/dist/types/src/Serializer.d.ts +86 -0
- package/dist/types/src/Shaders.d.ts +2 -0
- package/dist/types/{Shapes.d.ts → src/Shapes.d.ts} +4 -6
- package/dist/types/src/SpatialGrid.d.ts +50 -0
- package/dist/types/src/SpriteBatch.d.ts +89 -0
- package/dist/types/src/StateMachine.d.ts +59 -0
- package/dist/types/src/Storage.d.ts +89 -0
- package/dist/types/{Texture.d.ts → src/Texture.d.ts} +3 -4
- package/dist/types/src/TextureAtlas.d.ts +55 -0
- package/dist/types/src/Tilemap.d.ts +91 -0
- package/dist/types/src/Time.d.ts +53 -0
- package/dist/types/src/Timer.d.ts +54 -0
- package/dist/types/src/Transform.d.ts +94 -0
- package/dist/types/src/Tween.d.ts +81 -0
- package/dist/types/src/UI.d.ts +121 -0
- package/dist/types/src/components/Behaviour.d.ts +71 -0
- package/dist/types/{components → src/components}/BoxCollider.d.ts +14 -14
- package/dist/types/src/components/BoxColliderDebug.d.ts +15 -0
- package/dist/types/{components → src/components}/CircleCollider.d.ts +14 -12
- package/dist/types/src/components/CircleColliderDebug.d.ts +15 -0
- package/dist/types/src/components/Collider.d.ts +96 -0
- package/dist/types/src/components/GameObject.d.ts +135 -0
- package/dist/types/src/components/RigidBody.d.ts +183 -0
- package/dist/types/src/importers/Aseprite.d.ts +79 -0
- package/dist/types/src/importers/TiledMap.d.ts +62 -0
- package/dist/types/{lights → src/lights}/DirectionalLight.d.ts +7 -9
- package/dist/types/{lights → src/lights}/PointLight.d.ts +6 -9
- package/dist/types/src/managers/AssetManager.d.ts +116 -0
- package/dist/types/src/managers/AudioManager.d.ts +259 -0
- package/dist/types/{managers → src/managers}/CameraManager.d.ts +8 -8
- package/dist/types/{managers → src/managers}/EventManager.d.ts +46 -32
- package/dist/types/src/managers/GLManager.d.ts +84 -0
- package/dist/types/src/managers/GLState.d.ts +37 -0
- package/dist/types/src/managers/IDManager.d.ts +31 -0
- package/dist/types/src/managers/InputManager.d.ts +290 -0
- package/dist/types/src/managers/NetworkManager.d.ts +93 -0
- package/dist/types/src/managers/RenderStats.d.ts +34 -0
- package/dist/types/src/managers/SceneManager.d.ts +44 -0
- package/dist/types/src/managers/ShaderManager.d.ts +55 -0
- package/dist/types/src/managers/TextureManager.d.ts +102 -0
- package/dist/types/src/particlesystem/Particle.d.ts +64 -0
- package/dist/types/{particlesystem → src/particlesystem}/ParticleSettings.d.ts +32 -24
- package/dist/types/{particlesystem → src/particlesystem}/Particles.d.ts +20 -12
- package/index.js +72 -0
- package/package.json +74 -60
- package/src/Animator.js +95 -0
- package/src/BitmapText.js +6 -5
- package/src/Camera.js +183 -0
- package/src/CameraController.js +192 -0
- package/src/CanvasText.js +281 -0
- package/src/CollisionLayers.js +86 -0
- package/src/Color.js +18 -18
- package/src/Coroutine.js +259 -0
- package/src/DebugOverlay.js +246 -0
- package/src/Drawable.js +842 -582
- package/src/Easing.js +57 -0
- package/src/Emerald.js +1150 -459
- package/src/EmeraldDB.js +328 -0
- package/src/FPSCounter.js +43 -43
- package/src/GLUtils.js +60 -67
- package/src/Instance.js +41 -5
- package/src/InstancedTexture.js +251 -118
- package/src/Interpolator.js +124 -0
- package/src/Material.js +202 -0
- package/src/MathUtils.js +133 -0
- package/src/ParticleEmitter.js +284 -0
- package/src/Physics.js +186 -5
- package/src/Pool.js +85 -0
- package/src/PostEffects.js +296 -0
- package/src/PostProcessor.js +304 -0
- package/src/RenderTarget.js +134 -0
- package/src/Scene.js +115 -83
- package/src/ScreenEffects.js +266 -0
- package/src/Serializer.js +131 -0
- package/src/Shaders.js +150 -165
- package/src/Shapes.js +118 -129
- package/src/SpatialGrid.js +111 -0
- package/src/SpriteBatch.js +299 -0
- package/src/StateMachine.js +82 -0
- package/src/Storage.js +175 -47
- package/src/Texture.js +58 -67
- package/src/TextureAtlas.js +96 -0
- package/src/Tilemap.js +274 -0
- package/src/Time.js +51 -6
- package/src/Timer.js +99 -0
- package/src/Transform.js +100 -7
- package/src/Tween.js +160 -0
- package/src/UI.js +394 -0
- package/src/components/Behaviour.js +90 -0
- package/src/components/BoxCollider.js +22 -3
- package/src/components/CircleCollider.js +19 -3
- package/src/components/CircleColliderDebug.js +24 -24
- package/src/components/Collider.js +140 -34
- package/src/components/GameObject.js +130 -21
- package/src/components/RigidBody.js +123 -2
- package/src/importers/Aseprite.js +142 -0
- package/src/importers/TiledMap.js +158 -0
- package/src/lights/DirectionalLight.js +6 -15
- package/src/lights/PointLight.js +4 -4
- package/src/managers/AssetManager.js +239 -0
- package/src/managers/AudioManager.js +565 -146
- package/src/managers/EventManager.js +488 -477
- package/src/managers/GLManager.js +57 -0
- package/src/managers/GLState.js +70 -0
- package/src/managers/IDManager.js +24 -2
- package/src/managers/InputManager.js +779 -0
- package/src/managers/NetworkManager.js +178 -0
- package/src/managers/RenderStats.js +34 -0
- package/src/managers/SceneManager.js +30 -0
- package/src/managers/ShaderManager.js +0 -2
- package/src/managers/TextureManager.js +218 -0
- package/src/particlesystem/Particle.js +82 -7
- package/src/particlesystem/ParticleSettings.js +21 -3
- package/src/particlesystem/Particles.js +80 -31
- package/dist/types/Drawable.d.ts +0 -157
- package/dist/types/Emerald.d.ts +0 -73
- package/dist/types/GLUtils.d.ts +0 -6
- package/dist/types/Scene.d.ts +0 -39
- package/dist/types/Shaders.d.ts +0 -4
- package/dist/types/Storage.d.ts +0 -46
- package/dist/types/Time.d.ts +0 -22
- package/dist/types/Transform.d.ts +0 -41
- package/dist/types/components/BoxColliderDebug.d.ts +0 -19
- package/dist/types/components/CircleColliderDebug.d.ts +0 -19
- package/dist/types/components/Collider.d.ts +0 -53
- package/dist/types/components/GameObject.d.ts +0 -72
- package/dist/types/components/RigidBody.d.ts +0 -104
- package/dist/types/managers/AudioManager.d.ts +0 -60
- package/dist/types/managers/GLManager.d.ts +0 -47
- package/dist/types/managers/IDManager.d.ts +0 -21
- package/dist/types/managers/SceneManager.d.ts +0 -22
- 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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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;
|