@debuffjp/juice 0.0.0-stage → 0.2.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/README.md +27 -2
- package/dist/draw-like.d.ts +9 -0
- package/dist/draw-like.d.ts.map +1 -0
- package/dist/draw-like.js +2 -0
- package/dist/draw-like.js.map +1 -0
- package/dist/ease.d.ts +15 -0
- package/dist/ease.d.ts.map +1 -0
- package/dist/ease.js +28 -0
- package/dist/ease.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/particles.d.ts +42 -0
- package/dist/particles.d.ts.map +1 -0
- package/dist/particles.js +85 -0
- package/dist/particles.js.map +1 -0
- package/dist/recipes.d.ts +9 -0
- package/dist/recipes.d.ts.map +1 -0
- package/dist/recipes.js +9 -0
- package/dist/recipes.js.map +1 -0
- package/dist/trail.d.ts +14 -0
- package/dist/trail.d.ts.map +1 -0
- package/dist/trail.js +38 -0
- package/dist/trail.js.map +1 -0
- package/dist/tween.d.ts +31 -0
- package/dist/tween.d.ts.map +1 -0
- package/dist/tween.js +86 -0
- package/dist/tween.js.map +1 -0
- package/package.json +46 -4
package/README.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @debuffjp/juice
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Game-feel building blocks: tweens, easing, pooled particles, trails and squash-and-stretch. No dependencies, and each export can be used on its own.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { Particles, squash, Tweens } from "@debuffjp/juice";
|
|
7
|
+
|
|
8
|
+
const tweens = new Tweens();
|
|
9
|
+
const particles = new Particles(() => game.random.next()); // seeded, so captures are reproducible
|
|
10
|
+
|
|
11
|
+
// on impact
|
|
12
|
+
squash(tweens, player, 0.35);
|
|
13
|
+
particles.emit({ x, y, count: 16, colors: ["#ffd166", "#ef476f"], gravity: 200 });
|
|
14
|
+
game.camera.shake(0.3);
|
|
15
|
+
game.freeze(0.06); // hit-stop
|
|
16
|
+
|
|
17
|
+
// every step
|
|
18
|
+
tweens.update(dt);
|
|
19
|
+
particles.update(dt);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## API
|
|
23
|
+
|
|
24
|
+
- `Tweens`: `to(target, props, { duration, ease, delay, yoyo, repeat, onComplete })` → `{ done, cancel(), finished }`, `kill(target)`, `update(dt)`
|
|
25
|
+
- `ease`: `linear`, `in/out/inOutQuad`, `in/out/inOutCubic`, `outBack`, `outElastic`, `outBounce`
|
|
26
|
+
- `Particles`: `emit({ x, y, count, speed, angle, spread, life, size, sizeEnd, colors, gravity, drag, shape, additive })`, `update(dt)`, `draw(draw)`, `clear()`
|
|
27
|
+
- `Trail`: `push(x, y)`, `draw(draw)`, `clear()`
|
|
28
|
+
- `squash(tweens, target, amount?, duration?)`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** The parts of `@debuffjp/core`'s `Draw` that juice effects use. Structural, so juice has no dependencies. */
|
|
2
|
+
export interface DrawLike {
|
|
3
|
+
alpha: number;
|
|
4
|
+
rect(x: number, y: number, w: number, h: number, color: string | number): void;
|
|
5
|
+
circle(x: number, y: number, radius: number, color: string | number): void;
|
|
6
|
+
line(x1: number, y1: number, x2: number, y2: number, width: number, color: string | number): void;
|
|
7
|
+
blend(mode: "normal" | "add"): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=draw-like.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw-like.d.ts","sourceRoot":"","sources":["../src/draw-like.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAC/G,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC/E,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3E,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClG,KAAK,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draw-like.js","sourceRoot":"","sources":["../src/draw-like.ts"],"names":[],"mappings":""}
|
package/dist/ease.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type Easing = (t: number) => number;
|
|
2
|
+
export declare const ease: {
|
|
3
|
+
linear: (t: number) => number;
|
|
4
|
+
inQuad: (t: number) => number;
|
|
5
|
+
outQuad: (t: number) => number;
|
|
6
|
+
inOutQuad: (t: number) => number;
|
|
7
|
+
inCubic: (t: number) => number;
|
|
8
|
+
outCubic: (t: number) => number;
|
|
9
|
+
inOutCubic: (t: number) => number;
|
|
10
|
+
outBack: (t: number) => number;
|
|
11
|
+
outElastic: (t: number) => number;
|
|
12
|
+
outBounce: (t: number) => number;
|
|
13
|
+
};
|
|
14
|
+
export type EaseName = keyof typeof ease;
|
|
15
|
+
//# sourceMappingURL=ease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ease.d.ts","sourceRoot":"","sources":["../src/ease.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;AAE3C,eAAO,MAAM,IAAI;;;;;;;;;;;CAyBiB,CAAC;AAEnC,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,IAAI,CAAC"}
|
package/dist/ease.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const ease = {
|
|
2
|
+
linear: (t) => t,
|
|
3
|
+
inQuad: (t) => t * t,
|
|
4
|
+
outQuad: (t) => t * (2 - t),
|
|
5
|
+
inOutQuad: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),
|
|
6
|
+
inCubic: (t) => t * t * t,
|
|
7
|
+
outCubic: (t) => 1 - (1 - t) ** 3,
|
|
8
|
+
inOutCubic: (t) => (t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2),
|
|
9
|
+
outBack: (t) => 1 + 2.70158 * (t - 1) ** 3 + 1.70158 * (t - 1) ** 2,
|
|
10
|
+
outElastic: (t) => (t === 0 || t === 1 ? t : 2 ** (-10 * t) * Math.sin((t * 10 - 0.75) * ((2 * Math.PI) / 3)) + 1),
|
|
11
|
+
outBounce: (t) => {
|
|
12
|
+
const n = 7.5625;
|
|
13
|
+
const d = 2.75;
|
|
14
|
+
if (t < 1 / d)
|
|
15
|
+
return n * t * t;
|
|
16
|
+
if (t < 2 / d) {
|
|
17
|
+
const u = t - 1.5 / d;
|
|
18
|
+
return n * u * u + 0.75;
|
|
19
|
+
}
|
|
20
|
+
if (t < 2.5 / d) {
|
|
21
|
+
const u = t - 2.25 / d;
|
|
22
|
+
return n * u * u + 0.9375;
|
|
23
|
+
}
|
|
24
|
+
const u = t - 2.625 / d;
|
|
25
|
+
return n * u * u + 0.984375;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=ease.js.map
|
package/dist/ease.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ease.js","sourceRoot":"","sources":["../src/ease.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChB,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC;IACpB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC3B,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxE,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IACnE,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClH,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,MAAM,CAAC,GAAG,MAAM,CAAC;QACjB,MAAM,CAAC,GAAG,IAAI,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACd,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QAC5B,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;IAC9B,CAAC;CAC+B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type { DrawLike } from "./draw-like.js";
|
|
2
|
+
export { type EaseName, type Easing, ease } from "./ease.js";
|
|
3
|
+
export { type EmitOptions, Particles, type RandomSource } from "./particles.js";
|
|
4
|
+
export { type Squashable, squash } from "./recipes.js";
|
|
5
|
+
export { Trail } from "./trail.js";
|
|
6
|
+
export { type Tween, type TweenOptions, Tweens } from "./tween.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,KAAK,WAAW,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAoB,SAAS,EAAqB,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAmB,MAAM,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAiC,MAAM,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { DrawLike } from "./draw-like.js";
|
|
2
|
+
/** Pooled particle system drawn as rects or circles. Particles live in world space;
|
|
3
|
+
* draw inside the camera transform. */
|
|
4
|
+
export interface EmitOptions {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
count?: number;
|
|
8
|
+
/** Speed range in px/s. */
|
|
9
|
+
speed?: [number, number];
|
|
10
|
+
/** Direction in radians and spread around it. Default: full circle. */
|
|
11
|
+
angle?: number;
|
|
12
|
+
spread?: number;
|
|
13
|
+
/** Lifetime range in seconds. */
|
|
14
|
+
life?: [number, number];
|
|
15
|
+
/** Size range in px; shrinks to `sizeEnd` (fraction of start) over life. */
|
|
16
|
+
size?: [number, number];
|
|
17
|
+
sizeEnd?: number;
|
|
18
|
+
colors?: readonly string[];
|
|
19
|
+
/** Downward acceleration px/s². */
|
|
20
|
+
gravity?: number;
|
|
21
|
+
/** Velocity multiplier per second (0.1 = strong drag). */
|
|
22
|
+
drag?: number;
|
|
23
|
+
shape?: "rect" | "circle";
|
|
24
|
+
/** Additive blending for glows. */
|
|
25
|
+
additive?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export type RandomSource = () => number;
|
|
28
|
+
export declare class Particles {
|
|
29
|
+
private readonly random;
|
|
30
|
+
readonly max: number;
|
|
31
|
+
private readonly live;
|
|
32
|
+
private readonly pool;
|
|
33
|
+
/** @param random Supply the game's seeded RNG for reproducible effects. */
|
|
34
|
+
constructor(random?: RandomSource, max?: number);
|
|
35
|
+
get count(): number;
|
|
36
|
+
emit(o: EmitOptions): void;
|
|
37
|
+
update(dt: number): void;
|
|
38
|
+
/** Draw in the current transform (e.g. inside `draw.withCamera`). Additive particles batch together. */
|
|
39
|
+
draw(draw: DrawLike): void;
|
|
40
|
+
clear(): void;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=particles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;wCACwC;AACxC,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2BAA2B;IAC3B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAkBD,MAAM,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC;AAExC,qBAAa,SAAS;IAMlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,QAAQ,CAAC,GAAG;IANd,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkB;IAEvC,2EAA2E;IAC3E,YACmB,MAAM,GAAE,YAA0B,EAC1C,GAAG,SAAO,EACjB;IAEJ,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,IAAI,CAuBzB;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAkBvB;IAED,wGAAwG;IACxG,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAgBzB;IAED,KAAK,IAAI,IAAI,CAGZ;CACF"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export class Particles {
|
|
2
|
+
random;
|
|
3
|
+
max;
|
|
4
|
+
live = [];
|
|
5
|
+
pool = [];
|
|
6
|
+
/** @param random Supply the game's seeded RNG for reproducible effects. */
|
|
7
|
+
constructor(random = Math.random, max = 2000) {
|
|
8
|
+
this.random = random;
|
|
9
|
+
this.max = max;
|
|
10
|
+
}
|
|
11
|
+
get count() {
|
|
12
|
+
return this.live.length;
|
|
13
|
+
}
|
|
14
|
+
emit(o) {
|
|
15
|
+
const r = this.random;
|
|
16
|
+
const range = (v) => v[0] + (v[1] - v[0]) * r();
|
|
17
|
+
const count = o.count ?? 10;
|
|
18
|
+
const colors = o.colors ?? ["#fff"];
|
|
19
|
+
for (let i = 0; i < count && this.live.length < this.max; i++) {
|
|
20
|
+
const p = this.pool.pop() ?? {};
|
|
21
|
+
const angle = (o.angle ?? 0) + (r() - 0.5) * (o.spread ?? Math.PI * 2);
|
|
22
|
+
const speed = range(o.speed ?? [40, 120]);
|
|
23
|
+
p.x = o.x;
|
|
24
|
+
p.y = o.y;
|
|
25
|
+
p.vx = Math.cos(angle) * speed;
|
|
26
|
+
p.vy = Math.sin(angle) * speed;
|
|
27
|
+
p.maxLife = p.life = range(o.life ?? [0.3, 0.6]);
|
|
28
|
+
p.size = range(o.size ?? [2, 4]);
|
|
29
|
+
p.sizeEnd = o.sizeEnd ?? 0;
|
|
30
|
+
p.color = colors[Math.floor(r() * colors.length)] ?? "#fff";
|
|
31
|
+
p.gravity = o.gravity ?? 0;
|
|
32
|
+
p.drag = o.drag ?? 1;
|
|
33
|
+
p.circle = o.shape === "circle";
|
|
34
|
+
p.additive = o.additive ?? false;
|
|
35
|
+
this.live.push(p);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
update(dt) {
|
|
39
|
+
for (let i = this.live.length - 1; i >= 0; i--) {
|
|
40
|
+
const p = this.live[i];
|
|
41
|
+
if (!p)
|
|
42
|
+
continue;
|
|
43
|
+
p.life -= dt;
|
|
44
|
+
if (p.life <= 0) {
|
|
45
|
+
// Swap-remove to avoid shifting.
|
|
46
|
+
const last = this.live.pop();
|
|
47
|
+
if (last && last !== p)
|
|
48
|
+
this.live[i] = last;
|
|
49
|
+
this.pool.push(p);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const d = p.drag === 1 ? 1 : p.drag ** dt;
|
|
53
|
+
p.vx *= d;
|
|
54
|
+
p.vy = p.vy * d + p.gravity * dt;
|
|
55
|
+
p.x += p.vx * dt;
|
|
56
|
+
p.y += p.vy * dt;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Draw in the current transform (e.g. inside `draw.withCamera`). Additive particles batch together. */
|
|
60
|
+
draw(draw) {
|
|
61
|
+
const baseAlpha = draw.alpha;
|
|
62
|
+
let additive = false;
|
|
63
|
+
for (const p of this.live) {
|
|
64
|
+
if (p.additive !== additive) {
|
|
65
|
+
additive = p.additive;
|
|
66
|
+
draw.blend(additive ? "add" : "normal");
|
|
67
|
+
}
|
|
68
|
+
const t = p.life / p.maxLife;
|
|
69
|
+
const s = p.size * (p.sizeEnd + (1 - p.sizeEnd) * t);
|
|
70
|
+
draw.alpha = baseAlpha * Math.min(1, t * 2);
|
|
71
|
+
if (p.circle)
|
|
72
|
+
draw.circle(p.x, p.y, s / 2, p.color);
|
|
73
|
+
else
|
|
74
|
+
draw.rect(p.x - s / 2, p.y - s / 2, s, s, p.color);
|
|
75
|
+
}
|
|
76
|
+
if (additive)
|
|
77
|
+
draw.blend("normal");
|
|
78
|
+
draw.alpha = baseAlpha;
|
|
79
|
+
}
|
|
80
|
+
clear() {
|
|
81
|
+
this.pool.push(...this.live);
|
|
82
|
+
this.live.length = 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=particles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"particles.js","sourceRoot":"","sources":["../src/particles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Tween, Tweens } from "./tween.js";
|
|
2
|
+
export interface Squashable {
|
|
3
|
+
scaleX: number;
|
|
4
|
+
scaleY: number;
|
|
5
|
+
}
|
|
6
|
+
/** Squash-and-stretch: snap to a deformed scale then spring back to 1.
|
|
7
|
+
* `amount` > 0 squashes (wide/short, e.g. landing), < 0 stretches (tall/thin, e.g. jump). */
|
|
8
|
+
export declare function squash(tweens: Tweens, target: Squashable, amount?: number, duration?: number): Tween;
|
|
9
|
+
//# sourceMappingURL=recipes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.d.ts","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;8FAC8F;AAC9F,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAM,EAAE,QAAQ,SAAO,GAAG,KAAK,CAK/F"}
|
package/dist/recipes.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Squash-and-stretch: snap to a deformed scale then spring back to 1.
|
|
2
|
+
* `amount` > 0 squashes (wide/short, e.g. landing), < 0 stretches (tall/thin, e.g. jump). */
|
|
3
|
+
export function squash(tweens, target, amount = 0.3, duration = 0.25) {
|
|
4
|
+
tweens.kill(target);
|
|
5
|
+
target.scaleX = 1 + amount;
|
|
6
|
+
target.scaleY = 1 - amount;
|
|
7
|
+
return tweens.to(target, { scaleX: 1, scaleY: 1 }, { duration, ease: "outElastic" });
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=recipes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.js","sourceRoot":"","sources":["../src/recipes.ts"],"names":[],"mappings":"AAOA;8FAC8F;AAC9F,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,MAAkB,EAAE,MAAM,GAAG,GAAG,EAAE,QAAQ,GAAG,IAAI;IACtF,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpB,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC;IAC3B,OAAO,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;AACvF,CAAC"}
|
package/dist/trail.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DrawLike } from "./draw-like.js";
|
|
2
|
+
/** Fading polyline behind a moving point (dashes, projectiles, swipes). */
|
|
3
|
+
export declare class Trail {
|
|
4
|
+
readonly length: number;
|
|
5
|
+
color: string;
|
|
6
|
+
width: number;
|
|
7
|
+
private readonly xs;
|
|
8
|
+
private readonly ys;
|
|
9
|
+
constructor(length?: number, color?: string, width?: number);
|
|
10
|
+
push(x: number, y: number): void;
|
|
11
|
+
clear(): void;
|
|
12
|
+
draw(draw: DrawLike): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=trail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trail.d.ts","sourceRoot":"","sources":["../src/trail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,2EAA2E;AAC3E,qBAAa,KAAK;IAKd,QAAQ,CAAC,MAAM;IACR,KAAK;IACL,KAAK;IANd,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAgB;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAgB;IAEnC,YACW,MAAM,SAAK,EACb,KAAK,SAAS,EACd,KAAK,SAAI,EACd;IAEJ,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAO/B;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAUzB;CACF"}
|
package/dist/trail.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Fading polyline behind a moving point (dashes, projectiles, swipes). */
|
|
2
|
+
export class Trail {
|
|
3
|
+
length;
|
|
4
|
+
color;
|
|
5
|
+
width;
|
|
6
|
+
xs = [];
|
|
7
|
+
ys = [];
|
|
8
|
+
constructor(length = 12, color = "#fff", width = 3) {
|
|
9
|
+
this.length = length;
|
|
10
|
+
this.color = color;
|
|
11
|
+
this.width = width;
|
|
12
|
+
}
|
|
13
|
+
push(x, y) {
|
|
14
|
+
this.xs.push(x);
|
|
15
|
+
this.ys.push(y);
|
|
16
|
+
if (this.xs.length > this.length) {
|
|
17
|
+
this.xs.shift();
|
|
18
|
+
this.ys.shift();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
clear() {
|
|
22
|
+
this.xs.length = 0;
|
|
23
|
+
this.ys.length = 0;
|
|
24
|
+
}
|
|
25
|
+
draw(draw) {
|
|
26
|
+
const n = this.xs.length;
|
|
27
|
+
if (n < 2)
|
|
28
|
+
return;
|
|
29
|
+
const baseAlpha = draw.alpha;
|
|
30
|
+
for (let i = 1; i < n; i++) {
|
|
31
|
+
const t = i / (n - 1);
|
|
32
|
+
draw.alpha = baseAlpha * t;
|
|
33
|
+
draw.line(this.xs[i - 1] ?? 0, this.ys[i - 1] ?? 0, this.xs[i] ?? 0, this.ys[i] ?? 0, this.width * t, this.color);
|
|
34
|
+
}
|
|
35
|
+
draw.alpha = baseAlpha;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=trail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trail.js","sourceRoot":"","sources":["../src/trail.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,OAAO,KAAK;IAKL,MAAM;IACR,KAAK;IACL,KAAK;IANG,EAAE,GAAa,EAAE,CAAC;IAClB,EAAE,GAAa,EAAE,CAAC;IAEnC,YACW,MAAM,GAAG,EAAE,EACb,KAAK,GAAG,MAAM,EACd,KAAK,GAAG,CAAC;sBAFP,MAAM;qBACR,KAAK;qBACL,KAAK;IACX,CAAC;IAEJ,IAAI,CAAC,CAAS,EAAE,CAAS;QACvB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,IAAc;QACjB,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACpH,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IACzB,CAAC;CACF"}
|
package/dist/tween.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type EaseName, type Easing } from "./ease.js";
|
|
2
|
+
type NumericKeys<T> = {
|
|
3
|
+
[K in keyof T]: T[K] extends number ? K : never;
|
|
4
|
+
}[keyof T];
|
|
5
|
+
export interface TweenOptions {
|
|
6
|
+
duration: number;
|
|
7
|
+
ease?: EaseName | Easing;
|
|
8
|
+
delay?: number;
|
|
9
|
+
/** Play forward then back. */
|
|
10
|
+
yoyo?: boolean;
|
|
11
|
+
/** Extra repetitions; -1 repeats forever. */
|
|
12
|
+
repeat?: number;
|
|
13
|
+
onComplete?: () => void;
|
|
14
|
+
}
|
|
15
|
+
export interface Tween {
|
|
16
|
+
readonly done: boolean;
|
|
17
|
+
cancel(): void;
|
|
18
|
+
/** Resolves when the tween completes (not when cancelled). */
|
|
19
|
+
readonly finished: Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
/** Tweens numeric properties of any object. Drive with `update(dt)` from the game loop. */
|
|
22
|
+
export declare class Tweens {
|
|
23
|
+
private active;
|
|
24
|
+
to<T extends object>(target: T, props: Partial<Pick<T, NumericKeys<T>>>, options: TweenOptions): Tween;
|
|
25
|
+
/** Cancel all tweens on a target. */
|
|
26
|
+
kill(target: object): void;
|
|
27
|
+
get count(): number;
|
|
28
|
+
update(dt: number): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=tween.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tween.d.ts","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAQ,MAAM,WAAW,CAAC;AAE7D,KAAK,WAAW,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAEnF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,MAAM,IAAI,IAAI,CAAC;IACf,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAiBD,2FAA2F;AAC3F,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAgB;IAE9B,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,KAAK,CA+BrG;IAED,qCAAqC;IACrC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEzB;IAED,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CA+BvB;CACF"}
|
package/dist/tween.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ease } from "./ease.js";
|
|
2
|
+
/** Tweens numeric properties of any object. Drive with `update(dt)` from the game loop. */
|
|
3
|
+
export class Tweens {
|
|
4
|
+
active = [];
|
|
5
|
+
to(target, props, options) {
|
|
6
|
+
const t = target;
|
|
7
|
+
const to = props;
|
|
8
|
+
const from = {};
|
|
9
|
+
for (const key of Object.keys(to))
|
|
10
|
+
from[key] = t[key] ?? 0;
|
|
11
|
+
let resolve;
|
|
12
|
+
const finished = new Promise((r) => (resolve = r));
|
|
13
|
+
const a = {
|
|
14
|
+
target: t,
|
|
15
|
+
from,
|
|
16
|
+
to,
|
|
17
|
+
duration: Math.max(options.duration, 1e-6),
|
|
18
|
+
easing: typeof options.ease === "function" ? options.ease : ease[options.ease ?? "outQuad"],
|
|
19
|
+
delay: options.delay ?? 0,
|
|
20
|
+
time: 0,
|
|
21
|
+
yoyo: options.yoyo ?? false,
|
|
22
|
+
repeat: options.repeat ?? 0,
|
|
23
|
+
done: false,
|
|
24
|
+
resolve,
|
|
25
|
+
onComplete: options.onComplete,
|
|
26
|
+
};
|
|
27
|
+
this.active.push(a);
|
|
28
|
+
return {
|
|
29
|
+
get done() {
|
|
30
|
+
return a.done;
|
|
31
|
+
},
|
|
32
|
+
cancel: () => {
|
|
33
|
+
a.done = true;
|
|
34
|
+
},
|
|
35
|
+
finished,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Cancel all tweens on a target. */
|
|
39
|
+
kill(target) {
|
|
40
|
+
for (const a of this.active)
|
|
41
|
+
if (a.target === target)
|
|
42
|
+
a.done = true;
|
|
43
|
+
}
|
|
44
|
+
get count() {
|
|
45
|
+
return this.active.length;
|
|
46
|
+
}
|
|
47
|
+
update(dt) {
|
|
48
|
+
for (const a of this.active) {
|
|
49
|
+
if (a.done)
|
|
50
|
+
continue;
|
|
51
|
+
let step = dt;
|
|
52
|
+
if (a.delay > 0) {
|
|
53
|
+
a.delay -= step;
|
|
54
|
+
if (a.delay > 0)
|
|
55
|
+
continue;
|
|
56
|
+
step = -a.delay;
|
|
57
|
+
a.delay = 0;
|
|
58
|
+
}
|
|
59
|
+
a.time += step;
|
|
60
|
+
const span = a.yoyo ? a.duration * 2 : a.duration;
|
|
61
|
+
let t = Math.min(a.time / a.duration, a.yoyo ? 2 : 1);
|
|
62
|
+
if (t > 1)
|
|
63
|
+
t = 2 - t;
|
|
64
|
+
const k = a.easing(t);
|
|
65
|
+
for (const key in a.to) {
|
|
66
|
+
const from = a.from[key] ?? 0;
|
|
67
|
+
a.target[key] = from + ((a.to[key] ?? from) - from) * k;
|
|
68
|
+
}
|
|
69
|
+
if (a.time >= span) {
|
|
70
|
+
if (a.repeat !== 0) {
|
|
71
|
+
a.time -= span;
|
|
72
|
+
if (a.repeat > 0)
|
|
73
|
+
a.repeat--;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
a.done = true;
|
|
77
|
+
a.onComplete?.();
|
|
78
|
+
a.resolve();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (this.active.some((a) => a.done))
|
|
83
|
+
this.active = this.active.filter((a) => !a.done);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=tween.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tween.js","sourceRoot":"","sources":["../src/tween.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@debuffjp/juice",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Tweens, easing, particles and game-feel effects for debuff",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"game",
|
|
7
|
+
"gamedev",
|
|
8
|
+
"game-engine",
|
|
9
|
+
"2d",
|
|
10
|
+
"html5-game",
|
|
11
|
+
"browser-game",
|
|
12
|
+
"debuff",
|
|
13
|
+
"tween",
|
|
14
|
+
"easing",
|
|
15
|
+
"particles",
|
|
16
|
+
"game-feel",
|
|
17
|
+
"juice"
|
|
18
|
+
],
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"homepage": "https://debuff.jp",
|
|
21
|
+
"bugs": "https://github.com/debuffjp/debuff/issues",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/debuffjp/debuff.git",
|
|
25
|
+
"directory": "packages/juice"
|
|
26
|
+
},
|
|
27
|
+
"type": "module",
|
|
28
|
+
"sideEffects": false,
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"README.md"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -b"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"provenance": false
|
|
47
|
+
}
|
|
48
|
+
}
|