cubeforge 0.3.11 → 0.3.13
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/dist/index.js +27 -16
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ var ECSWorld = class {
|
|
|
9
9
|
// Seeded RNG (LCG) for deterministic mode
|
|
10
10
|
_rngState = 0;
|
|
11
11
|
_deterministic = false;
|
|
12
|
+
/** Asset manager reference — set by Game, available in Script callbacks via world.assets */
|
|
13
|
+
assets;
|
|
12
14
|
// Primary storage: archetypes keyed by sorted type string
|
|
13
15
|
archetypes = /* @__PURE__ */ new Map();
|
|
14
16
|
// Which archetype each entity lives in
|
|
@@ -343,6 +345,11 @@ var AssetManager = class {
|
|
|
343
345
|
_loaded = 0;
|
|
344
346
|
_total = 0;
|
|
345
347
|
_progressListeners = /* @__PURE__ */ new Set();
|
|
348
|
+
/** Base URL prefix applied to all asset paths starting with '/'. Set by Game component. */
|
|
349
|
+
baseURL = "";
|
|
350
|
+
resolve(src) {
|
|
351
|
+
return this.baseURL && src.startsWith("/") ? this.baseURL + src : src;
|
|
352
|
+
}
|
|
346
353
|
getAudioContext() {
|
|
347
354
|
if (!this.audioCtx) {
|
|
348
355
|
this.audioCtx = new AudioContext();
|
|
@@ -371,28 +378,29 @@ var AssetManager = class {
|
|
|
371
378
|
return () => this._progressListeners.delete(cb);
|
|
372
379
|
}
|
|
373
380
|
async loadImage(src) {
|
|
374
|
-
|
|
381
|
+
const resolved = this.resolve(src);
|
|
382
|
+
if (this.imagePromises.has(resolved)) return this.imagePromises.get(resolved);
|
|
375
383
|
this._total++;
|
|
376
384
|
this.emitProgress();
|
|
377
385
|
const promise = (async () => {
|
|
378
386
|
const img = new Image();
|
|
379
|
-
img.src =
|
|
387
|
+
img.src = resolved;
|
|
380
388
|
try {
|
|
381
389
|
await new Promise((resolve, reject) => {
|
|
382
390
|
img.onload = () => resolve();
|
|
383
391
|
img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
|
|
384
392
|
});
|
|
385
393
|
} catch (err) {
|
|
386
|
-
console.warn(`[Cubeforge] Failed to load image: ${
|
|
394
|
+
console.warn(`[Cubeforge] Failed to load image: ${resolved}`);
|
|
387
395
|
throw err;
|
|
388
396
|
} finally {
|
|
389
397
|
this._loaded++;
|
|
390
398
|
this.emitProgress();
|
|
391
399
|
}
|
|
392
|
-
this.images.set(
|
|
400
|
+
this.images.set(resolved, img);
|
|
393
401
|
return img;
|
|
394
402
|
})();
|
|
395
|
-
this.imagePromises.set(
|
|
403
|
+
this.imagePromises.set(resolved, promise);
|
|
396
404
|
return promise;
|
|
397
405
|
}
|
|
398
406
|
/** Resolves once every image that has been requested via loadImage() is settled. */
|
|
@@ -400,23 +408,24 @@ var AssetManager = class {
|
|
|
400
408
|
await Promise.allSettled([...this.imagePromises.values()]);
|
|
401
409
|
}
|
|
402
410
|
getImage(src) {
|
|
403
|
-
return this.images.get(src);
|
|
411
|
+
return this.images.get(this.resolve(src));
|
|
404
412
|
}
|
|
405
413
|
/** Returns a read-only snapshot of all loaded images keyed by src. */
|
|
406
414
|
getLoadedImages() {
|
|
407
415
|
return this.images;
|
|
408
416
|
}
|
|
409
417
|
async loadAudio(src) {
|
|
410
|
-
|
|
418
|
+
const resolved = this.resolve(src);
|
|
419
|
+
if (this.audio.has(resolved)) return this.audio.get(resolved);
|
|
411
420
|
const ctx = this.getAudioContext();
|
|
412
421
|
try {
|
|
413
|
-
const response = await fetch(
|
|
422
|
+
const response = await fetch(resolved);
|
|
414
423
|
const arrayBuffer = await response.arrayBuffer();
|
|
415
424
|
const audioBuffer = await ctx.decodeAudioData(arrayBuffer);
|
|
416
|
-
this.audio.set(
|
|
425
|
+
this.audio.set(resolved, audioBuffer);
|
|
417
426
|
return audioBuffer;
|
|
418
427
|
} catch (err) {
|
|
419
|
-
console.warn(`[Cubeforge] Failed to load audio: ${
|
|
428
|
+
console.warn(`[Cubeforge] Failed to load audio: ${resolved}`);
|
|
420
429
|
throw err;
|
|
421
430
|
}
|
|
422
431
|
}
|
|
@@ -3884,6 +3893,9 @@ function Game({
|
|
|
3884
3893
|
const input = new InputManager();
|
|
3885
3894
|
const events = new EventBus();
|
|
3886
3895
|
const assets = new AssetManager();
|
|
3896
|
+
const viteEnv = import.meta.env;
|
|
3897
|
+
assets.baseURL = (viteEnv?.BASE_URL ?? "/").replace(/\/$/, "");
|
|
3898
|
+
ecs.assets = assets;
|
|
3887
3899
|
const physics = new PhysicsSystem(gravity, events);
|
|
3888
3900
|
const entityIds = /* @__PURE__ */ new Map();
|
|
3889
3901
|
const renderSystem = new RenderSystem(canvas, entityIds);
|
|
@@ -4210,13 +4222,12 @@ function Sprite({
|
|
|
4210
4222
|
});
|
|
4211
4223
|
engine.ecs.addComponent(entityId, comp);
|
|
4212
4224
|
if (src) {
|
|
4213
|
-
|
|
4214
|
-
const base = (viteEnv?.BASE_URL ?? "/").replace(/\/$/, "");
|
|
4215
|
-
const resolvedSrc = base && src.startsWith("/") ? base + src : src;
|
|
4216
|
-
comp.src = resolvedSrc;
|
|
4217
|
-
engine.assets.loadImage(resolvedSrc).then((img) => {
|
|
4225
|
+
engine.assets.loadImage(src).then((img) => {
|
|
4218
4226
|
const c = engine.ecs.getComponent(entityId, "Sprite");
|
|
4219
|
-
if (c)
|
|
4227
|
+
if (c) {
|
|
4228
|
+
c.image = img;
|
|
4229
|
+
c.src = img.src;
|
|
4230
|
+
}
|
|
4220
4231
|
}).catch(console.error);
|
|
4221
4232
|
}
|
|
4222
4233
|
return () => engine.ecs.removeComponent(entityId, "Sprite");
|