@energy8platform/shell 0.5.0 → 0.6.1
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/html.cjs.js +47 -6
- package/dist/html.cjs.js.map +1 -1
- package/dist/html.d.ts +34 -5
- package/dist/html.esm.js +47 -6
- package/dist/html.esm.js.map +1 -1
- package/dist/index.cjs.js +37 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +34 -5
- package/dist/index.esm.js +37 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/pixi.cjs.js +69 -10
- package/dist/pixi.cjs.js.map +1 -1
- package/dist/pixi.d.ts +34 -5
- package/dist/pixi.esm.js +69 -10
- package/dist/pixi.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ShellController.ts +29 -1
- package/src/core/renderer.ts +8 -1
- package/src/core/state.ts +10 -0
- package/src/core/types.ts +12 -1
- package/src/core/version.ts +1 -1
- package/src/ui/html/components/Settings.ts +14 -5
- package/src/ui/pixi/PixiRenderer.ts +9 -0
- package/src/ui/pixi/components/Settings.ts +23 -8
- package/src/ui/pixi/primitives/controls.ts +7 -0
package/dist/html.cjs.js
CHANGED
|
@@ -67,8 +67,17 @@ function createInitialState(config) {
|
|
|
67
67
|
freeSpins: { current: 0, total: 0, totalWin: 0 },
|
|
68
68
|
bonus: null,
|
|
69
69
|
activeFeature: null,
|
|
70
|
+
volumes: {
|
|
71
|
+
master: clampVolume(config.volumes?.master),
|
|
72
|
+
music: clampVolume(config.volumes?.music),
|
|
73
|
+
sfx: clampVolume(config.volumes?.sfx),
|
|
74
|
+
},
|
|
70
75
|
};
|
|
71
76
|
}
|
|
77
|
+
/** Clamp a configured volume to 0..1, defaulting to full (1) when unset/invalid. */
|
|
78
|
+
function clampVolume(v) {
|
|
79
|
+
return typeof v === 'number' && Number.isFinite(v) ? Math.max(0, Math.min(1, v)) : 1;
|
|
80
|
+
}
|
|
72
81
|
/** Step bet up/down within availableBets, clamped at the ends. */
|
|
73
82
|
function stepBet(state, direction) {
|
|
74
83
|
const idx = state.availableBets.indexOf(state.bet);
|
|
@@ -1439,7 +1448,7 @@ class KeyboardController {
|
|
|
1439
1448
|
|
|
1440
1449
|
// AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
|
|
1441
1450
|
/** The @energy8platform/shell package version, stamped into the game-info footer. */
|
|
1442
|
-
const PACKAGE_VERSION = '0.
|
|
1451
|
+
const PACKAGE_VERSION = '0.6.1';
|
|
1443
1452
|
|
|
1444
1453
|
/** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
|
|
1445
1454
|
function resolveConfig(config) {
|
|
@@ -1456,6 +1465,7 @@ function resolveConfig(config) {
|
|
|
1456
1465
|
features: config.features,
|
|
1457
1466
|
theme: config.theme,
|
|
1458
1467
|
onBonusBuy: config.onBonusBuy,
|
|
1468
|
+
volumes: config.volumes,
|
|
1459
1469
|
version: config.version ?? '1.0.0',
|
|
1460
1470
|
isSocial: config.isSocial ?? false,
|
|
1461
1471
|
replay: config.replay ?? config.mode === 'replay',
|
|
@@ -1477,6 +1487,7 @@ class ShellController extends EventEmitter {
|
|
|
1477
1487
|
kbd;
|
|
1478
1488
|
overlay = null;
|
|
1479
1489
|
soundRefresh = null;
|
|
1490
|
+
volumeRefresh = null;
|
|
1480
1491
|
prevBalance;
|
|
1481
1492
|
prevWin;
|
|
1482
1493
|
destroyed = false;
|
|
@@ -1660,6 +1671,7 @@ class ShellController extends EventEmitter {
|
|
|
1660
1671
|
return;
|
|
1661
1672
|
this.overlay = null;
|
|
1662
1673
|
this.soundRefresh = null;
|
|
1674
|
+
this.volumeRefresh = null;
|
|
1663
1675
|
this.renderer.closeOverlay();
|
|
1664
1676
|
}
|
|
1665
1677
|
// ── sound ──────────────────────────────────────────────────────────────────
|
|
@@ -1672,6 +1684,22 @@ class ShellController extends EventEmitter {
|
|
|
1672
1684
|
setSoundRefresh(fn) {
|
|
1673
1685
|
this.soundRefresh = fn;
|
|
1674
1686
|
}
|
|
1687
|
+
// ── volume ─────────────────────────────────────────────────────────────────
|
|
1688
|
+
getVolume(key) {
|
|
1689
|
+
return this.state.volumes[key];
|
|
1690
|
+
}
|
|
1691
|
+
/** Set a volume slider (0..1). Shared by the slider control (drag) and game code (public API):
|
|
1692
|
+
* clamps, stores so a reopened Settings overlay reflects it, emits `settingChange`, and
|
|
1693
|
+
* live-updates the slider if the overlay is currently open. */
|
|
1694
|
+
setVolume(key, value) {
|
|
1695
|
+
const v = Math.max(0, Math.min(1, value));
|
|
1696
|
+
this.state.volumes[key] = v;
|
|
1697
|
+
this.emit('settingChange', { key, value: v });
|
|
1698
|
+
this.volumeRefresh?.(key, v);
|
|
1699
|
+
}
|
|
1700
|
+
setVolumeRefresh(fn) {
|
|
1701
|
+
this.volumeRefresh = fn;
|
|
1702
|
+
}
|
|
1675
1703
|
// ── features ─────────────────────────────────────────────────────────────────
|
|
1676
1704
|
activateFeature(bonus) {
|
|
1677
1705
|
this.state.activeFeature = bonus;
|
|
@@ -1698,10 +1726,17 @@ class ShellController extends EventEmitter {
|
|
|
1698
1726
|
this.prevBalance = n;
|
|
1699
1727
|
this.money('balance', from, n);
|
|
1700
1728
|
}
|
|
1701
|
-
|
|
1729
|
+
/** Set the WIN readout. Counts up/down from the previous value by default. Pass
|
|
1730
|
+
* `{ animate: false }` to SNAP instantly (renderBar cancels any in-flight count-up) — used by the
|
|
1731
|
+
* host to clear WIN to 0 at spin start, where an animated count-DOWN would look wrong. */
|
|
1732
|
+
setWin(n, opts) {
|
|
1702
1733
|
const from = this.prevWin;
|
|
1703
1734
|
this.state.win = n;
|
|
1704
1735
|
this.prevWin = n;
|
|
1736
|
+
if (opts?.animate === false) {
|
|
1737
|
+
this.renderer.renderBar(); // instant repaint from state; cancels running money anims
|
|
1738
|
+
return;
|
|
1739
|
+
}
|
|
1705
1740
|
this.money('win', from, n);
|
|
1706
1741
|
}
|
|
1707
1742
|
setBet(n) {
|
|
@@ -2829,7 +2864,10 @@ function openSettingsModal(host) {
|
|
|
2829
2864
|
return row;
|
|
2830
2865
|
})();
|
|
2831
2866
|
body.appendChild(sound);
|
|
2832
|
-
// Volume sliders — full-width column rows with a live value readout
|
|
2867
|
+
// Volume sliders — full-width column rows with a live value readout. Positions are read from the
|
|
2868
|
+
// shell's stored volumes (not hardcoded to 100%), so reopening the overlay reflects the last set
|
|
2869
|
+
// value, and `host.setVolume()` from game code updates them live via the registered refreshers.
|
|
2870
|
+
const updaters = {};
|
|
2833
2871
|
const slider = (key, label) => {
|
|
2834
2872
|
const row = document.createElement('div');
|
|
2835
2873
|
row.className = 'ge-ov-row ge-col';
|
|
@@ -2837,7 +2875,6 @@ function openSettingsModal(host) {
|
|
|
2837
2875
|
head.className = 'ge-row-head';
|
|
2838
2876
|
const val = document.createElement('span');
|
|
2839
2877
|
val.className = 'ge-val';
|
|
2840
|
-
val.textContent = '100%';
|
|
2841
2878
|
head.innerHTML = `<span>${label}</span>`;
|
|
2842
2879
|
head.appendChild(val);
|
|
2843
2880
|
const input = document.createElement('input');
|
|
@@ -2845,19 +2882,23 @@ function openSettingsModal(host) {
|
|
|
2845
2882
|
input.min = '0';
|
|
2846
2883
|
input.max = '1';
|
|
2847
2884
|
input.step = '0.05';
|
|
2848
|
-
input.value = '1';
|
|
2849
2885
|
input.className = 'ge-slider';
|
|
2850
2886
|
input.dataset.ge = `setting-${key}`;
|
|
2887
|
+
const paint = (v) => { input.value = String(v); val.textContent = `${Math.round(v * 100)}%`; };
|
|
2888
|
+
paint(host.getVolume(key));
|
|
2851
2889
|
input.addEventListener('input', () => {
|
|
2852
2890
|
val.textContent = `${Math.round(Number(input.value) * 100)}%`;
|
|
2853
|
-
host.
|
|
2891
|
+
host.setVolume(key, Number(input.value));
|
|
2854
2892
|
});
|
|
2893
|
+
updaters[key] = paint;
|
|
2855
2894
|
row.append(head, input);
|
|
2856
2895
|
return row;
|
|
2857
2896
|
};
|
|
2858
2897
|
body.appendChild(slider('master', host.t('Master volume')));
|
|
2859
2898
|
body.appendChild(slider('music', host.t('Music')));
|
|
2860
2899
|
body.appendChild(slider('sfx', host.t('SFX')));
|
|
2900
|
+
// Live-update sliders when volume changes via host.setVolume (shell clears on close).
|
|
2901
|
+
host.setVolumeRefresh((key, v) => updaters[key]?.(v));
|
|
2861
2902
|
// Game info — full-width row button that opens its own overlay
|
|
2862
2903
|
const gameInfo = document.createElement('button');
|
|
2863
2904
|
gameInfo.className = 'ge-ov-row';
|