@mingxy/opencode-mascot 0.7.8 → 0.7.9
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/package.json
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import type { PropPack } from "../../core/types";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Pad 道具 — busy 状态变体道具
|
|
5
|
-
*
|
|
6
|
-
* 尺寸: 18 宽 × 9 高(双层框+.•摄像头+底部◉Home键)
|
|
7
|
-
* 屏幕区: 12 宽 × 4 高
|
|
8
|
-
* 叙事: 月儿小人玩游戏,又菜又爱玩
|
|
9
|
-
* 贪吃蛇 6帧: 开局→走→撞墙→哭→不服→重开
|
|
10
|
-
* 俄罗斯方块 4帧: 开局→堆积→满→over
|
|
11
|
-
* 2048 4帧: 开局→合并→128→over
|
|
12
|
-
* 切换 1帧: next!
|
|
13
|
-
* 月儿小人: ☆ 呆毛 + (^-^) 圆脸 + ┃█┃ 身体(迷你版)
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const W = 12; // 屏幕内容区宽
|
|
3
|
+
const W = 12;
|
|
17
4
|
|
|
18
5
|
const OUTER_TOP = "╭.•" + "─".repeat(14) + "╮";
|
|
19
6
|
const INNER_TOP = "│ ┌" + "─".repeat(W) + "┐ │";
|
|
@@ -25,24 +12,20 @@ const scr = (rows: string[]) =>
|
|
|
25
12
|
rows.map((r) => "│ │" + r.padEnd(W) + "│ │");
|
|
26
13
|
|
|
27
14
|
const games: string[][] = [
|
|
28
|
-
// 贪吃蛇 6帧
|
|
29
15
|
[" ☆ ᵇᵉᵍⁱⁿ ", "(^-^) ◯→ ●", " ┃█┃ ˢ:0 ", " "],
|
|
30
16
|
[" ☆ ", "(^-^) ◯◯→ ●", " ┃█┃ ˢ:1 ", " "],
|
|
31
17
|
[" ☆ ", "(×_×) ◯◯💥 ", " ┃█┃ ᵍᵍ! ", " "],
|
|
32
18
|
[" ☆ ", "(╥_╥) ᵒᵛᵉʳ ", " ┃█┃ ˢ:1 ", " "],
|
|
33
19
|
[" ☆ ", "(¬_¬) ᵃᵍᵃⁱⁿ", " ┃█┃ ", " "],
|
|
34
20
|
[" ☆ ᵍᵒ! ", "(^-^) ◯→ ●", " ┃█┃ ˢ:0 ", " "],
|
|
35
|
-
// 俄罗斯方块 4帧
|
|
36
21
|
[" ☆ ᵇᵉᵍⁱⁿ ", "(^-^) ▣ ", " ┃█┃ ", " "],
|
|
37
22
|
[" ☆ ", "(^-^) ▣▣ ", " ┃█┃ ▣▣▣▣ ", " "],
|
|
38
23
|
[" ☆ ", "(×_×) ", " ┃█┃ ▣▣▣▣▣▣", " ᶠᵘˡˡ! "],
|
|
39
24
|
[" ☆ ", "(╥_╥) ᵒᵛᵉʳ ", " ┃█┃ ", " "],
|
|
40
|
-
// 2048 4帧
|
|
41
25
|
[" ☆ ᵇᵉᵍⁱⁿ ", "(^-^) [ 2 ]", " ┃█┃ ", " "],
|
|
42
26
|
[" ☆ ", "(^-^) [ 4 ]", " ┃█┃ ᵒᵒⁿ ", " "],
|
|
43
27
|
[" ☆ ", "(⊙_⊙) [128]", " ┃█┃ ʷᵒʷ ", " "],
|
|
44
28
|
[" ☆ ", "(╥_╥) ᵒᵛᵉʳ ", " ┃█┃ ", " "],
|
|
45
|
-
// 切换
|
|
46
29
|
[" ☆ ", "(^-^) ⁿᵉˣᵗ!", " ┃█┃ ", " "],
|
|
47
30
|
];
|
|
48
31
|
|
|
@@ -157,7 +157,19 @@ export function HomeMascot(props: HomeMascotProps): JSX.Element {
|
|
|
157
157
|
onMouseUp={() => { stopDrag(); }}
|
|
158
158
|
onMouseDragEnd={() => { stopDrag(); }}
|
|
159
159
|
>
|
|
160
|
-
{renderers[currentName()]?.
|
|
160
|
+
{renderers[currentName()]?.propElement() ? (
|
|
161
|
+
<box
|
|
162
|
+
position="absolute"
|
|
163
|
+
zIndex={50}
|
|
164
|
+
left={renderers[currentName()].getPropPosition() === "side-left" ? -16 : renderers[currentName()].getPropPosition() === "side-right" ? 12 : 0}
|
|
165
|
+
top={0}
|
|
166
|
+
>
|
|
167
|
+
{renderers[currentName()].propElement()}
|
|
168
|
+
</box>
|
|
169
|
+
) : null}
|
|
170
|
+
<box zIndex={100}>
|
|
171
|
+
{renderers[currentName()]?.element() ?? null}
|
|
172
|
+
</box>
|
|
161
173
|
</box>
|
|
162
174
|
);
|
|
163
175
|
}
|
|
@@ -159,16 +159,8 @@ export function SidebarMascot(props: SidebarMascotProps): JSX.Element {
|
|
|
159
159
|
if (statusType === "busy" || statusType === "retry") {
|
|
160
160
|
if (hideSide) returnToView();
|
|
161
161
|
renderers[currentName()].setState("busy");
|
|
162
|
-
// 先显示箱子"打开"动画300ms,再切换到 busy 道具(道具从箱子里掉出来)
|
|
163
162
|
const busyProp = pickPropByTrigger("busy");
|
|
164
|
-
|
|
165
|
-
renderers[currentName()].setProp(getProp("box") ?? null);
|
|
166
|
-
setTimeout(() => {
|
|
167
|
-
renderers[currentName()].setProp(busyProp);
|
|
168
|
-
}, 300);
|
|
169
|
-
} else {
|
|
170
|
-
renderers[currentName()].setProp(null);
|
|
171
|
-
}
|
|
163
|
+
renderers[currentName()].setProp(busyProp);
|
|
172
164
|
} else {
|
|
173
165
|
setStateWithSwitch("idle");
|
|
174
166
|
renderers[currentName()].setProp(null);
|
|
@@ -279,7 +271,19 @@ export function SidebarMascot(props: SidebarMascotProps): JSX.Element {
|
|
|
279
271
|
checkEdge();
|
|
280
272
|
}}
|
|
281
273
|
>
|
|
282
|
-
{renderers[currentName()]?.
|
|
274
|
+
{renderers[currentName()]?.propElement() ? (
|
|
275
|
+
<box
|
|
276
|
+
position="absolute"
|
|
277
|
+
zIndex={50}
|
|
278
|
+
left={renderers[currentName()].getPropPosition() === "side-left" ? -16 : renderers[currentName()].getPropPosition() === "side-right" ? 12 : 0}
|
|
279
|
+
top={0}
|
|
280
|
+
>
|
|
281
|
+
{renderers[currentName()].propElement()}
|
|
282
|
+
</box>
|
|
283
|
+
) : null}
|
|
284
|
+
<box zIndex={100}>
|
|
285
|
+
{renderers[currentName()]?.element() ?? null}
|
|
286
|
+
</box>
|
|
283
287
|
</box>
|
|
284
288
|
);
|
|
285
289
|
}
|
|
@@ -46,6 +46,8 @@ function getFrameLines(pack: MascotPack, frameName: string): string[] {
|
|
|
46
46
|
|
|
47
47
|
export function createAnimatedRenderer(pack: MascotPack): {
|
|
48
48
|
element: () => JSX.Element;
|
|
49
|
+
propElement: () => JSX.Element | null;
|
|
50
|
+
getPropPosition: () => PropPosition | null;
|
|
49
51
|
getState: () => MascotState;
|
|
50
52
|
setState: (s: MascotState) => void;
|
|
51
53
|
toggleWalk: () => void;
|
|
@@ -331,9 +333,6 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
331
333
|
scatter();
|
|
332
334
|
bomb();
|
|
333
335
|
versionMsg();
|
|
334
|
-
activeProp();
|
|
335
|
-
propFrameIdx();
|
|
336
|
-
propPosition();
|
|
337
336
|
|
|
338
337
|
for (const [, [get]] of extraSignals) {
|
|
339
338
|
get();
|
|
@@ -368,47 +367,6 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
368
367
|
lines = effects.render(lines, renderCtx);
|
|
369
368
|
}
|
|
370
369
|
|
|
371
|
-
// ─── Prop overlay ───
|
|
372
|
-
const prop = activeProp();
|
|
373
|
-
if (prop) {
|
|
374
|
-
const propFramesRaw = Array.isArray(prop.frames[0])
|
|
375
|
-
? (prop.frames as string[][])
|
|
376
|
-
: [prop.frames as string[]];
|
|
377
|
-
const propLines = propFramesRaw[propFrameIdx() % propFramesRaw.length] ?? propFramesRaw[0];
|
|
378
|
-
|
|
379
|
-
if (propLines.length > 0) {
|
|
380
|
-
const pos = propPosition();
|
|
381
|
-
if (pos === 'front') {
|
|
382
|
-
const overlayCount = Math.min(propLines.length, lines.length);
|
|
383
|
-
const startRow = Math.floor((lines.length - overlayCount) / 2);
|
|
384
|
-
for (let i = 0; i < overlayCount; i++) {
|
|
385
|
-
lines[startRow + i] = propLines[i];
|
|
386
|
-
}
|
|
387
|
-
} else {
|
|
388
|
-
const charWidth = lines[0]?.length ?? 0;
|
|
389
|
-
const propWidth = propLines[0]?.length ?? 0;
|
|
390
|
-
const charHeight = lines.length;
|
|
391
|
-
const propHeight = propLines.length;
|
|
392
|
-
const maxLines = Math.max(charHeight, propHeight);
|
|
393
|
-
const charPad = Math.floor((maxLines - charHeight) / 2);
|
|
394
|
-
const propPad = Math.floor((maxLines - propHeight) / 2);
|
|
395
|
-
const sep = " ";
|
|
396
|
-
|
|
397
|
-
const merged: string[] = [];
|
|
398
|
-
for (let i = 0; i < maxLines; i++) {
|
|
399
|
-
const cLine = (i >= charPad && i < charPad + charHeight)
|
|
400
|
-
? lines[i - charPad]
|
|
401
|
-
: " ".repeat(charWidth);
|
|
402
|
-
const pLine = (i >= propPad && i < propPad + propHeight)
|
|
403
|
-
? propLines[i - propPad]
|
|
404
|
-
: " ".repeat(propWidth);
|
|
405
|
-
merged.push(pos === 'side-right' ? cLine + sep + pLine : pLine + sep + cLine);
|
|
406
|
-
}
|
|
407
|
-
lines = merged;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
370
|
const top = jumpOffset();
|
|
413
371
|
const left = offset > 0 ? offset : 0;
|
|
414
372
|
const cel = celebrate();
|
|
@@ -435,6 +393,26 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
435
393
|
);
|
|
436
394
|
};
|
|
437
395
|
|
|
396
|
+
const propElement = () => {
|
|
397
|
+
activeProp();
|
|
398
|
+
propFrameIdx();
|
|
399
|
+
const prop = activeProp();
|
|
400
|
+
if (!prop) return null;
|
|
401
|
+
|
|
402
|
+
const propFramesRaw = Array.isArray(prop.frames[0])
|
|
403
|
+
? (prop.frames as string[][])
|
|
404
|
+
: [prop.frames as string[]];
|
|
405
|
+
const propLines = propFramesRaw[propFrameIdx() % propFramesRaw.length] ?? propFramesRaw[0];
|
|
406
|
+
|
|
407
|
+
return (
|
|
408
|
+
<box flexDirection="column" alignItems="flex-start">
|
|
409
|
+
{propLines.map((line: string) => (
|
|
410
|
+
<text fg={fg}>{line}</text>
|
|
411
|
+
))}
|
|
412
|
+
</box>
|
|
413
|
+
);
|
|
414
|
+
};
|
|
415
|
+
|
|
438
416
|
// ─── State control ───
|
|
439
417
|
const setState = (s: MascotState) => {
|
|
440
418
|
setCurrentState(s);
|
|
@@ -658,5 +636,5 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
658
636
|
|
|
659
637
|
const getProp = () => activeProp();
|
|
660
638
|
|
|
661
|
-
return { element, getState: currentState, setState, toggleWalk, setDragging, setCharacterHidden, celebrateUpdate, bounce, showVersion, scatterIn, explode, setProp, getProp };
|
|
639
|
+
return { element, propElement, getPropPosition: () => propPosition(), getState: currentState, setState, toggleWalk, setDragging, setCharacterHidden, celebrateUpdate, bounce, showVersion, scatterIn, explode, setProp, getProp };
|
|
662
640
|
}
|