@rpgjs/map-builder 0.0.0-stage → 5.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/LICENSE +19 -0
- package/README.md +341 -2
- package/dist/authority/authority.d.ts +118 -0
- package/dist/authority/authority.d.ts.map +1 -0
- package/dist/authority/authority.js +289 -0
- package/dist/authority/authority.js.map +1 -0
- package/dist/authority/index.d.ts +3 -0
- package/dist/authority/index.d.ts.map +1 -0
- package/dist/authority/index.js +3 -0
- package/dist/authority/store.d.ts +36 -0
- package/dist/authority/store.d.ts.map +1 -0
- package/dist/authority/store.js +35 -0
- package/dist/authority/store.js.map +1 -0
- package/dist/client/index.d.ts +72 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +200 -0
- package/dist/client/index.js.map +1 -0
- package/dist/embed/client.d.ts +85 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +255 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +112 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +278 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +4 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +4 -0
- package/dist/embed/protocol.d.ts +137 -0
- package/dist/embed/protocol.d.ts.map +1 -0
- package/dist/embed/protocol.js +161 -0
- package/dist/embed/protocol.js.map +1 -0
- package/dist/features/index.d.ts +66 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +157 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/skin.d.ts +9 -0
- package/dist/features/skin.d.ts.map +1 -0
- package/dist/features/skin.js +43 -0
- package/dist/features/skin.js.map +1 -0
- package/dist/features/terrain.d.ts +66 -0
- package/dist/features/terrain.d.ts.map +1 -0
- package/dist/features/terrain.js +291 -0
- package/dist/features/terrain.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/interaction/builtin-intents.d.ts +9 -0
- package/dist/interaction/builtin-intents.d.ts.map +1 -0
- package/dist/interaction/builtin-intents.js +61 -0
- package/dist/interaction/builtin-intents.js.map +1 -0
- package/dist/interaction/catalog.d.ts +24 -0
- package/dist/interaction/catalog.d.ts.map +1 -0
- package/dist/interaction/catalog.js +20 -0
- package/dist/interaction/catalog.js.map +1 -0
- package/dist/interaction/controller.d.ts +137 -0
- package/dist/interaction/controller.d.ts.map +1 -0
- package/dist/interaction/controller.js +215 -0
- package/dist/interaction/controller.js.map +1 -0
- package/dist/interaction/index.d.ts +14 -0
- package/dist/interaction/index.d.ts.map +1 -0
- package/dist/interaction/index.js +13 -0
- package/dist/interaction/input.d.ts +26 -0
- package/dist/interaction/input.d.ts.map +1 -0
- package/dist/interaction/input.js +33 -0
- package/dist/interaction/input.js.map +1 -0
- package/dist/interaction/intents.d.ts +80 -0
- package/dist/interaction/intents.d.ts.map +1 -0
- package/dist/interaction/keyboard.d.ts +26 -0
- package/dist/interaction/keyboard.d.ts.map +1 -0
- package/dist/interaction/keyboard.js +32 -0
- package/dist/interaction/keyboard.js.map +1 -0
- package/dist/interaction/picking.d.ts +33 -0
- package/dist/interaction/picking.d.ts.map +1 -0
- package/dist/interaction/picking.js +35 -0
- package/dist/interaction/picking.js.map +1 -0
- package/dist/interaction/pipeline.d.ts +45 -0
- package/dist/interaction/pipeline.d.ts.map +1 -0
- package/dist/interaction/pipeline.js +26 -0
- package/dist/interaction/pipeline.js.map +1 -0
- package/dist/interaction/placement.d.ts +76 -0
- package/dist/interaction/placement.d.ts.map +1 -0
- package/dist/interaction/placement.js +238 -0
- package/dist/interaction/placement.js.map +1 -0
- package/dist/interaction/selection-tool.d.ts +29 -0
- package/dist/interaction/selection-tool.d.ts.map +1 -0
- package/dist/interaction/selection-tool.js +190 -0
- package/dist/interaction/selection-tool.js.map +1 -0
- package/dist/interaction/steps.d.ts +62 -0
- package/dist/interaction/steps.d.ts.map +1 -0
- package/dist/interaction/steps.js +126 -0
- package/dist/interaction/steps.js.map +1 -0
- package/dist/interaction/store.d.ts +10 -0
- package/dist/interaction/store.d.ts.map +1 -0
- package/dist/interaction/store.js +28 -0
- package/dist/interaction/store.js.map +1 -0
- package/dist/interaction/tools.d.ts +26 -0
- package/dist/interaction/tools.d.ts.map +1 -0
- package/dist/interaction/tools.js +41 -0
- package/dist/interaction/tools.js.map +1 -0
- package/dist/model/assets.d.ts +36 -0
- package/dist/model/assets.d.ts.map +1 -0
- package/dist/model/assets.js +18 -0
- package/dist/model/assets.js.map +1 -0
- package/dist/model/committer.d.ts +66 -0
- package/dist/model/committer.d.ts.map +1 -0
- package/dist/model/committer.js +38 -0
- package/dist/model/committer.js.map +1 -0
- package/dist/model/core-patches.d.ts +2 -0
- package/dist/model/core-patches.d.ts.map +1 -0
- package/dist/model/core-patches.js +193 -0
- package/dist/model/core-patches.js.map +1 -0
- package/dist/model/define-map.d.ts +52 -0
- package/dist/model/define-map.d.ts.map +1 -0
- package/dist/model/define-map.js +66 -0
- package/dist/model/define-map.js.map +1 -0
- package/dist/model/definition.d.ts +57 -0
- package/dist/model/definition.d.ts.map +1 -0
- package/dist/model/definition.js +6 -0
- package/dist/model/definition.js.map +1 -0
- package/dist/model/errors.d.ts +21 -0
- package/dist/model/errors.d.ts.map +1 -0
- package/dist/model/errors.js +14 -0
- package/dist/model/errors.js.map +1 -0
- package/dist/model/history.d.ts +43 -0
- package/dist/model/history.d.ts.map +1 -0
- package/dist/model/history.js +141 -0
- package/dist/model/history.js.map +1 -0
- package/dist/model/index.d.ts +14 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +14 -0
- package/dist/model/json.d.ts +15 -0
- package/dist/model/json.d.ts.map +1 -0
- package/dist/model/json.js +35 -0
- package/dist/model/json.js.map +1 -0
- package/dist/model/model.d.ts +68 -0
- package/dist/model/model.d.ts.map +1 -0
- package/dist/model/model.js +170 -0
- package/dist/model/model.js.map +1 -0
- package/dist/model/parse.d.ts +24 -0
- package/dist/model/parse.d.ts.map +1 -0
- package/dist/model/parse.js +165 -0
- package/dist/model/parse.js.map +1 -0
- package/dist/model/patches.d.ts +100 -0
- package/dist/model/patches.d.ts.map +1 -0
- package/dist/model/patches.js +21 -0
- package/dist/model/patches.js.map +1 -0
- package/dist/model/result.d.ts +22 -0
- package/dist/model/result.d.ts.map +1 -0
- package/dist/model/result.js +10 -0
- package/dist/model/result.js.map +1 -0
- package/dist/model/source.d.ts +52 -0
- package/dist/model/source.d.ts.map +1 -0
- package/dist/model/source.js +75 -0
- package/dist/model/source.js.map +1 -0
- package/dist/protocol/index.d.ts +92 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +106 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/remote/committer.d.ts +43 -0
- package/dist/remote/committer.d.ts.map +1 -0
- package/dist/remote/committer.js +206 -0
- package/dist/remote/committer.js.map +1 -0
- package/dist/remote/index.d.ts +4 -0
- package/dist/remote/index.d.ts.map +1 -0
- package/dist/remote/index.js +4 -0
- package/dist/remote/join.d.ts +30 -0
- package/dist/remote/join.d.ts.map +1 -0
- package/dist/remote/join.js +36 -0
- package/dist/remote/join.js.map +1 -0
- package/dist/remote/memory-transport.d.ts +20 -0
- package/dist/remote/memory-transport.d.ts.map +1 -0
- package/dist/remote/memory-transport.js +48 -0
- package/dist/remote/memory-transport.js.map +1 -0
- package/dist/renderer/effects.d.ts +52 -0
- package/dist/renderer/effects.d.ts.map +1 -0
- package/dist/renderer/effects.js +111 -0
- package/dist/renderer/effects.js.map +1 -0
- package/dist/renderer/feature.d.ts +79 -0
- package/dist/renderer/feature.d.ts.map +1 -0
- package/dist/renderer/feature.js +50 -0
- package/dist/renderer/feature.js.map +1 -0
- package/dist/renderer/geometry.d.ts +59 -0
- package/dist/renderer/geometry.d.ts.map +1 -0
- package/dist/renderer/geometry.js +114 -0
- package/dist/renderer/geometry.js.map +1 -0
- package/dist/renderer/index.d.ts +7 -0
- package/dist/renderer/index.d.ts.map +1 -0
- package/dist/renderer/index.js +7 -0
- package/dist/renderer/scene.d.ts +77 -0
- package/dist/renderer/scene.d.ts.map +1 -0
- package/dist/renderer/scene.js +125 -0
- package/dist/renderer/scene.js.map +1 -0
- package/dist/renderer/textures.d.ts +20 -0
- package/dist/renderer/textures.d.ts.map +1 -0
- package/dist/renderer/textures.js +61 -0
- package/dist/renderer/textures.js.map +1 -0
- package/dist/renderer/view.d.ts +139 -0
- package/dist/renderer/view.d.ts.map +1 -0
- package/dist/renderer/view.js +349 -0
- package/dist/renderer/view.js.map +1 -0
- package/dist/rpgjs/shared.d.ts +41 -0
- package/dist/rpgjs/shared.d.ts.map +1 -0
- package/dist/rpgjs/shared.js +77 -0
- package/dist/rpgjs/shared.js.map +1 -0
- package/dist/server/index.d.ts +64 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +205 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/storage.d.ts +16 -0
- package/dist/server/storage.d.ts.map +1 -0
- package/dist/server/storage.js +52 -0
- package/dist/server/storage.js.map +1 -0
- package/dist/skins/default.d.ts +27 -0
- package/dist/skins/default.d.ts.map +1 -0
- package/dist/skins/default.js +144 -0
- package/dist/skins/default.js.map +1 -0
- package/dist/skins/frames.d.ts +19 -0
- package/dist/skins/frames.d.ts.map +1 -0
- package/dist/skins/frames.js +49 -0
- package/dist/skins/frames.js.map +1 -0
- package/dist/skins/game.d.ts +21 -0
- package/dist/skins/game.d.ts.map +1 -0
- package/dist/skins/game.js +21 -0
- package/dist/skins/game.js.map +1 -0
- package/dist/skins/index.d.ts +5 -0
- package/dist/skins/index.d.ts.map +1 -0
- package/dist/skins/index.js +5 -0
- package/dist/skins/types.d.ts +46 -0
- package/dist/skins/types.d.ts.map +1 -0
- package/dist/skins/types.js +12 -0
- package/dist/skins/types.js.map +1 -0
- package/dist/terrain/data.d.ts +10 -0
- package/dist/terrain/data.d.ts.map +1 -0
- package/dist/terrain/data.js +83 -0
- package/dist/terrain/data.js.map +1 -0
- package/dist/terrain/define.d.ts +72 -0
- package/dist/terrain/define.d.ts.map +1 -0
- package/dist/terrain/define.js +91 -0
- package/dist/terrain/define.js.map +1 -0
- package/dist/terrain/editing.d.ts +54 -0
- package/dist/terrain/editing.d.ts.map +1 -0
- package/dist/terrain/editing.js +169 -0
- package/dist/terrain/editing.js.map +1 -0
- package/dist/terrain/index.d.ts +10 -0
- package/dist/terrain/index.d.ts.map +1 -0
- package/dist/terrain/index.js +10 -0
- package/dist/terrain/kernel.d.ts +57 -0
- package/dist/terrain/kernel.d.ts.map +1 -0
- package/dist/terrain/kernel.js +198 -0
- package/dist/terrain/kernel.js.map +1 -0
- package/dist/terrain/mask.d.ts +37 -0
- package/dist/terrain/mask.d.ts.map +1 -0
- package/dist/terrain/mask.js +244 -0
- package/dist/terrain/mask.js.map +1 -0
- package/dist/terrain/patches.d.ts +32 -0
- package/dist/terrain/patches.d.ts.map +1 -0
- package/dist/terrain/patches.js +135 -0
- package/dist/terrain/patches.js.map +1 -0
- package/dist/terrain/rle.d.ts +4 -0
- package/dist/terrain/rle.d.ts.map +1 -0
- package/dist/terrain/rle.js +68 -0
- package/dist/terrain/rle.js.map +1 -0
- package/dist/terrain/scheduler.d.ts +46 -0
- package/dist/terrain/scheduler.d.ts.map +1 -0
- package/dist/terrain/scheduler.js +148 -0
- package/dist/terrain/scheduler.js.map +1 -0
- package/dist/terrain/types.d.ts +110 -0
- package/dist/terrain/types.d.ts.map +1 -0
- package/dist/terrain/types.js +11 -0
- package/dist/terrain/types.js.map +1 -0
- package/dist/terrain-render/backend.d.ts +66 -0
- package/dist/terrain-render/backend.d.ts.map +1 -0
- package/dist/terrain-render/backend.js +96 -0
- package/dist/terrain-render/backend.js.map +1 -0
- package/dist/terrain-render/host.d.ts +21 -0
- package/dist/terrain-render/host.d.ts.map +1 -0
- package/dist/terrain-render/host.js +62 -0
- package/dist/terrain-render/host.js.map +1 -0
- package/dist/terrain-render/index.d.ts +3 -0
- package/dist/terrain-render/index.d.ts.map +1 -0
- package/dist/terrain-render/index.js +3 -0
- package/dist/terrain-render/worker.d.ts +2 -0
- package/dist/terrain-render/worker.d.ts.map +1 -0
- package/dist/terrain-render/worker.js +34 -0
- package/dist/terrain-render/worker.js.map +1 -0
- package/package.json +124 -3
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { resolveElementGeometry, unionBounds } from "./geometry.js";
|
|
2
|
+
//#region src/renderer/scene.ts
|
|
3
|
+
/** Draw order, back to front. Only `objects` is filled by the built-in features. */
|
|
4
|
+
var STAGE_ORDER = [
|
|
5
|
+
"ground",
|
|
6
|
+
"objects",
|
|
7
|
+
"overlay",
|
|
8
|
+
"lighting",
|
|
9
|
+
"post"
|
|
10
|
+
];
|
|
11
|
+
var toParts = (nodeKey, spec, origin, src) => spec.map((part, index) => ({
|
|
12
|
+
key: part.key ?? `${nodeKey}#${index}`,
|
|
13
|
+
x: origin.x + part.x,
|
|
14
|
+
y: origin.y + part.y,
|
|
15
|
+
width: part.width,
|
|
16
|
+
height: part.height,
|
|
17
|
+
src: part.src ?? src,
|
|
18
|
+
...part.frame ? { frame: part.frame } : {}
|
|
19
|
+
}));
|
|
20
|
+
/**
|
|
21
|
+
* What to draw for an element, or `undefined` when nothing can be drawn yet: the
|
|
22
|
+
* asset is unknown, or its size is not known until its image has loaded.
|
|
23
|
+
*/
|
|
24
|
+
function describeElement(element, context) {
|
|
25
|
+
const descriptor = context.assets.resolve(element.kind);
|
|
26
|
+
const spec = context.hooks?.resolveElementSprite?.(element, { descriptor });
|
|
27
|
+
if (!descriptor && !spec) {
|
|
28
|
+
context.hooks?.onMissingAsset?.(element.kind, {
|
|
29
|
+
type: "element",
|
|
30
|
+
id: element.id
|
|
31
|
+
});
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const src = spec?.src ?? descriptor?.src;
|
|
35
|
+
if (!src) return void 0;
|
|
36
|
+
const frame = spec?.frame ?? descriptor?.frame;
|
|
37
|
+
const size = spec?.size ?? descriptor?.size;
|
|
38
|
+
const hitbox = spec?.hitbox ?? descriptor?.hitbox;
|
|
39
|
+
const geometry = resolveElementGeometry({
|
|
40
|
+
x: element.x,
|
|
41
|
+
y: element.y,
|
|
42
|
+
...element.scale !== void 0 ? { scale: element.scale } : {},
|
|
43
|
+
...element.depth ? { depth: element.depth } : {},
|
|
44
|
+
...frame ? { frame } : {},
|
|
45
|
+
...size ? { size } : {},
|
|
46
|
+
...hitbox ? { hitbox } : {},
|
|
47
|
+
...(() => {
|
|
48
|
+
const measured = frame || size ? void 0 : context.measure?.(src);
|
|
49
|
+
return measured ? { sourceSize: measured } : {};
|
|
50
|
+
})()
|
|
51
|
+
});
|
|
52
|
+
if (!geometry) return void 0;
|
|
53
|
+
const key = `elements/${element.id}`;
|
|
54
|
+
const parts = spec?.parts ? toParts(key, spec.parts, element, src) : [{
|
|
55
|
+
key: "default",
|
|
56
|
+
x: geometry.draw.x,
|
|
57
|
+
y: geometry.draw.y,
|
|
58
|
+
width: geometry.draw.width,
|
|
59
|
+
height: geometry.draw.height,
|
|
60
|
+
src,
|
|
61
|
+
...frame ? { frame } : {}
|
|
62
|
+
}];
|
|
63
|
+
const node = {
|
|
64
|
+
key,
|
|
65
|
+
id: element.id,
|
|
66
|
+
type: "element",
|
|
67
|
+
kind: element.kind,
|
|
68
|
+
stage: "objects",
|
|
69
|
+
sortKey: geometry.sortKey,
|
|
70
|
+
bounds: unionBounds(parts),
|
|
71
|
+
parts,
|
|
72
|
+
...geometry.hitbox ? { hitbox: {
|
|
73
|
+
x: geometry.draw.x + geometry.hitbox.x * geometry.hitbox.scaleX,
|
|
74
|
+
y: geometry.draw.y + geometry.hitbox.y * geometry.hitbox.scaleY,
|
|
75
|
+
width: geometry.hitbox.width * geometry.hitbox.scaleX,
|
|
76
|
+
height: geometry.hitbox.height * geometry.hitbox.scaleY
|
|
77
|
+
} } : {}
|
|
78
|
+
};
|
|
79
|
+
return context.hooks?.onBeforeRenderElement?.(node, element) ?? node;
|
|
80
|
+
}
|
|
81
|
+
/** What to draw for an event: its graphic, when it has one that is a known asset. */
|
|
82
|
+
function describeEvent(event, context) {
|
|
83
|
+
if (event.graphic === void 0) return void 0;
|
|
84
|
+
const descriptor = context.assets.resolve(event.graphic);
|
|
85
|
+
if (!descriptor) {
|
|
86
|
+
context.hooks?.onMissingAsset?.(event.graphic, {
|
|
87
|
+
type: "event",
|
|
88
|
+
id: event.id
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const measured = descriptor.frame || descriptor.size ? void 0 : context.measure?.(descriptor.src);
|
|
93
|
+
const geometry = resolveElementGeometry({
|
|
94
|
+
x: event.x,
|
|
95
|
+
y: event.y,
|
|
96
|
+
...descriptor.frame ? { frame: descriptor.frame } : {},
|
|
97
|
+
...descriptor.size ? { size: descriptor.size } : {},
|
|
98
|
+
...descriptor.hitbox ? { hitbox: descriptor.hitbox } : {},
|
|
99
|
+
...measured ? { sourceSize: measured } : {}
|
|
100
|
+
});
|
|
101
|
+
if (!geometry) return void 0;
|
|
102
|
+
const part = {
|
|
103
|
+
key: "default",
|
|
104
|
+
x: geometry.draw.x,
|
|
105
|
+
y: geometry.draw.y,
|
|
106
|
+
width: geometry.draw.width,
|
|
107
|
+
height: geometry.draw.height,
|
|
108
|
+
src: descriptor.src,
|
|
109
|
+
...descriptor.frame ? { frame: descriptor.frame } : {}
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
key: `events/${event.id}`,
|
|
113
|
+
id: event.id,
|
|
114
|
+
type: "event",
|
|
115
|
+
kind: event.kind,
|
|
116
|
+
stage: "objects",
|
|
117
|
+
sortKey: geometry.sortKey,
|
|
118
|
+
bounds: unionBounds([part]),
|
|
119
|
+
parts: [part]
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
123
|
+
export { STAGE_ORDER, describeElement, describeEvent };
|
|
124
|
+
|
|
125
|
+
//# sourceMappingURL=scene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.js","names":[],"sources":["../../src/renderer/scene.ts"],"sourcesContent":["import type { AssetDescriptor, AssetResolver } from \"../model/assets\";\nimport type { MapElement, MapEvent } from \"../model/definition\";\nimport { resolveElementGeometry, unionBounds, type Frame, type Rect } from \"./geometry\";\n\nexport type StageName = \"ground\" | \"objects\" | \"overlay\" | \"lighting\" | \"post\";\n\n/** Draw order, back to front. Only `objects` is filled by the built-in features. */\nexport const STAGE_ORDER: readonly StageName[] = [\"ground\", \"objects\", \"overlay\", \"lighting\", \"post\"];\n\n/** One image drawn at a world position. */\nexport interface ScenePart {\n readonly key: string;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly src: string;\n readonly frame?: Frame;\n}\n\n/** What to draw for one element or event. Plain data: it can be compared, logged and snapshotted. */\nexport interface SceneNode {\n /** Unique in the scene: `<feature>/<id>`. */\n readonly key: string;\n readonly id: string;\n readonly type: \"element\" | \"event\";\n readonly kind: string;\n readonly stage: StageName;\n /** Nodes with a higher key are drawn in front. */\n readonly sortKey: number;\n readonly bounds: Rect;\n readonly parts: readonly ScenePart[];\n /** Collision box in world coordinates. */\n readonly hitbox?: Rect;\n}\n\n/** A part given by a hook, relative to the element origin. */\nexport interface SpritePartSpec {\n readonly key?: string;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n readonly src?: string;\n readonly frame?: Frame;\n}\n\n/** What a hook can change about how an element is drawn. */\nexport interface ElementSpriteSpec {\n /** Replaces the single image by these parts (a repeated body, a nine-slice…). */\n readonly parts?: readonly SpritePartSpec[];\n readonly src?: string;\n readonly frame?: Frame;\n readonly size?: readonly [number, number];\n readonly hitbox?: Frame;\n}\n\nexport interface MapViewHooks {\n /** Changes how an element is drawn. Studio uses it for drawing rules and element sizes. */\n resolveElementSprite?(element: MapElement, context: { readonly descriptor: AssetDescriptor | undefined }): ElementSpriteSpec | undefined;\n /** Last chance to adjust a node, e.g. its sort key or its parts. */\n onBeforeRenderElement?(node: SceneNode, element: MapElement): SceneNode | void;\n /** An element or an event refers to an asset nobody knows. */\n onMissingAsset?(kind: string, owner: { readonly type: \"element\" | \"event\"; readonly id: string }): void;\n}\n\nexport interface DescribeContext {\n readonly assets: AssetResolver;\n readonly hooks?: MapViewHooks;\n /** Size of a loaded image, for assets that do not declare one. */\n readonly measure?: (src: string) => readonly [number, number] | undefined;\n}\n\nconst toParts = (nodeKey: string, spec: readonly SpritePartSpec[], origin: { x: number; y: number }, src: string): ScenePart[] =>\n spec.map((part, index) => ({\n key: part.key ?? `${nodeKey}#${index}`,\n x: origin.x + part.x,\n y: origin.y + part.y,\n width: part.width,\n height: part.height,\n src: part.src ?? src,\n ...(part.frame ? { frame: part.frame } : {}),\n }));\n\n/**\n * What to draw for an element, or `undefined` when nothing can be drawn yet: the\n * asset is unknown, or its size is not known until its image has loaded.\n */\nexport function describeElement(element: MapElement, context: DescribeContext): SceneNode | undefined {\n const descriptor = context.assets.resolve(element.kind);\n const spec = context.hooks?.resolveElementSprite?.(element, { descriptor });\n if (!descriptor && !spec) {\n context.hooks?.onMissingAsset?.(element.kind, { type: \"element\", id: element.id });\n return undefined;\n }\n\n const src = spec?.src ?? descriptor?.src;\n if (!src) return undefined;\n const frame = spec?.frame ?? descriptor?.frame;\n const size = spec?.size ?? descriptor?.size;\n const hitbox = spec?.hitbox ?? descriptor?.hitbox;\n\n const geometry = resolveElementGeometry({\n x: element.x,\n y: element.y,\n ...(element.scale !== undefined ? { scale: element.scale } : {}),\n ...(element.depth ? { depth: element.depth } : {}),\n ...(frame ? { frame } : {}),\n ...(size ? { size } : {}),\n ...(hitbox ? { hitbox } : {}),\n ...(() => {\n // Only an image that declares neither a frame nor a size has to be measured.\n const measured = frame || size ? undefined : context.measure?.(src);\n return measured ? { sourceSize: measured } : {};\n })(),\n });\n if (!geometry) return undefined;\n\n const key = `elements/${element.id}`;\n const parts: ScenePart[] = spec?.parts\n ? toParts(key, spec.parts, element, src)\n : [\n {\n key: \"default\",\n x: geometry.draw.x,\n y: geometry.draw.y,\n width: geometry.draw.width,\n height: geometry.draw.height,\n src,\n ...(frame ? { frame } : {}),\n },\n ];\n\n const node: SceneNode = {\n key,\n id: element.id,\n type: \"element\",\n kind: element.kind,\n stage: \"objects\",\n sortKey: geometry.sortKey,\n bounds: unionBounds(parts),\n parts,\n ...(geometry.hitbox\n ? {\n hitbox: {\n x: geometry.draw.x + geometry.hitbox.x * geometry.hitbox.scaleX,\n y: geometry.draw.y + geometry.hitbox.y * geometry.hitbox.scaleY,\n width: geometry.hitbox.width * geometry.hitbox.scaleX,\n height: geometry.hitbox.height * geometry.hitbox.scaleY,\n },\n }\n : {}),\n };\n return context.hooks?.onBeforeRenderElement?.(node, element) ?? node;\n}\n\n/** What to draw for an event: its graphic, when it has one that is a known asset. */\nexport function describeEvent(event: MapEvent, context: DescribeContext): SceneNode | undefined {\n if (event.graphic === undefined) return undefined;\n const descriptor = context.assets.resolve(event.graphic);\n if (!descriptor) {\n context.hooks?.onMissingAsset?.(event.graphic, { type: \"event\", id: event.id });\n return undefined;\n }\n const measured = descriptor.frame || descriptor.size ? undefined : context.measure?.(descriptor.src);\n const geometry = resolveElementGeometry({\n x: event.x,\n y: event.y,\n ...(descriptor.frame ? { frame: descriptor.frame } : {}),\n ...(descriptor.size ? { size: descriptor.size } : {}),\n ...(descriptor.hitbox ? { hitbox: descriptor.hitbox } : {}),\n ...(measured ? { sourceSize: measured } : {}),\n });\n if (!geometry) return undefined;\n\n const part: ScenePart = {\n key: \"default\",\n x: geometry.draw.x,\n y: geometry.draw.y,\n width: geometry.draw.width,\n height: geometry.draw.height,\n src: descriptor.src,\n ...(descriptor.frame ? { frame: descriptor.frame } : {}),\n };\n return {\n key: `events/${event.id}`,\n id: event.id,\n type: \"event\",\n kind: event.kind,\n stage: \"objects\",\n sortKey: geometry.sortKey,\n bounds: unionBounds([part]),\n parts: [part],\n };\n}\n"],"mappings":";;;AAOA,IAAa,cAAoC;CAAC;CAAU;CAAW;CAAW;CAAY;AAAM;AAkEpG,IAAM,WAAW,SAAiB,MAAiC,QAAkC,QACnG,KAAK,KAAK,MAAM,WAAW;CACzB,KAAK,KAAK,OAAO,GAAG,QAAQ,GAAG;CAC/B,GAAG,OAAO,IAAI,KAAK;CACnB,GAAG,OAAO,IAAI,KAAK;CACnB,OAAO,KAAK;CACZ,QAAQ,KAAK;CACb,KAAK,KAAK,OAAO;CACjB,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAC5C,EAAE;;;;;AAMJ,SAAgB,gBAAgB,SAAqB,SAAiD;CACpG,MAAM,aAAa,QAAQ,OAAO,QAAQ,QAAQ,IAAI;CACtD,MAAM,OAAO,QAAQ,OAAO,uBAAuB,SAAS,EAAE,WAAW,CAAC;CAC1E,IAAI,CAAC,cAAc,CAAC,MAAM;EACxB,QAAQ,OAAO,iBAAiB,QAAQ,MAAM;GAAE,MAAM;GAAW,IAAI,QAAQ;EAAG,CAAC;EACjF;CACF;CAEA,MAAM,MAAM,MAAM,OAAO,YAAY;CACrC,IAAI,CAAC,KAAK,OAAO,KAAA;CACjB,MAAM,QAAQ,MAAM,SAAS,YAAY;CACzC,MAAM,OAAO,MAAM,QAAQ,YAAY;CACvC,MAAM,SAAS,MAAM,UAAU,YAAY;CAE3C,MAAM,WAAW,uBAAuB;EACtC,GAAG,QAAQ;EACX,GAAG,QAAQ;EACX,GAAI,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAC9D,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;EAChD,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;EACzB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;EACvB,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAC3B,UAAU;GAER,MAAM,WAAW,SAAS,OAAO,KAAA,IAAY,QAAQ,UAAU,GAAG;GAClE,OAAO,WAAW,EAAE,YAAY,SAAS,IAAI,CAAC;EAChD,EAAA,CAAG;CACL,CAAC;CACD,IAAI,CAAC,UAAU,OAAO,KAAA;CAEtB,MAAM,MAAM,YAAY,QAAQ;CAChC,MAAM,QAAqB,MAAM,QAC7B,QAAQ,KAAK,KAAK,OAAO,SAAS,GAAG,IACrC,CACE;EACE,KAAK;EACL,GAAG,SAAS,KAAK;EACjB,GAAG,SAAS,KAAK;EACjB,OAAO,SAAS,KAAK;EACrB,QAAQ,SAAS,KAAK;EACtB;EACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC3B,CACF;CAEJ,MAAM,OAAkB;EACtB;EACA,IAAI,QAAQ;EACZ,MAAM;EACN,MAAM,QAAQ;EACd,OAAO;EACP,SAAS,SAAS;EAClB,QAAQ,YAAY,KAAK;EACzB;EACA,GAAI,SAAS,SACT,EACE,QAAQ;GACN,GAAG,SAAS,KAAK,IAAI,SAAS,OAAO,IAAI,SAAS,OAAO;GACzD,GAAG,SAAS,KAAK,IAAI,SAAS,OAAO,IAAI,SAAS,OAAO;GACzD,OAAO,SAAS,OAAO,QAAQ,SAAS,OAAO;GAC/C,QAAQ,SAAS,OAAO,SAAS,SAAS,OAAO;EACnD,EACF,IACA,CAAC;CACP;CACA,OAAO,QAAQ,OAAO,wBAAwB,MAAM,OAAO,KAAK;AAClE;;AAGA,SAAgB,cAAc,OAAiB,SAAiD;CAC9F,IAAI,MAAM,YAAY,KAAA,GAAW,OAAO,KAAA;CACxC,MAAM,aAAa,QAAQ,OAAO,QAAQ,MAAM,OAAO;CACvD,IAAI,CAAC,YAAY;EACf,QAAQ,OAAO,iBAAiB,MAAM,SAAS;GAAE,MAAM;GAAS,IAAI,MAAM;EAAG,CAAC;EAC9E;CACF;CACA,MAAM,WAAW,WAAW,SAAS,WAAW,OAAO,KAAA,IAAY,QAAQ,UAAU,WAAW,GAAG;CACnG,MAAM,WAAW,uBAAuB;EACtC,GAAG,MAAM;EACT,GAAG,MAAM;EACT,GAAI,WAAW,QAAQ,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;EACtD,GAAI,WAAW,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;EACnD,GAAI,WAAW,SAAS,EAAE,QAAQ,WAAW,OAAO,IAAI,CAAC;EACzD,GAAI,WAAW,EAAE,YAAY,SAAS,IAAI,CAAC;CAC7C,CAAC;CACD,IAAI,CAAC,UAAU,OAAO,KAAA;CAEtB,MAAM,OAAkB;EACtB,KAAK;EACL,GAAG,SAAS,KAAK;EACjB,GAAG,SAAS,KAAK;EACjB,OAAO,SAAS,KAAK;EACrB,QAAQ,SAAS,KAAK;EACtB,KAAK,WAAW;EAChB,GAAI,WAAW,QAAQ,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;CACxD;CACA,OAAO;EACL,KAAK,UAAU,MAAM;EACrB,IAAI,MAAM;EACV,MAAM;EACN,MAAM,MAAM;EACZ,OAAO;EACP,SAAS,SAAS;EAClB,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,OAAO,CAAC,IAAI;CACd;AACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Texture } from 'pixi.js';
|
|
2
|
+
import { Frame } from './geometry';
|
|
3
|
+
/** Loads the image behind an asset. Replaceable, so tests and games can bring their own loading. */
|
|
4
|
+
export interface TextureProvider {
|
|
5
|
+
load(src: string): Texture | Promise<Texture>;
|
|
6
|
+
}
|
|
7
|
+
/** The default provider: PixiJS `Assets`. */
|
|
8
|
+
export declare const pixiTextureProvider: TextureProvider;
|
|
9
|
+
export interface TextureStore {
|
|
10
|
+
/** The texture, or `undefined` while the image is loading (or if it failed). */
|
|
11
|
+
get(src: string, frame?: Frame): Texture | undefined;
|
|
12
|
+
/** Loads the image, then resolves the texture. Rejects if loading failed. */
|
|
13
|
+
ready(src: string, frame?: Frame): Promise<Texture>;
|
|
14
|
+
/** Size of a loaded image, before any frame is applied. */
|
|
15
|
+
size(src: string): readonly [number, number] | undefined;
|
|
16
|
+
destroy(): void;
|
|
17
|
+
}
|
|
18
|
+
/** Loads each image once and caches the textures cut out of it. */
|
|
19
|
+
export declare function createTextureStore(provider: TextureProvider): TextureStore;
|
|
20
|
+
//# sourceMappingURL=textures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textures.d.ts","sourceRoot":"","sources":["../../src/renderer/textures.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,OAAO,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/C;AAED,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,EAAE,eAA8D,CAAC;AAEjG,MAAM,WAAW,YAAY;IAC3B,gFAAgF;IAChF,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,SAAS,CAAC;IACrD,6EAA6E;IAC7E,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,2DAA2D;IAC3D,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACzD,OAAO,IAAI,IAAI,CAAC;CACjB;AAID,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,eAAe,GAAG,YAAY,CAmD1E"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Assets, Rectangle, Texture } from "pixi.js";
|
|
2
|
+
//#region src/renderer/textures.ts
|
|
3
|
+
/** The default provider: PixiJS `Assets`. */
|
|
4
|
+
var pixiTextureProvider = { load: (src) => Assets.load(src) };
|
|
5
|
+
var frameKey = (src, frame) => frame ? `${src}#${frame.join(",")}` : src;
|
|
6
|
+
/** Loads each image once and caches the textures cut out of it. */
|
|
7
|
+
function createTextureStore(provider) {
|
|
8
|
+
const loading = /* @__PURE__ */ new Map();
|
|
9
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
10
|
+
const frames = /* @__PURE__ */ new Map();
|
|
11
|
+
const base = (src) => {
|
|
12
|
+
let promise = loading.get(src);
|
|
13
|
+
if (!promise) {
|
|
14
|
+
promise = Promise.resolve(provider.load(src)).then((texture) => {
|
|
15
|
+
loaded.set(src, texture);
|
|
16
|
+
return texture;
|
|
17
|
+
});
|
|
18
|
+
loading.set(src, promise);
|
|
19
|
+
promise.catch(() => loading.delete(src));
|
|
20
|
+
}
|
|
21
|
+
return promise;
|
|
22
|
+
};
|
|
23
|
+
const cut = (src, texture, frame) => {
|
|
24
|
+
if (!frame) return texture;
|
|
25
|
+
const key = frameKey(src, frame);
|
|
26
|
+
let part = frames.get(key);
|
|
27
|
+
if (!part) {
|
|
28
|
+
part = new Texture({
|
|
29
|
+
source: texture.source,
|
|
30
|
+
frame: new Rectangle(frame[0], frame[1], frame[2], frame[3])
|
|
31
|
+
});
|
|
32
|
+
frames.set(key, part);
|
|
33
|
+
}
|
|
34
|
+
return part;
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
get(src, frame) {
|
|
38
|
+
const texture = loaded.get(src);
|
|
39
|
+
if (!texture) {
|
|
40
|
+
base(src).catch(() => void 0);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
return cut(src, texture, frame);
|
|
44
|
+
},
|
|
45
|
+
ready: async (src, frame) => cut(src, await base(src), frame),
|
|
46
|
+
size(src) {
|
|
47
|
+
const texture = loaded.get(src);
|
|
48
|
+
return texture ? [texture.width, texture.height] : void 0;
|
|
49
|
+
},
|
|
50
|
+
destroy() {
|
|
51
|
+
for (const part of frames.values()) part.destroy(false);
|
|
52
|
+
frames.clear();
|
|
53
|
+
loaded.clear();
|
|
54
|
+
loading.clear();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { createTextureStore, pixiTextureProvider };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=textures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"textures.js","names":[],"sources":["../../src/renderer/textures.ts"],"sourcesContent":["import { Assets, Rectangle, Texture } from \"pixi.js\";\nimport type { Frame } from \"./geometry\";\n\n/** Loads the image behind an asset. Replaceable, so tests and games can bring their own loading. */\nexport interface TextureProvider {\n load(src: string): Texture | Promise<Texture>;\n}\n\n/** The default provider: PixiJS `Assets`. */\nexport const pixiTextureProvider: TextureProvider = { load: (src) => Assets.load<Texture>(src) };\n\nexport interface TextureStore {\n /** The texture, or `undefined` while the image is loading (or if it failed). */\n get(src: string, frame?: Frame): Texture | undefined;\n /** Loads the image, then resolves the texture. Rejects if loading failed. */\n ready(src: string, frame?: Frame): Promise<Texture>;\n /** Size of a loaded image, before any frame is applied. */\n size(src: string): readonly [number, number] | undefined;\n destroy(): void;\n}\n\nconst frameKey = (src: string, frame?: Frame): string => (frame ? `${src}#${frame.join(\",\")}` : src);\n\n/** Loads each image once and caches the textures cut out of it. */\nexport function createTextureStore(provider: TextureProvider): TextureStore {\n const loading = new Map<string, Promise<Texture>>();\n const loaded = new Map<string, Texture>();\n const frames = new Map<string, Texture>();\n\n const base = (src: string): Promise<Texture> => {\n let promise = loading.get(src);\n if (!promise) {\n promise = Promise.resolve(provider.load(src)).then((texture) => {\n loaded.set(src, texture);\n return texture;\n });\n loading.set(src, promise);\n // A failed load can be retried on the next request.\n promise.catch(() => loading.delete(src));\n }\n return promise;\n };\n\n const cut = (src: string, texture: Texture, frame?: Frame): Texture => {\n if (!frame) return texture;\n const key = frameKey(src, frame);\n let part = frames.get(key);\n if (!part) {\n part = new Texture({ source: texture.source, frame: new Rectangle(frame[0], frame[1], frame[2], frame[3]) });\n frames.set(key, part);\n }\n return part;\n };\n\n return {\n get(src, frame) {\n const texture = loaded.get(src);\n if (!texture) {\n void base(src).catch(() => undefined);\n return undefined;\n }\n return cut(src, texture, frame);\n },\n ready: async (src, frame) => cut(src, await base(src), frame),\n size(src) {\n const texture = loaded.get(src);\n return texture ? [texture.width, texture.height] : undefined;\n },\n destroy() {\n for (const part of frames.values()) part.destroy(false);\n frames.clear();\n loaded.clear();\n loading.clear();\n },\n };\n}\n"],"mappings":";;;AASA,IAAa,sBAAuC,EAAE,OAAO,QAAQ,OAAO,KAAc,GAAG,EAAE;AAY/F,IAAM,YAAY,KAAa,UAA2B,QAAQ,GAAG,IAAI,GAAG,MAAM,KAAK,GAAG,MAAM;;AAGhG,SAAgB,mBAAmB,UAAyC;CAC1E,MAAM,0BAAU,IAAI,IAA8B;CAClD,MAAM,yBAAS,IAAI,IAAqB;CACxC,MAAM,yBAAS,IAAI,IAAqB;CAExC,MAAM,QAAQ,QAAkC;EAC9C,IAAI,UAAU,QAAQ,IAAI,GAAG;EAC7B,IAAI,CAAC,SAAS;GACZ,UAAU,QAAQ,QAAQ,SAAS,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,YAAY;IAC9D,OAAO,IAAI,KAAK,OAAO;IACvB,OAAO;GACT,CAAC;GACD,QAAQ,IAAI,KAAK,OAAO;GAExB,QAAQ,YAAY,QAAQ,OAAO,GAAG,CAAC;EACzC;EACA,OAAO;CACT;CAEA,MAAM,OAAO,KAAa,SAAkB,UAA2B;EACrE,IAAI,CAAC,OAAO,OAAO;EACnB,MAAM,MAAM,SAAS,KAAK,KAAK;EAC/B,IAAI,OAAO,OAAO,IAAI,GAAG;EACzB,IAAI,CAAC,MAAM;GACT,OAAO,IAAI,QAAQ;IAAE,QAAQ,QAAQ;IAAQ,OAAO,IAAI,UAAU,MAAM,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE;GAAE,CAAC;GAC3G,OAAO,IAAI,KAAK,IAAI;EACtB;EACA,OAAO;CACT;CAEA,OAAO;EACL,IAAI,KAAK,OAAO;GACd,MAAM,UAAU,OAAO,IAAI,GAAG;GAC9B,IAAI,CAAC,SAAS;IACZ,KAAU,GAAG,CAAC,CAAC,YAAY,KAAA,CAAS;IACpC;GACF;GACA,OAAO,IAAI,KAAK,SAAS,KAAK;EAChC;EACA,OAAO,OAAO,KAAK,UAAU,IAAI,KAAK,MAAM,KAAK,GAAG,GAAG,KAAK;EAC5D,KAAK,KAAK;GACR,MAAM,UAAU,OAAO,IAAI,GAAG;GAC9B,OAAO,UAAU,CAAC,QAAQ,OAAO,QAAQ,MAAM,IAAI,KAAA;EACrD;EACA,UAAU;GACR,KAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,KAAK,QAAQ,KAAK;GACtD,OAAO,MAAM;GACb,OAAO,MAAM;GACb,QAAQ,MAAM;EAChB;CACF;AACF"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Container } from 'pixi.js';
|
|
2
|
+
import { AssetResolver } from '../model/assets';
|
|
3
|
+
import { ApplyResult, MaybePromise } from '../model/result';
|
|
4
|
+
import { KeyTarget } from '../interaction/keyboard';
|
|
5
|
+
import { InteractionController, ModelApi } from '../interaction/controller';
|
|
6
|
+
import { EffectDefinition, EffectHandle, EffectParams } from './effects';
|
|
7
|
+
import { FeatureApis, MapFeature } from './feature';
|
|
8
|
+
import { Rect } from './geometry';
|
|
9
|
+
import { MapViewHooks, SceneNode, StageName } from './scene';
|
|
10
|
+
import { TextureProvider } from './textures';
|
|
11
|
+
export type MapViewErrorCode = "asset-load-failed";
|
|
12
|
+
export interface MapViewError {
|
|
13
|
+
readonly code: MapViewErrorCode;
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly src: string;
|
|
16
|
+
readonly cause: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** The part of a PixiJS `Application` the view uses to mount itself. */
|
|
19
|
+
export interface PixiApplicationLike {
|
|
20
|
+
init(options: Record<string, unknown>): Promise<void>;
|
|
21
|
+
readonly canvas: unknown;
|
|
22
|
+
readonly stage: Container;
|
|
23
|
+
readonly ticker: {
|
|
24
|
+
add(callback: (ticker: {
|
|
25
|
+
deltaMS: number;
|
|
26
|
+
}) => void): unknown;
|
|
27
|
+
remove(callback: (ticker: {
|
|
28
|
+
deltaMS: number;
|
|
29
|
+
}) => void): unknown;
|
|
30
|
+
};
|
|
31
|
+
destroy(removeView?: boolean, options?: unknown): void;
|
|
32
|
+
}
|
|
33
|
+
export interface MountOptions {
|
|
34
|
+
/**
|
|
35
|
+
* Listen to the keyboard (Escape, Delete…) and give it to the interaction layer.
|
|
36
|
+
* `true` listens on the page, or give an event target. Off by default.
|
|
37
|
+
*/
|
|
38
|
+
readonly keyboard?: boolean | KeyTarget;
|
|
39
|
+
/** CSS-style colour of the canvas background. Transparent by default. */
|
|
40
|
+
readonly background?: string | number;
|
|
41
|
+
/** Anti-aliasing is off by default: it blurs pixel art. */
|
|
42
|
+
readonly antialias?: boolean;
|
|
43
|
+
/** Replaces `new Application()`. */
|
|
44
|
+
readonly createApplication?: () => PixiApplicationLike;
|
|
45
|
+
}
|
|
46
|
+
export interface MapViewOptions<F extends readonly MapFeature<string, object>[] = readonly MapFeature<string, object>[], R extends MaybePromise<ApplyResult> = MaybePromise<ApplyResult>> {
|
|
47
|
+
/** Any `MapModel` fits, whatever its committer. */
|
|
48
|
+
readonly model: ModelApi<R>;
|
|
49
|
+
readonly assets: AssetResolver;
|
|
50
|
+
/** What the view draws and how. Nothing is drawn without features. */
|
|
51
|
+
readonly features: F;
|
|
52
|
+
/** Who is acting, handed to the steps of the pipelines. Whatever the game decides. */
|
|
53
|
+
readonly actor?: () => unknown;
|
|
54
|
+
/** Modes active at the start. Tools belong to modes (`play`, `edit`, `inspect`). Defaults to `["edit"]`. */
|
|
55
|
+
readonly modes?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* Turn pointer events on the map into interaction. Defaults to true as soon as a
|
|
58
|
+
* feature has something to interact with, false otherwise: a view that only
|
|
59
|
+
* draws never gets in the way of the clicks of a game.
|
|
60
|
+
*/
|
|
61
|
+
readonly interactive?: boolean;
|
|
62
|
+
/** How images are loaded. Defaults to PixiJS `Assets`. */
|
|
63
|
+
readonly textures?: TextureProvider;
|
|
64
|
+
readonly hooks?: MapViewHooks;
|
|
65
|
+
/** Extra effects, by name, next to the built-in `shake` and `blink`. */
|
|
66
|
+
readonly effects?: Readonly<Record<string, EffectDefinition>>;
|
|
67
|
+
/**
|
|
68
|
+
* Draw the sprites of the elements and events. Defaults to true. With `false` the view only keeps them as
|
|
69
|
+
* what can be picked and selected (their bounds and hitboxes), so that a game that draws the map itself can
|
|
70
|
+
* use the tools and the selection of the map builder without drawing everything twice. Nothing is loaded.
|
|
71
|
+
*/
|
|
72
|
+
readonly draw?: boolean;
|
|
73
|
+
/** Margin, in pixels, added around the viewport before something is hidden. Defaults to 64. */
|
|
74
|
+
readonly cullingMargin?: number;
|
|
75
|
+
/** Receives non-fatal problems. Defaults to `console.warn`, once per image. */
|
|
76
|
+
readonly onError?: (error: MapViewError) => void;
|
|
77
|
+
}
|
|
78
|
+
/** An element or event, as an effect target. A plain string is an element id. */
|
|
79
|
+
export type EffectTarget = string | {
|
|
80
|
+
readonly type: "element" | "event";
|
|
81
|
+
readonly id: string;
|
|
82
|
+
};
|
|
83
|
+
export interface MapViewEffects {
|
|
84
|
+
/**
|
|
85
|
+
* Plays a short visual effect. It does not touch the model, so it is neither
|
|
86
|
+
* persisted nor undoable. It never throws: see the status of `handle.finished`.
|
|
87
|
+
*/
|
|
88
|
+
play(target: EffectTarget, name: string, params?: EffectParams): EffectHandle;
|
|
89
|
+
register(name: string, definition: EffectDefinition): void;
|
|
90
|
+
clear(target?: EffectTarget): void;
|
|
91
|
+
readonly running: number;
|
|
92
|
+
}
|
|
93
|
+
export interface MapView<R extends MaybePromise<ApplyResult> = MaybePromise<ApplyResult>> {
|
|
94
|
+
/** Add this to any PixiJS stage (a `Application`, a CanvasEngine scene). */
|
|
95
|
+
readonly root: Container;
|
|
96
|
+
/** The headless layer: modes, tools, selection, pipelines. Observable through `interaction.state`. */
|
|
97
|
+
readonly interaction: InteractionController<R>;
|
|
98
|
+
/** Asks for something to be done: runs the pipeline, then applies. See {@link InteractionController.submit}. */
|
|
99
|
+
readonly submit: InteractionController<R>["submit"];
|
|
100
|
+
/** One container per stage, back to front. */
|
|
101
|
+
readonly stages: Readonly<Record<StageName, Container>>;
|
|
102
|
+
readonly effects: MapViewEffects;
|
|
103
|
+
/**
|
|
104
|
+
* Restricts drawing to a world rectangle (usually the camera view). What is
|
|
105
|
+
* outside, margin included, is hidden. `null` shows everything.
|
|
106
|
+
*/
|
|
107
|
+
setViewport(viewport: Rect | null): void;
|
|
108
|
+
/** Advances time. `mount` calls it every frame; call it yourself when you host `root`. */
|
|
109
|
+
tick(deltaMs: number): void;
|
|
110
|
+
/** Creates a PixiJS application in `host` and draws into it. */
|
|
111
|
+
mount(host: {
|
|
112
|
+
appendChild(node: never): unknown;
|
|
113
|
+
}, options?: MountOptions): Promise<void>;
|
|
114
|
+
/** Resolves once every image requested so far has loaded (or failed). */
|
|
115
|
+
whenIdle(): Promise<void>;
|
|
116
|
+
/** The nodes currently in the scene, as plain data. Useful for tests and tools. */
|
|
117
|
+
describe(): readonly SceneNode[];
|
|
118
|
+
destroy(): void;
|
|
119
|
+
}
|
|
120
|
+
export declare function createMapView<const F extends readonly MapFeature<string, object>[], R extends MaybePromise<ApplyResult> = ApplyResult>(options: MapViewOptions<F, R>): MapView<R> & FeatureApis<F>;
|
|
121
|
+
/**
|
|
122
|
+
* Hosts a view in an existing PixiJS container, typically the `componentInstance`
|
|
123
|
+
* of a CanvasEngine component. Returns the function that detaches it again, which
|
|
124
|
+
* is what the `mount` hook of CanvasEngine expects to return.
|
|
125
|
+
*
|
|
126
|
+
* ```ce
|
|
127
|
+
* <Container />
|
|
128
|
+
*
|
|
129
|
+
* <script>
|
|
130
|
+
* import { mount, tick } from "canvasengine";
|
|
131
|
+
* import { attachMapView } from "@rpgjs/map-builder/renderer";
|
|
132
|
+
*
|
|
133
|
+
* mount((element) => attachMapView(element.componentInstance, view));
|
|
134
|
+
* tick(({ deltaTime }) => view.tick(deltaTime));
|
|
135
|
+
* </script>
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export declare function attachMapView(container: Container, view: Pick<MapView, "root">): () => void;
|
|
139
|
+
//# sourceMappingURL=view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/renderer/view.ts"],"names":[],"mappings":"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"}
|