@datamoc/mw_games 0.30.0 → 0.33.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/CHANGELOG.md +86 -0
- package/README.md +1 -1
- package/api-surface.json +384 -0
- package/dist/assets/index.d.ts +2 -0
- package/dist/assets/index.d.ts.map +1 -1
- package/dist/assets/index.js +1 -0
- package/dist/assets/index.js.map +1 -1
- package/dist/assets/svg.d.ts +87 -0
- package/dist/assets/svg.d.ts.map +1 -0
- package/dist/assets/svg.js +162 -0
- package/dist/assets/svg.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mw_games.global.js +41 -41
- package/dist/mwl/fengari.d.ts +12 -6
- package/dist/mwl/fengari.d.ts.map +1 -1
- package/dist/mwl/fengari.js +56 -70
- package/dist/mwl/fengari.js.map +1 -1
- package/dist/mwl/runtime.d.ts +13 -0
- package/dist/mwl/runtime.d.ts.map +1 -1
- package/dist/mwl/runtime.js +72 -4
- package/dist/mwl/runtime.js.map +1 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/schema.js +4 -1
- package/dist/mwl/schema.js.map +1 -1
- package/dist/roguelike/Cave.d.ts +109 -0
- package/dist/roguelike/Cave.d.ts.map +1 -0
- package/dist/roguelike/Cave.js +192 -0
- package/dist/roguelike/Cave.js.map +1 -0
- package/dist/roguelike/Overworld.d.ts +82 -0
- package/dist/roguelike/Overworld.d.ts.map +1 -0
- package/dist/roguelike/Overworld.js +306 -0
- package/dist/roguelike/Overworld.js.map +1 -0
- package/dist/roguelike/index.d.ts +4 -0
- package/dist/roguelike/index.d.ts.map +1 -1
- package/dist/roguelike/index.js +2 -0
- package/dist/roguelike/index.js.map +1 -1
- package/dist/skeleton/index.d.ts +131 -0
- package/dist/skeleton/index.d.ts.map +1 -0
- package/dist/skeleton/index.js +206 -0
- package/dist/skeleton/index.js.map +1 -0
- package/dist/testing/SceneControls.d.ts +35 -0
- package/dist/testing/SceneControls.d.ts.map +1 -0
- package/dist/testing/SceneControls.js +49 -0
- package/dist/testing/SceneControls.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/two-d/render/Camera.d.ts +13 -3
- package/dist/two-d/render/Camera.d.ts.map +1 -1
- package/dist/two-d/render/Camera.js +35 -25
- package/dist/two-d/render/Camera.js.map +1 -1
- package/dist/two-d/render/SkeletalSprite.d.ts +118 -0
- package/dist/two-d/render/SkeletalSprite.d.ts.map +1 -0
- package/dist/two-d/render/SkeletalSprite.js +189 -0
- package/dist/two-d/render/SkeletalSprite.js.map +1 -0
- package/dist/two-d/render/SpriteMotion.d.ts +121 -0
- package/dist/two-d/render/SpriteMotion.d.ts.map +1 -0
- package/dist/two-d/render/SpriteMotion.js +193 -0
- package/dist/two-d/render/SpriteMotion.js.map +1 -0
- package/dist/two-d/render/index.d.ts +4 -0
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +2 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -2
- package/sbom.cdx.json +222 -222
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/roguelike/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/roguelike/index.ts"],"names":[],"mappings":"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"}
|
package/dist/roguelike/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { Level, WALL, FLOOR, rectCenter, rectsOverlap } from './Level.js';
|
|
2
2
|
export { generateDungeon, generateDungeonGraph, findFreeCell, furthestRoom, DUNGEON_KINDS } from './generate.js';
|
|
3
|
+
export { generateCave } from './Cave.js';
|
|
4
|
+
export { generateOverworld } from './Overworld.js';
|
|
3
5
|
export { hallBuilder, eligibleBuilders, pickBuilder } from './RoomBuilders.js';
|
|
4
6
|
export { FeatureLayer } from './Features.js';
|
|
5
7
|
export { rollRoster } from './ContentRoll.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/roguelike/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/roguelike/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAWnD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG/E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG/D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EACN,iBAAiB,EACjB,SAAS,EACT,UAAU,EACV,cAAc,EACd,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,YAAY,GACZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAEhH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASnD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeletal pose math, renderer-free: a bone tree, keyframed clips, and layered blending.
|
|
3
|
+
*
|
|
4
|
+
* The pose half of a skeletal puppet (roadmap 399), as pure data and arithmetic so it loads
|
|
5
|
+
* headless and tests without a renderer - the same split every other module draws. A bone
|
|
6
|
+
* is a name, a parent name, a length and a local rotation; a pose is one rotation per bone;
|
|
7
|
+
* resolving a pose walks the tree so rotating an arm, a leg or a head is one number on one
|
|
8
|
+
* bone and the rest of the body follows. Clips are keyframed poses over time - plain data a
|
|
9
|
+
* game authors in JSON, never code, and never a borrowed game's animation data - with
|
|
10
|
+
* interpolation, looping, a playback rate and a crossfade between clips. Additive layers
|
|
11
|
+
* (aim on top of walk, hurt on top of idle) mix by priority, so a game composes motion
|
|
12
|
+
* instead of authoring every combination as its own clip.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import * as Skeleton from '@datamoc/mw_games/skeleton';
|
|
17
|
+
*
|
|
18
|
+
* const puppet = Skeleton.create([
|
|
19
|
+
* { name: 'body' },
|
|
20
|
+
* { name: 'arm', parent: 'body', length: 12 },
|
|
21
|
+
* ]);
|
|
22
|
+
* const mixer = Skeleton.createMixer(puppet, { id: 'idle', duration: 2, loop: true, frames: [
|
|
23
|
+
* { time: 0, rotations: {} },
|
|
24
|
+
* { time: 1, rotations: { arm: 90 } },
|
|
25
|
+
* ] });
|
|
26
|
+
* Skeleton.advance(mixer, 1); // the arm swings up over one second
|
|
27
|
+
* const pose = Skeleton.advance(mixer, 1); // the arm swings up over one second
|
|
28
|
+
* const arm = Skeleton.resolve(puppet, pose)[1]; // world x, y and angle per bone
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export interface Bone {
|
|
32
|
+
/** unique within one skeleton */
|
|
33
|
+
name: string;
|
|
34
|
+
/** the parent bone's name; the roots have none */
|
|
35
|
+
parent?: string;
|
|
36
|
+
/** how far the bone reaches from its base, world units */
|
|
37
|
+
length?: number;
|
|
38
|
+
/** the bone's own offset from its parent's tip, before any pose */
|
|
39
|
+
origin?: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
};
|
|
43
|
+
/** the bone's rest rotation, degrees */
|
|
44
|
+
rotation?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface SkeletonBones {
|
|
47
|
+
bones: readonly Bone[];
|
|
48
|
+
}
|
|
49
|
+
/** one rotation per bone name, degrees; a bone left out keeps its rest rotation */
|
|
50
|
+
export type Pose = Readonly<Record<string, number>>;
|
|
51
|
+
export interface Keyframe {
|
|
52
|
+
/** seconds into the clip */
|
|
53
|
+
time: number;
|
|
54
|
+
rotations: Pose;
|
|
55
|
+
}
|
|
56
|
+
export interface Clip {
|
|
57
|
+
id: string;
|
|
58
|
+
/** seconds; a looping clip wraps at it, a one-shot holds its last frame */
|
|
59
|
+
duration: number;
|
|
60
|
+
loop?: boolean;
|
|
61
|
+
/** ascending by time; the first needs no time 0 entry, the last needs no duration entry */
|
|
62
|
+
frames: readonly Keyframe[];
|
|
63
|
+
}
|
|
64
|
+
/** a clip in motion: its playhead and rate */
|
|
65
|
+
export interface Playback {
|
|
66
|
+
clip: Clip;
|
|
67
|
+
time: number;
|
|
68
|
+
/** multiplied per advance; negative plays backwards, 0 freezes */
|
|
69
|
+
rate: number;
|
|
70
|
+
}
|
|
71
|
+
export interface Layer {
|
|
72
|
+
playback: Playback;
|
|
73
|
+
/** 0..1, how far this layer's pose displaces the pose beneath it */
|
|
74
|
+
weight: number;
|
|
75
|
+
/** layers apply in ascending priority; same-priority layers keep their given order */
|
|
76
|
+
priority: number;
|
|
77
|
+
}
|
|
78
|
+
export interface Mixer {
|
|
79
|
+
skeleton: SkeletonBones;
|
|
80
|
+
/** the base motion, always present */
|
|
81
|
+
base: Playback;
|
|
82
|
+
/** additive layers over the base */
|
|
83
|
+
layers: Layer[];
|
|
84
|
+
/** while set, the previous base fades out as the new one fades in */
|
|
85
|
+
crossfade?: {
|
|
86
|
+
from: Playback;
|
|
87
|
+
remaining: number;
|
|
88
|
+
duration: number;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export interface BoneTransform {
|
|
92
|
+
name: string;
|
|
93
|
+
/** the bone's base in world space */
|
|
94
|
+
x: number;
|
|
95
|
+
y: number;
|
|
96
|
+
/** the bone's angle in world space, degrees */
|
|
97
|
+
angle: number;
|
|
98
|
+
/** the bone's tip in world space, `length` along its angle */
|
|
99
|
+
tipX: number;
|
|
100
|
+
tipY: number;
|
|
101
|
+
}
|
|
102
|
+
/** names in dependency order: every bone after its parent, so resolution is one pass */
|
|
103
|
+
export declare function boneOrder(skeleton: SkeletonBones): string[];
|
|
104
|
+
/** create a skeleton, refusing duplicate names and cycles by name */
|
|
105
|
+
export declare function create(bones: readonly Bone[]): SkeletonBones;
|
|
106
|
+
/**
|
|
107
|
+
* A pose through the tree: each bone starts at its parent's tip plus its origin, rotated by
|
|
108
|
+
* its rest rotation plus its pose rotation plus every ancestor's world rotation.
|
|
109
|
+
*/
|
|
110
|
+
export declare function resolve(skeleton: SkeletonBones, pose?: Pose): BoneTransform[];
|
|
111
|
+
/** the pose a clip shows at `time`: its frames interpolated, looped or held */
|
|
112
|
+
export declare function samplePose(clip: Clip, time: number): Record<string, number>;
|
|
113
|
+
/** move a playback's playhead, wrapping a looping clip and clamping a one-shot */
|
|
114
|
+
export declare function advancePlayback(playback: Playback, dt: number): Playback;
|
|
115
|
+
/** a mixer over a skeleton: one base clip, any number of weighted layers */
|
|
116
|
+
export declare function createMixer(skeleton: SkeletonBones, base: Clip, rate?: number): Mixer;
|
|
117
|
+
/** crossfade: the current base fades out over `duration` seconds as the new one fades in */
|
|
118
|
+
export declare function crossfadeTo(mixer: Mixer, clip: Clip, duration?: number, rate?: number): void;
|
|
119
|
+
/** mix poses by layer priority: each layer displaces what is beneath it by its weight */
|
|
120
|
+
export declare function mixPoses(base: Pose, layers: ReadonlyArray<{
|
|
121
|
+
pose: Pose;
|
|
122
|
+
weight: number;
|
|
123
|
+
priority: number;
|
|
124
|
+
}>): Record<string, number>;
|
|
125
|
+
/**
|
|
126
|
+
* One tick: advance every playback, sample the base (crossfaded when a fade is running),
|
|
127
|
+
* layer the additive poses over it, and return the pose. Call `resolve` on the result when
|
|
128
|
+
* the world transforms are what the drawing side needs.
|
|
129
|
+
*/
|
|
130
|
+
export declare function advance(mixer: Mixer, dt: number): Record<string, number>;
|
|
131
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/skeleton/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeletal pose math, renderer-free: a bone tree, keyframed clips, and layered blending.
|
|
3
|
+
*
|
|
4
|
+
* The pose half of a skeletal puppet (roadmap 399), as pure data and arithmetic so it loads
|
|
5
|
+
* headless and tests without a renderer - the same split every other module draws. A bone
|
|
6
|
+
* is a name, a parent name, a length and a local rotation; a pose is one rotation per bone;
|
|
7
|
+
* resolving a pose walks the tree so rotating an arm, a leg or a head is one number on one
|
|
8
|
+
* bone and the rest of the body follows. Clips are keyframed poses over time - plain data a
|
|
9
|
+
* game authors in JSON, never code, and never a borrowed game's animation data - with
|
|
10
|
+
* interpolation, looping, a playback rate and a crossfade between clips. Additive layers
|
|
11
|
+
* (aim on top of walk, hurt on top of idle) mix by priority, so a game composes motion
|
|
12
|
+
* instead of authoring every combination as its own clip.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import * as Skeleton from '@datamoc/mw_games/skeleton';
|
|
17
|
+
*
|
|
18
|
+
* const puppet = Skeleton.create([
|
|
19
|
+
* { name: 'body' },
|
|
20
|
+
* { name: 'arm', parent: 'body', length: 12 },
|
|
21
|
+
* ]);
|
|
22
|
+
* const mixer = Skeleton.createMixer(puppet, { id: 'idle', duration: 2, loop: true, frames: [
|
|
23
|
+
* { time: 0, rotations: {} },
|
|
24
|
+
* { time: 1, rotations: { arm: 90 } },
|
|
25
|
+
* ] });
|
|
26
|
+
* Skeleton.advance(mixer, 1); // the arm swings up over one second
|
|
27
|
+
* const pose = Skeleton.advance(mixer, 1); // the arm swings up over one second
|
|
28
|
+
* const arm = Skeleton.resolve(puppet, pose)[1]; // world x, y and angle per bone
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
/** names in dependency order: every bone after its parent, so resolution is one pass */
|
|
32
|
+
export function boneOrder(skeleton) {
|
|
33
|
+
const byName = new Map(skeleton.bones.map((bone) => [bone.name, bone]));
|
|
34
|
+
const order = [];
|
|
35
|
+
const placed = new Set();
|
|
36
|
+
const visit = (bone) => {
|
|
37
|
+
if (placed.has(bone.name))
|
|
38
|
+
return;
|
|
39
|
+
if (bone.parent && !byName.has(bone.parent))
|
|
40
|
+
throw new Error(`skeleton bone ${bone.name} names no parent ${bone.parent}`);
|
|
41
|
+
if (bone.parent)
|
|
42
|
+
visit(byName.get(bone.parent));
|
|
43
|
+
if (!placed.has(bone.name)) {
|
|
44
|
+
placed.add(bone.name);
|
|
45
|
+
order.push(bone.name);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
for (const bone of skeleton.bones)
|
|
49
|
+
visit(bone);
|
|
50
|
+
return order;
|
|
51
|
+
}
|
|
52
|
+
/** create a skeleton, refusing duplicate names and cycles by name */
|
|
53
|
+
export function create(bones) {
|
|
54
|
+
const names = new Set();
|
|
55
|
+
for (const bone of bones) {
|
|
56
|
+
if (names.has(bone.name))
|
|
57
|
+
throw new Error(`duplicate skeleton bone ${bone.name}`);
|
|
58
|
+
names.add(bone.name);
|
|
59
|
+
}
|
|
60
|
+
const order = boneOrder({ bones });
|
|
61
|
+
//boneOrder throws on a missing parent, which is also what a cycle surfaces as here
|
|
62
|
+
for (const bone of bones)
|
|
63
|
+
if (bone.parent && order.indexOf(bone.parent) >= order.indexOf(bone.name))
|
|
64
|
+
throw new Error(`skeleton bone ${bone.name} cannot precede its parent ${bone.parent}`);
|
|
65
|
+
return { bones };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A pose through the tree: each bone starts at its parent's tip plus its origin, rotated by
|
|
69
|
+
* its rest rotation plus its pose rotation plus every ancestor's world rotation.
|
|
70
|
+
*/
|
|
71
|
+
export function resolve(skeleton, pose = {}) {
|
|
72
|
+
const byName = new Map(skeleton.bones.map((bone) => [bone.name, bone]));
|
|
73
|
+
const world = new Map();
|
|
74
|
+
for (const name of boneOrder(skeleton)) {
|
|
75
|
+
const bone = byName.get(name);
|
|
76
|
+
const parent = bone.parent ? world.get(bone.parent) : undefined;
|
|
77
|
+
const rotation = (bone.rotation ?? 0) + (pose[name] ?? 0);
|
|
78
|
+
const angle = parent ? parent.angle + rotation : rotation;
|
|
79
|
+
const originX = bone.origin?.x ?? 0;
|
|
80
|
+
const originY = bone.origin?.y ?? 0;
|
|
81
|
+
const x = parent ? parent.tipX : 0;
|
|
82
|
+
const y = parent ? parent.tipY : 0;
|
|
83
|
+
const radians = (angle * Math.PI) / 180;
|
|
84
|
+
world.set(name, {
|
|
85
|
+
name,
|
|
86
|
+
x,
|
|
87
|
+
y,
|
|
88
|
+
angle,
|
|
89
|
+
tipX: x + originX + Math.cos(radians) * (bone.length ?? 0),
|
|
90
|
+
tipY: y + originY + Math.sin(radians) * (bone.length ?? 0),
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return [...world.values()];
|
|
94
|
+
}
|
|
95
|
+
/** the pose a clip shows at `time`: its frames interpolated, looped or held */
|
|
96
|
+
export function samplePose(clip, time) {
|
|
97
|
+
const frames = clip.frames;
|
|
98
|
+
if (frames.length === 0)
|
|
99
|
+
return {};
|
|
100
|
+
let clock = time;
|
|
101
|
+
if (clip.loop && clip.duration > 0) {
|
|
102
|
+
clock = clock % clip.duration;
|
|
103
|
+
if (clock < 0)
|
|
104
|
+
clock += clip.duration;
|
|
105
|
+
}
|
|
106
|
+
else if (clock >= clip.duration) {
|
|
107
|
+
//a one-shot holds its last frame past the end
|
|
108
|
+
return { ...frames[frames.length - 1].rotations };
|
|
109
|
+
}
|
|
110
|
+
else if (clock < 0) {
|
|
111
|
+
return { ...frames[0].rotations };
|
|
112
|
+
}
|
|
113
|
+
let previous = frames[0];
|
|
114
|
+
for (let index = 1; index < frames.length; index++) {
|
|
115
|
+
if (frames[index].time > clock) {
|
|
116
|
+
const span = frames[index].time - previous.time;
|
|
117
|
+
const t = span > 0 ? (clock - previous.time) / span : 0;
|
|
118
|
+
const pose = {};
|
|
119
|
+
const names = new Set([...Object.keys(previous.rotations), ...Object.keys(frames[index].rotations)]);
|
|
120
|
+
for (const name of names) {
|
|
121
|
+
const from = previous.rotations[name] ?? 0;
|
|
122
|
+
const to = frames[index].rotations[name] ?? 0;
|
|
123
|
+
pose[name] = from + (to - from) * t;
|
|
124
|
+
}
|
|
125
|
+
return pose;
|
|
126
|
+
}
|
|
127
|
+
previous = frames[index];
|
|
128
|
+
}
|
|
129
|
+
return { ...previous.rotations };
|
|
130
|
+
}
|
|
131
|
+
/** move a playback's playhead, wrapping a looping clip and clamping a one-shot */
|
|
132
|
+
export function advancePlayback(playback, dt) {
|
|
133
|
+
const clip = playback.clip;
|
|
134
|
+
let time = playback.time + dt * playback.rate;
|
|
135
|
+
if (clip.loop && clip.duration > 0) {
|
|
136
|
+
time = time % clip.duration;
|
|
137
|
+
if (time < 0)
|
|
138
|
+
time += clip.duration;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
time = Math.max(0, Math.min(clip.duration, time));
|
|
142
|
+
}
|
|
143
|
+
return { clip, time, rate: playback.rate };
|
|
144
|
+
}
|
|
145
|
+
/** a mixer over a skeleton: one base clip, any number of weighted layers */
|
|
146
|
+
export function createMixer(skeleton, base, rate = 1) {
|
|
147
|
+
return { skeleton, base: { clip: base, time: 0, rate }, layers: [] };
|
|
148
|
+
}
|
|
149
|
+
/** crossfade: the current base fades out over `duration` seconds as the new one fades in */
|
|
150
|
+
export function crossfadeTo(mixer, clip, duration = 0.25, rate = mixer.base.rate) {
|
|
151
|
+
if (duration <= 0) {
|
|
152
|
+
mixer.base = { clip, time: 0, rate };
|
|
153
|
+
mixer.crossfade = undefined;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
mixer.crossfade = { from: mixer.base, remaining: duration, duration };
|
|
157
|
+
mixer.base = { clip, time: 0, rate };
|
|
158
|
+
}
|
|
159
|
+
/** mix poses by layer priority: each layer displaces what is beneath it by its weight */
|
|
160
|
+
export function mixPoses(base, layers) {
|
|
161
|
+
const mixed = { ...base };
|
|
162
|
+
const sorted = [...layers].sort((a, b) => a.priority - b.priority);
|
|
163
|
+
for (const layer of sorted) {
|
|
164
|
+
const weight = Math.max(0, Math.min(1, layer.weight));
|
|
165
|
+
if (weight === 0)
|
|
166
|
+
continue;
|
|
167
|
+
//a layer displaces only the bones it names: an unnamed bone keeps whatever
|
|
168
|
+
//the layers beneath it decided, so 'aim' never resets the legs to rest
|
|
169
|
+
for (const name of Object.keys(layer.pose)) {
|
|
170
|
+
const from = mixed[name] ?? 0;
|
|
171
|
+
const to = layer.pose[name];
|
|
172
|
+
mixed[name] = from + (to - from) * weight;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return mixed;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* One tick: advance every playback, sample the base (crossfaded when a fade is running),
|
|
179
|
+
* layer the additive poses over it, and return the pose. Call `resolve` on the result when
|
|
180
|
+
* the world transforms are what the drawing side needs.
|
|
181
|
+
*/
|
|
182
|
+
export function advance(mixer, dt) {
|
|
183
|
+
mixer.base = advancePlayback(mixer.base, dt);
|
|
184
|
+
for (const layer of mixer.layers)
|
|
185
|
+
layer.playback = advancePlayback(layer.playback, dt);
|
|
186
|
+
let pose = samplePose(mixer.base.clip, mixer.base.time);
|
|
187
|
+
if (mixer.crossfade) {
|
|
188
|
+
const fade = mixer.crossfade;
|
|
189
|
+
fade.from = advancePlayback(fade.from, dt);
|
|
190
|
+
fade.remaining = Math.max(0, fade.remaining - dt);
|
|
191
|
+
const outgoing = samplePose(fade.from.clip, fade.from.time);
|
|
192
|
+
const t = fade.duration > 0 ? 1 - fade.remaining / fade.duration : 1;
|
|
193
|
+
const blended = {};
|
|
194
|
+
for (const name of new Set([...Object.keys(outgoing), ...Object.keys(pose)]))
|
|
195
|
+
blended[name] = (outgoing[name] ?? 0) * (1 - t) + (pose[name] ?? 0) * t;
|
|
196
|
+
pose = blended;
|
|
197
|
+
if (fade.remaining === 0)
|
|
198
|
+
mixer.crossfade = undefined;
|
|
199
|
+
}
|
|
200
|
+
return mixPoses(pose, mixer.layers.map((layer) => ({
|
|
201
|
+
pose: samplePose(layer.playback.clip, layer.playback.time),
|
|
202
|
+
weight: layer.weight,
|
|
203
|
+
priority: layer.priority,
|
|
204
|
+
})));
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/skeleton/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A scene control API for tests (roadmap 408): named steps a game opts into, driven by name.
|
|
3
|
+
*
|
|
4
|
+
* A game's own scene flow - enter a scenario, finish a turn, advance a dialogue - is private
|
|
5
|
+
* to the game, and that is the point of this seam: instead of the framework reaching into a
|
|
6
|
+
* game, the game registers the steps it wants a test or a headless Chrome to be able to
|
|
7
|
+
* drive, by name, on a `SceneControls`. The game decides what a step does; the controls only
|
|
8
|
+
* promise that a registered name runs its step and an unknown name is refused by name.
|
|
9
|
+
*
|
|
10
|
+
* Kept off the root barrel with the rest of `src/testing`: nothing here reaches a shipped
|
|
11
|
+
* game unless a test imports it.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createSceneControls } from '@datamoc/mw_games/testing';
|
|
16
|
+
*
|
|
17
|
+
* const controls = createSceneControls();
|
|
18
|
+
* const enterScenario = (name: string) => {}; // the game's own private scene flow
|
|
19
|
+
* controls.register('enterScenario', () => enterScenario('the-freelands'));
|
|
20
|
+
* controls.register('finishTurn', () => {});
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type SceneStep = () => void | Promise<void>;
|
|
24
|
+
export interface SceneControls {
|
|
25
|
+
/** one step by name; a duplicate name is refused rather than overwritten */
|
|
26
|
+
register(step: string, run: SceneStep): void;
|
|
27
|
+
/** whether a step is registered */
|
|
28
|
+
has(step: string): boolean;
|
|
29
|
+
/** every registered name, in registration order */
|
|
30
|
+
steps(): string[];
|
|
31
|
+
/** run one step, refusing an unknown name; awaits a step that returns a promise */
|
|
32
|
+
run(step: string): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export declare function createSceneControls(): SceneControls;
|
|
35
|
+
//# sourceMappingURL=SceneControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneControls.d.ts","sourceRoot":"","sources":["../../src/testing/SceneControls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7C,mCAAmC;IACnC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,mDAAmD;IACnD,KAAK,IAAI,MAAM,EAAE,CAAC;IAClB,mFAAmF;IACnF,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,wBAAgB,mBAAmB,IAAI,aAAa,CAsBnD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A scene control API for tests (roadmap 408): named steps a game opts into, driven by name.
|
|
3
|
+
*
|
|
4
|
+
* A game's own scene flow - enter a scenario, finish a turn, advance a dialogue - is private
|
|
5
|
+
* to the game, and that is the point of this seam: instead of the framework reaching into a
|
|
6
|
+
* game, the game registers the steps it wants a test or a headless Chrome to be able to
|
|
7
|
+
* drive, by name, on a `SceneControls`. The game decides what a step does; the controls only
|
|
8
|
+
* promise that a registered name runs its step and an unknown name is refused by name.
|
|
9
|
+
*
|
|
10
|
+
* Kept off the root barrel with the rest of `src/testing`: nothing here reaches a shipped
|
|
11
|
+
* game unless a test imports it.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { createSceneControls } from '@datamoc/mw_games/testing';
|
|
16
|
+
*
|
|
17
|
+
* const controls = createSceneControls();
|
|
18
|
+
* const enterScenario = (name: string) => {}; // the game's own private scene flow
|
|
19
|
+
* controls.register('enterScenario', () => enterScenario('the-freelands'));
|
|
20
|
+
* controls.register('finishTurn', () => {});
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function createSceneControls() {
|
|
24
|
+
const registry = new Map();
|
|
25
|
+
const order = [];
|
|
26
|
+
return {
|
|
27
|
+
register(step, run) {
|
|
28
|
+
if (!step)
|
|
29
|
+
throw new Error('a scene control step needs a name');
|
|
30
|
+
if (registry.has(step))
|
|
31
|
+
throw new Error(`scene control step already registered: ${step}`);
|
|
32
|
+
registry.set(step, run);
|
|
33
|
+
order.push(step);
|
|
34
|
+
},
|
|
35
|
+
has(step) {
|
|
36
|
+
return registry.has(step);
|
|
37
|
+
},
|
|
38
|
+
steps() {
|
|
39
|
+
return [...order];
|
|
40
|
+
},
|
|
41
|
+
async run(step) {
|
|
42
|
+
const run2 = registry.get(step);
|
|
43
|
+
if (!run2)
|
|
44
|
+
throw new Error(`scene control step is not registered: ${step}`);
|
|
45
|
+
await run2();
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=SceneControls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SceneControls.js","sourceRoot":"","sources":["../../src/testing/SceneControls.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAeH,MAAM,UAAU,mBAAmB;IAClC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,OAAO;QACN,QAAQ,CAAC,IAAI,EAAE,GAAG;YACjB,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAChE,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;YAC1F,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QACD,GAAG,CAAC,IAAI;YACP,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK;YACJ,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;QACnB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,IAAI;YACb,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;YAC5E,MAAM,IAAI,EAAE,CAAC;QACd,CAAC;KACD,CAAC;AACH,CAAC"}
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -102,4 +102,6 @@ export declare function fakeFetch(respond: (url: string, init?: RequestInit) =>
|
|
|
102
102
|
* would.
|
|
103
103
|
*/
|
|
104
104
|
export declare function fakeGamepad(index: number, buttons?: number[], axes?: number[]): Gamepad;
|
|
105
|
+
export { createSceneControls } from './SceneControls.ts';
|
|
106
|
+
export type { SceneControls, SceneStep } from './SceneControls.ts';
|
|
105
107
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,IAAI,WAAW,CAE3C;AAED,wDAAwD;AACxD,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAexC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC/C,UAAU,SAAK;IACf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAM;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IACjD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAClD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAClD,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAE7D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvB;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE9B;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE7B;CACD;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,GACnD,OAAO,UAAU,CAAC,KAAK,GAAG;IAAE,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,CAStD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAM/F"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,IAAI,WAAW,CAE3C;AAED,wDAAwD;AACxD,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAexC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAEjD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,UAAW,YAAW,aAAa;IAC/C,UAAU,SAAK;IACf,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,CAAM;IAC7B,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IACjD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAClD,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAClD,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAQ;IAE7D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEvB;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE9B;IAED,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAE7B;CACD;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,GACnD,OAAO,UAAU,CAAC,KAAK,GAAG;IAAE,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,CAStD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAM,EAAO,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,OAAO,CAM/F;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/testing/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,iBAAiB,CAAC;AAIlE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa;IAC5B,OAAO,IAAI,aAAa,EAAE,CAAC;AAC5B,CAAC;AAQD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS;IACxB,OAAO;QACN,SAAS,EAAE,CAAC;QACZ,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,CAAC;QACT,WAAW,EAAE,CAAC;QACd,IAAI,EAAE,KAAK;QACX,IAAI;YACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,KAAK;YACJ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IACjC,OAAO,EAAE,GAAG,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,UAAU;IAAvB;QACC,eAAU,GAAG,CAAC,CAAC;QACN,SAAI,GAAa,EAAE,CAAC;QAC7B,WAAM,GAAsC,IAAI,CAAC;QACjD,YAAO,GAAsC,IAAI,CAAC;QAClD,YAAO,GAAsC,IAAI,CAAC;QAClD,cAAS,GAA+C,IAAI,CAAC;IAkB9D,CAAC;IAhBA,IAAI,CAAC,IAAY;QAChB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,CAAC,OAAgB;QACvB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,UAAU,CAAC,IAAY;QACtB,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;CACD;AAQD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CACxB,OAAqD;IAErD,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,KAAK,EAAE,KAAwB,EAAE,IAAkB,EAAE,EAAE;QACpE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACxC,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACpG,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,KAAgC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,OAAO,GAAa,EAAE,EAAE,IAAI,GAAa,EAAE;IACrF,OAAO;QACN,KAAK;QACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,GAAG,EAAE,OAAO,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACxF,IAAI;KACkB,CAAC;AACzB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,6 +66,12 @@ export interface CameraOptions {
|
|
|
66
66
|
* its source, without a per-tile sampling flag.
|
|
67
67
|
*/
|
|
68
68
|
pixelPerfectTileSize?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Device pixels per CSS pixel, read live. `apply()` rounds the screen offset, and
|
|
71
|
+
* `pixelPerfectTileSize` snaps zoom, to whole *device* pixels at this ratio. Defaults to 1;
|
|
72
|
+
* `createCamera` supplies the running renderer's resolution.
|
|
73
|
+
*/
|
|
74
|
+
resolution?: () => number;
|
|
69
75
|
}
|
|
70
76
|
/**
|
|
71
77
|
* @example
|
|
@@ -92,7 +98,8 @@ export declare class Camera {
|
|
|
92
98
|
/** centre of the view, in world units */
|
|
93
99
|
x: number;
|
|
94
100
|
y: number;
|
|
95
|
-
private
|
|
101
|
+
private requestedZoom;
|
|
102
|
+
private readonly resolution;
|
|
96
103
|
private deadzone;
|
|
97
104
|
private readonly pixelPerfectTileSize?;
|
|
98
105
|
private viewWidth;
|
|
@@ -145,6 +152,7 @@ export declare class Camera {
|
|
|
145
152
|
animateRotationTo(angle: number, intensity?: number): void;
|
|
146
153
|
/** cos/sin of the current rotation, the shared arithmetic `toScreen`/`toWorld`/`view` use */
|
|
147
154
|
private get spin();
|
|
155
|
+
/** snapped on every read, not on set, so a resolution change (a `QualityScaler` step) is followed */
|
|
148
156
|
get zoom(): number;
|
|
149
157
|
set zoom(value: number);
|
|
150
158
|
/**
|
|
@@ -211,9 +219,11 @@ export declare class Camera {
|
|
|
211
219
|
};
|
|
212
220
|
private clampedCentre;
|
|
213
221
|
private apply;
|
|
222
|
+
private snapToDevice;
|
|
214
223
|
}
|
|
215
224
|
/**
|
|
216
|
-
* The nearest zoom to `zoom` at which `tileSize * zoom` is a whole number of
|
|
225
|
+
* The nearest zoom to `zoom` at which `tileSize * zoom` is a whole number of device pixels
|
|
226
|
+
* (`resolution` device pixels per screen pixel, default 1) -
|
|
217
227
|
* the pure math behind `CameraOptions.pixelPerfectTileSize`, exported so a game can snap a
|
|
218
228
|
* zoom value (from a slider, say) before ever handing it to a `Camera`.
|
|
219
229
|
*
|
|
@@ -224,7 +234,7 @@ export declare class Camera {
|
|
|
224
234
|
* console.log(snapZoom(2.4, 16)); // 2.375 - 16 * 2.375 = 38, a whole number of pixels
|
|
225
235
|
* ```
|
|
226
236
|
*/
|
|
227
|
-
export declare function snapZoom(zoom: number, tileSize: number): number;
|
|
237
|
+
export declare function snapZoom(zoom: number, tileSize: number, resolution?: number): number;
|
|
228
238
|
/**
|
|
229
239
|
* a camera sized to the running game's viewport, updated on every frame
|
|
230
240
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Camera.d.ts","sourceRoot":"","sources":["../../../src/two-d/render/Camera.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,WAAW,aAAa;IAC7B,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAExB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;;;;;OAWG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"Camera.d.ts","sourceRoot":"","sources":["../../../src/two-d/render/Camera.ts"],"names":[],"mappings":"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"}
|