@combos-fun/engine 0.0.37 → 0.0.39
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/engine.cjs.js +204 -3
- package/dist/engine.cjs.js.map +1 -1
- package/dist/engine.cjs.prod.js +1 -1
- package/dist/engine.d.ts +76 -3
- package/dist/engine.esm.js +203 -4
- package/dist/engine.esm.js.map +1 -1
- package/package.json +7 -3
- package/references/bootstrap-examples.md +0 -2
- package/references/public-api.md +1 -1
package/dist/engine.cjs.js
CHANGED
|
@@ -1001,7 +1001,7 @@ class Scene extends GameObject {
|
|
|
1001
1001
|
}
|
|
1002
1002
|
|
|
1003
1003
|
/** Generated at build from package.json */
|
|
1004
|
-
const version = "0.0.
|
|
1004
|
+
const version = "0.0.39";
|
|
1005
1005
|
|
|
1006
1006
|
/**
|
|
1007
1007
|
* Sent to `window.parent` after each `System.init` completes during `Game.addSystem`
|
|
@@ -1642,6 +1642,105 @@ class Progress extends EventEmitter__default.default {
|
|
|
1642
1642
|
}
|
|
1643
1643
|
}
|
|
1644
1644
|
|
|
1645
|
+
const SLOT_DEFAULT_TYPE = {
|
|
1646
|
+
image: 'png',
|
|
1647
|
+
json: 'json',
|
|
1648
|
+
tex: 'tex',
|
|
1649
|
+
ske: 'ske',
|
|
1650
|
+
audio: 'audio',
|
|
1651
|
+
video: 'video',
|
|
1652
|
+
};
|
|
1653
|
+
const EXT_TO_TYPE = {
|
|
1654
|
+
png: 'png',
|
|
1655
|
+
jpg: 'jpg',
|
|
1656
|
+
jpeg: 'jpeg',
|
|
1657
|
+
webp: 'webp',
|
|
1658
|
+
json: 'json',
|
|
1659
|
+
tex: 'tex',
|
|
1660
|
+
ske: 'ske',
|
|
1661
|
+
mp3: 'audio',
|
|
1662
|
+
wav: 'audio',
|
|
1663
|
+
aac: 'audio',
|
|
1664
|
+
ogg: 'audio',
|
|
1665
|
+
mp4: 'video',
|
|
1666
|
+
webm: 'video',
|
|
1667
|
+
glb: 'glb',
|
|
1668
|
+
gltf: 'gltf',
|
|
1669
|
+
};
|
|
1670
|
+
function extensionOf(url) {
|
|
1671
|
+
const path = url.split('?')[0].split('#')[0];
|
|
1672
|
+
const dot = path.lastIndexOf('.');
|
|
1673
|
+
if (dot < 0)
|
|
1674
|
+
return '';
|
|
1675
|
+
return path.slice(dot + 1).toLowerCase();
|
|
1676
|
+
}
|
|
1677
|
+
function typeFromUrl(url, slot) {
|
|
1678
|
+
return EXT_TO_TYPE[extensionOf(url)] || SLOT_DEFAULT_TYPE[slot] || 'png';
|
|
1679
|
+
}
|
|
1680
|
+
function defaultSlotForResourceType(resourceType) {
|
|
1681
|
+
if (resourceType === 'AUDIO')
|
|
1682
|
+
return 'audio';
|
|
1683
|
+
if (resourceType === 'VIDEO')
|
|
1684
|
+
return 'video';
|
|
1685
|
+
return 'image';
|
|
1686
|
+
}
|
|
1687
|
+
function wrapSlot(slot, value, resourceName) {
|
|
1688
|
+
if (typeof value === 'string') {
|
|
1689
|
+
const url = value.trim();
|
|
1690
|
+
if (!url) {
|
|
1691
|
+
throw missingUrlError(resourceName, slot);
|
|
1692
|
+
}
|
|
1693
|
+
return { type: typeFromUrl(url, slot), url };
|
|
1694
|
+
}
|
|
1695
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1696
|
+
throw new Error(`Resource "${resourceName}" src.${slot} must be a url string or { type, url }.`);
|
|
1697
|
+
}
|
|
1698
|
+
const slotValue = value;
|
|
1699
|
+
if (slotValue.type === 'data') {
|
|
1700
|
+
return slotValue;
|
|
1701
|
+
}
|
|
1702
|
+
const url = typeof slotValue.url === 'string' ? slotValue.url.trim() : '';
|
|
1703
|
+
if (!url) {
|
|
1704
|
+
throw missingUrlError(resourceName, slot);
|
|
1705
|
+
}
|
|
1706
|
+
return {
|
|
1707
|
+
...slotValue,
|
|
1708
|
+
type: slotValue.type || typeFromUrl(url, slot),
|
|
1709
|
+
url,
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
function missingUrlError(resourceName, slot) {
|
|
1713
|
+
return new Error(`Resource "${resourceName}" src.${slot}.url is required. ` +
|
|
1714
|
+
`Use { type, url } (e.g. { type: "webp", url: "https://..." }). ` +
|
|
1715
|
+
`A flat path string is also accepted and will be normalized.`);
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* Accept the documented `{ type, url }` slots, plus the common guesses
|
|
1719
|
+
* `src: "file.png"` and `src: { image: "a.webp", json: "a.json" }`.
|
|
1720
|
+
*/
|
|
1721
|
+
function normalizeResourceSrc(src, resourceType, resourceName = '(unnamed)') {
|
|
1722
|
+
if (src == null) {
|
|
1723
|
+
throw new Error(`Resource "${resourceName}" src is required.`);
|
|
1724
|
+
}
|
|
1725
|
+
if (typeof src === 'string') {
|
|
1726
|
+
const slot = defaultSlotForResourceType(resourceType);
|
|
1727
|
+
return { [slot]: wrapSlot(slot, src, resourceName) };
|
|
1728
|
+
}
|
|
1729
|
+
if (typeof src !== 'object' || Array.isArray(src)) {
|
|
1730
|
+
throw new Error(`Resource "${resourceName}" src must be a url string or a slot object.`);
|
|
1731
|
+
}
|
|
1732
|
+
const out = {};
|
|
1733
|
+
for (const [slot, value] of Object.entries(src)) {
|
|
1734
|
+
if (value == null)
|
|
1735
|
+
continue;
|
|
1736
|
+
out[slot] = wrapSlot(slot, value, resourceName);
|
|
1737
|
+
}
|
|
1738
|
+
if (Object.keys(out).length === 0) {
|
|
1739
|
+
throw new Error(`Resource "${resourceName}" src has no loadable slots.`);
|
|
1740
|
+
}
|
|
1741
|
+
return out;
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1645
1744
|
const resourceLoader = {
|
|
1646
1745
|
AbstractLoadStrategy: resourceLoader$1.AbstractLoadStrategy,
|
|
1647
1746
|
AudioLoadStrategy: resourceLoader$1.AudioLoadStrategy,
|
|
@@ -1656,6 +1755,102 @@ const resourceLoader = {
|
|
|
1656
1755
|
ResourceState: resourceLoader$1.ResourceState
|
|
1657
1756
|
};
|
|
1658
1757
|
|
|
1758
|
+
function isFrameMap(frames) {
|
|
1759
|
+
return !!frames && typeof frames === 'object' && !Array.isArray(frames);
|
|
1760
|
+
}
|
|
1761
|
+
function frameFromPackedItem(item) {
|
|
1762
|
+
const frame = item.frame;
|
|
1763
|
+
if (!frame || typeof frame !== 'object')
|
|
1764
|
+
return null;
|
|
1765
|
+
return {
|
|
1766
|
+
...item,
|
|
1767
|
+
frame: frame,
|
|
1768
|
+
rotated: Boolean(item.rotated),
|
|
1769
|
+
trimmed: Boolean(item.trimmed),
|
|
1770
|
+
spriteSourceSize: item.spriteSourceSize,
|
|
1771
|
+
sourceSize: item.sourceSize,
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
function collectArrayFrames(list, frames, animations) {
|
|
1775
|
+
for (const raw of list) {
|
|
1776
|
+
if (!raw || typeof raw !== 'object')
|
|
1777
|
+
continue;
|
|
1778
|
+
const item = raw;
|
|
1779
|
+
const name = String(item.filename || item.name || '');
|
|
1780
|
+
if (!name)
|
|
1781
|
+
continue;
|
|
1782
|
+
const packed = frameFromPackedItem(item);
|
|
1783
|
+
if (!packed)
|
|
1784
|
+
continue;
|
|
1785
|
+
frames[name] = packed;
|
|
1786
|
+
const slash = name.lastIndexOf('/');
|
|
1787
|
+
if (slash > 0) {
|
|
1788
|
+
const anim = name.slice(0, slash);
|
|
1789
|
+
if (!animations[anim])
|
|
1790
|
+
animations[anim] = [];
|
|
1791
|
+
if (!animations[anim].includes(name))
|
|
1792
|
+
animations[anim].push(name);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
/**
|
|
1797
|
+
* Pixi `Spritesheet` reads `data.meta.scale` and a name→frame `frames` map.
|
|
1798
|
+
* TexturePacker multi-atlas (`textures[].frames` as an array) is accepted and
|
|
1799
|
+
* rewritten to that hash. Always returns a `meta.scale` so construction cannot
|
|
1800
|
+
* throw `Cannot read properties of undefined (reading 'scale')`.
|
|
1801
|
+
*/
|
|
1802
|
+
function normalizeSpritesheetData(raw) {
|
|
1803
|
+
if (!raw || typeof raw !== 'object') {
|
|
1804
|
+
return { frames: {}, animations: {}, meta: { scale: 1 } };
|
|
1805
|
+
}
|
|
1806
|
+
const json = raw;
|
|
1807
|
+
if (isFrameMap(json.frames)) {
|
|
1808
|
+
return {
|
|
1809
|
+
...json,
|
|
1810
|
+
frames: json.frames,
|
|
1811
|
+
animations: { ...(json.animations || {}) },
|
|
1812
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
const frames = {};
|
|
1816
|
+
const animations = { ...(json.animations || {}) };
|
|
1817
|
+
if (Array.isArray(json.textures)) {
|
|
1818
|
+
for (const sheet of json.textures) {
|
|
1819
|
+
if (!sheet || typeof sheet !== 'object')
|
|
1820
|
+
continue;
|
|
1821
|
+
if (Array.isArray(sheet.frames)) {
|
|
1822
|
+
collectArrayFrames(sheet.frames, frames, animations);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
const first = json.textures[0] || {};
|
|
1826
|
+
const scale = first.scale ?? json.meta?.scale ?? 1;
|
|
1827
|
+
return {
|
|
1828
|
+
frames,
|
|
1829
|
+
animations,
|
|
1830
|
+
meta: {
|
|
1831
|
+
scale: typeof scale === 'number' || typeof scale === 'string' ? scale : 1,
|
|
1832
|
+
image: typeof first.image === 'string' ? first.image : undefined,
|
|
1833
|
+
size: first.size,
|
|
1834
|
+
format: first.format,
|
|
1835
|
+
...(json.meta || {}),
|
|
1836
|
+
},
|
|
1837
|
+
};
|
|
1838
|
+
}
|
|
1839
|
+
if (Array.isArray(json.frames)) {
|
|
1840
|
+
collectArrayFrames(json.frames, frames, animations);
|
|
1841
|
+
return {
|
|
1842
|
+
frames,
|
|
1843
|
+
animations,
|
|
1844
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
return {
|
|
1848
|
+
frames: {},
|
|
1849
|
+
animations,
|
|
1850
|
+
meta: { scale: 1, ...(json.meta || {}) },
|
|
1851
|
+
};
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1659
1854
|
/** Resource type */
|
|
1660
1855
|
exports.RESOURCE_TYPE = void 0;
|
|
1661
1856
|
(function (RESOURCE_TYPE) {
|
|
@@ -1733,8 +1928,11 @@ class Resource extends EventEmitter__default.default {
|
|
|
1733
1928
|
console.warn(res.name + ' was already added');
|
|
1734
1929
|
continue;
|
|
1735
1930
|
}
|
|
1736
|
-
this.resourcesMap[res.name] =
|
|
1737
|
-
|
|
1931
|
+
this.resourcesMap[res.name] = {
|
|
1932
|
+
...res,
|
|
1933
|
+
src: normalizeResourceSrc(res.src, String(res.type), res.name),
|
|
1934
|
+
data: {},
|
|
1935
|
+
};
|
|
1738
1936
|
}
|
|
1739
1937
|
}
|
|
1740
1938
|
/** dd resource preprocesser*/
|
|
@@ -1823,6 +2021,7 @@ class Resource extends EventEmitter__default.default {
|
|
|
1823
2021
|
for (const handler of this.preProcessResourceHandlers) {
|
|
1824
2022
|
handler(res);
|
|
1825
2023
|
}
|
|
2024
|
+
res.src = normalizeResourceSrc(res.src, String(res.type), res.name);
|
|
1826
2025
|
for (const key in res.src) {
|
|
1827
2026
|
const resourceType = res.src[key].type;
|
|
1828
2027
|
if (resourceType === 'data') {
|
|
@@ -1949,6 +2148,8 @@ exports.componentObserver = componentObserver;
|
|
|
1949
2148
|
exports.decorators = decorators;
|
|
1950
2149
|
exports.isAllowedMessageOrigin = isAllowedMessageOrigin;
|
|
1951
2150
|
exports.mergeAllowedMessageOrigins = mergeAllowedMessageOrigins;
|
|
2151
|
+
exports.normalizeResourceSrc = normalizeResourceSrc;
|
|
2152
|
+
exports.normalizeSpritesheetData = normalizeSpritesheetData;
|
|
1952
2153
|
exports.parseSetPlayingMessage = parseSetPlayingMessage;
|
|
1953
2154
|
exports.postParentGameReady = postParentGameReady;
|
|
1954
2155
|
exports.postParentGameState = postParentGameState;
|