@playcraft/cli 0.0.53 → 0.0.56
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 +21 -0
- package/REMIX.md +103 -19
- package/dist/atom-tree/fusion-hints.js +8 -3
- package/dist/atom-tree/fusion-intent.js +62 -0
- package/dist/atom-tree/selection.js +3 -1
- package/dist/commands/create.js +439 -159
- package/dist/commands/image.js +79 -69
- package/dist/commands/levels.js +29 -0
- package/dist/commands/patterns.js +75 -0
- package/dist/commands/remix.js +47 -0
- package/dist/commands/skills.js +48 -17
- package/dist/index.js +13 -6
- package/dist/remix/clone-source.js +208 -0
- package/dist/remix/clone.js +255 -0
- package/dist/scaffold/templates.js +35 -0
- package/dist/utils/agent-api-client.js +10 -3
- package/dist/utils/remix-image-attachments.js +4 -32
- package/dist/utils/sandbox-path.js +20 -0
- package/package.json +3 -3
- package/project-template/.claude/agents/creative-director.md +114 -0
- package/project-template/.claude/agents/developer.md +5 -2
- package/project-template/.claude/agents/game-designer.md +41 -20
- package/project-template/.claude/agents/refs/README.md +8 -0
- package/project-template/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-template/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-template/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-template/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-template/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-template/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-template/.claude/agents/refs/game-designer-gameplay-sufficiency.md +4 -4
- package/project-template/.claude/agents/reviewer.md +11 -0
- package/project-template/.claude/hooks/README.md +12 -12
- package/project-template/.claude/hooks/block-developer-preflight.mjs +49 -13
- package/project-template/.claude/hooks/block-ring1-tasklist.mjs +1 -1
- package/project-template/.claude/hooks/user-prompt.mjs +3 -13
- package/project-template/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-template/.claude/settings.json +2 -2
- package/project-template/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-template/.claude/skills/session-analyzer/scripts/resolve-session.mjs +0 -1
- package/project-template/.claude/snapshot.mjs +0 -1
- package/project-template/.codebuddy/settings.json +1 -1
- package/project-template/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-template/CLAUDE.md +9 -9
- package/project-template/docs/project-state.md +1 -1
- package/project-template/docs/team/agent-conduct.md +18 -18
- package/project-template/docs/team/collaboration.md +19 -7
- package/project-template/docs/team/workflow-changelog.md +15 -0
- package/project-template/fusion-patterns/catalog.json +77 -0
- package/project-template/package.json +2 -0
- package/project-template/skills/_shared/scripts/create-playable.mjs +31 -11
- package/project-template/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-template/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-template/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-template/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-template/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-template/skills/_shared/scripts/slice-set.mjs +29 -2
- package/project-template/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-template/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-template/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-template/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-template/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-template/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-template/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-template/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-template/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-template/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-template/templates/design-brief.template.md +34 -0
- package/project-template/templates/design-methodology.md +1 -2
- package/project-template/templates/design.template.md +65 -0
- package/project-template/templates/developer-log.template.md +12 -1
- package/project-template/templates/five-axis-framework.md +12 -0
- package/project-template/templates/game-designer-creative-process.template.md +99 -0
- package/project-template/templates/level-sketch.template.json +56 -0
- package/project-template/templates/north-star.template.md +43 -0
- package/project-template/templates/project-state.template.md +1 -1
- package/project-template/vite.config.ts +4 -5
- package/project-templates/phaser/.claude/agents/creative-director.md +114 -0
- package/project-templates/phaser/.claude/agents/game-designer.md +41 -20
- package/project-templates/phaser/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-templates/phaser/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-templates/phaser/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-templates/phaser/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-templates/phaser/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-templates/phaser/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-templates/phaser/.claude/agents/reviewer.md +11 -0
- package/project-templates/phaser/.claude/hooks/block-ring1-tasklist.mjs +2 -2
- package/project-templates/phaser/.claude/hooks/user-prompt.mjs +17 -18
- package/project-templates/phaser/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-templates/phaser/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-templates/phaser/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-templates/phaser/CLAUDE.md +88 -54
- package/project-templates/phaser/docs/DESIGN.md +25 -0
- package/project-templates/phaser/docs/project-state.md +1 -1
- package/project-templates/phaser/docs/team/collaboration.md +19 -7
- package/project-templates/phaser/docs/team/workflow-changelog.md +14 -0
- package/project-templates/phaser/fusion-patterns/catalog.json +77 -0
- package/project-templates/phaser/package.json +3 -1
- package/project-templates/phaser/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-templates/phaser/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-templates/phaser/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-templates/phaser/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-templates/phaser/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-templates/phaser/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-templates/phaser/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-templates/phaser/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-templates/phaser/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-templates/phaser/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-templates/phaser/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-templates/phaser/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-templates/phaser/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-templates/phaser/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-templates/phaser/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-templates/phaser/templates/design-brief.template.md +42 -11
- package/project-templates/phaser/templates/design-methodology.md +1 -2
- package/project-templates/phaser/templates/design.template.md +77 -0
- package/project-templates/phaser/templates/five-axis-framework.md +50 -1
- package/project-templates/phaser/templates/game-designer-creative-process.template.md +99 -0
- package/project-templates/phaser/templates/level-sketch.template.json +56 -0
- package/project-templates/phaser/templates/north-star.template.md +43 -0
- package/project-templates/phaser/templates/project-state.template.md +1 -1
- package/project-templates/phaser/vite.config.ts +4 -5
- package/project-templates/playable-template-phaser/.playcraftignore +10 -0
- package/project-templates/playable-template-phaser/CLAUDE.md +178 -0
- package/project-templates/playable-template-phaser/PLAYCRAFT-MIGRATION.md +328 -0
- package/project-templates/playable-template-phaser/README.md +381 -0
- package/project-templates/playable-template-phaser/assets/brain.png +0 -0
- package/project-templates/playable-template-phaser/assets/button.png +0 -0
- package/project-templates/playable-template-phaser/assets/interact.png +0 -0
- package/project-templates/playable-template-phaser/assets/logo.webp +0 -0
- package/project-templates/playable-template-phaser/assets/warn_brain.png +0 -0
- package/project-templates/playable-template-phaser/builds.config.js +12 -0
- package/project-templates/playable-template-phaser/globals.d.ts +2 -0
- package/project-templates/playable-template-phaser/index.html +12 -0
- package/project-templates/playable-template-phaser/package.json +45 -0
- package/project-templates/playable-template-phaser/scripts/base64-to-mp3.js +340 -0
- package/project-templates/playable-template-phaser/scripts/convert-to-webp.js +370 -0
- package/project-templates/playable-template-phaser/src/Game.ts +154 -0
- package/project-templates/playable-template-phaser/src/config/LoadingConfig.ts +40 -0
- package/project-templates/playable-template-phaser/src/config/ThemeConfig.ts +81 -0
- package/project-templates/playable-template-phaser/src/index.css +18 -0
- package/project-templates/playable-template-phaser/src/index.html +9 -0
- package/project-templates/playable-template-phaser/src/index.ts +30 -0
- package/project-templates/playable-template-phaser/src/json5.d.ts +4 -0
- package/project-templates/playable-template-phaser/src/managers/AudioManager.ts +559 -0
- package/project-templates/playable-template-phaser/src/scenes/MainScene.ts +301 -0
- package/project-templates/playable-template-phaser/src/scenes/PreloadScene.ts +256 -0
- package/project-templates/playable-template-phaser/src/theme/README.md +194 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/assets/.gitkeep +24 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/index.ts +27 -0
- package/project-templates/playable-template-phaser/src/theme/blue-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/index.ts +20 -0
- package/project-templates/playable-template-phaser/src/theme/green-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/index.ts +1 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/index.ts +20 -0
- package/project-templates/playable-template-phaser/src/theme/red-theme/theme.data.json5 +19 -0
- package/project-templates/playable-template-phaser/src/theme/theme.metadata.md +60 -0
- package/project-templates/playable-template-phaser/src/theme/theme.schema.json5 +149 -0
- package/project-templates/playable-template-phaser/src/ui/BrainAgeUI.ts +681 -0
- package/project-templates/playable-template-phaser/src/ui/CountdownUI.ts +565 -0
- package/project-templates/playable-template-phaser/src/ui/PlayButton.ts +51 -0
- package/project-templates/playable-template-phaser/src/ui/ScoreUI.ts +207 -0
- package/project-templates/playable-template-phaser/src/ui/SuccessUI.ts +43 -0
- package/project-templates/playable-template-phaser/src/ui/index.ts +15 -0
- package/project-templates/playable-template-phaser/tsconfig.json +26 -0
- package/project-templates/playable-template-phaser/vite.config.ts +64 -0
- package/project-templates/playable-template-phaser//346/226/260/346/211/213/345/274/200/345/217/221/346/214/207/345/215/227.md +209 -0
- package/project-templates/playable-template-three/README.md +795 -0
- package/project-templates/playable-template-three/assets/Stork.glb +0 -0
- package/project-templates/playable-template-three/assets/button.png +0 -0
- package/project-templates/playable-template-three/assets/logo.webp +0 -0
- package/project-templates/playable-template-three/build.json +7 -0
- package/project-templates/playable-template-three/builds.config.example.js +151 -0
- package/project-templates/playable-template-three/builds.config.js +158 -0
- package/project-templates/playable-template-three/package.json +36 -0
- package/project-templates/playable-template-three/scripts/convert-to-webp.js +370 -0
- package/project-templates/playable-template-three/scripts/theme-builds.js +514 -0
- package/project-templates/playable-template-three/src/Game.ts +215 -0
- package/project-templates/playable-template-three/src/config/LoadingConfig.ts +27 -0
- package/project-templates/playable-template-three/src/config/ThemeConfig.ts +36 -0
- package/project-templates/playable-template-three/src/global.d.ts +108 -0
- package/project-templates/playable-template-three/src/index.css +18 -0
- package/project-templates/playable-template-three/src/index.html +9 -0
- package/project-templates/playable-template-three/src/index.ts +20 -0
- package/project-templates/playable-template-three/src/managers/AudioManager.ts +538 -0
- package/project-templates/playable-template-three/src/scenes/PreloadScene.ts +305 -0
- package/project-templates/playable-template-three/src/theme/README.md +225 -0
- package/project-templates/playable-template-three/src/theme/blue-theme/assets/.gitkeep +28 -0
- package/project-templates/playable-template-three/src/theme/blue-theme/index.ts +45 -0
- package/project-templates/playable-template-three/src/theme/current.ts +12 -0
- package/project-templates/playable-template-three/src/theme/green-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-three/src/theme/green-theme/index.ts +34 -0
- package/project-templates/playable-template-three/src/theme/red-theme/assets/.gitkeep +3 -0
- package/project-templates/playable-template-three/src/theme/red-theme/index.ts +34 -0
- package/project-templates/playable-template-three/tsconfig.json +24 -0
- package/project-templates/threejs/.claude/agents/creative-director.md +114 -0
- package/project-templates/threejs/.claude/agents/game-designer.md +41 -20
- package/project-templates/threejs/.claude/agents/refs/creative-director-guide.md +35 -0
- package/project-templates/threejs/.claude/agents/refs/creative-director-kickoff-guide.md +52 -0
- package/project-templates/threejs/.claude/agents/refs/creative-discovery-guide.md +76 -0
- package/project-templates/threejs/.claude/agents/refs/creative-north-star-examples.md +82 -0
- package/project-templates/threejs/.claude/agents/refs/developer-dev-handoff.md +1 -1
- package/project-templates/threejs/.claude/agents/refs/game-designer-fusion-depth-playbook.md +28 -0
- package/project-templates/threejs/.claude/agents/reviewer.md +11 -0
- package/project-templates/threejs/.claude/hooks/block-ring1-tasklist.mjs +2 -2
- package/project-templates/threejs/.claude/hooks/user-prompt.mjs +17 -18
- package/project-templates/threejs/.claude/hooks/validate-workflow-stop.mjs +209 -12
- package/project-templates/threejs/.claude/skills/playcraft-playable-optimization/SKILL.md +20 -20
- package/project-templates/threejs/.cursor/rules/playcraft-orchestrator.mdc +1 -1
- package/project-templates/threejs/CLAUDE.md +88 -54
- package/project-templates/threejs/docs/DESIGN.md +25 -0
- package/project-templates/threejs/docs/project-state.md +1 -1
- package/project-templates/threejs/docs/team/collaboration.md +19 -7
- package/project-templates/threejs/docs/team/workflow-changelog.md +14 -0
- package/project-templates/threejs/fusion-patterns/catalog.json +77 -0
- package/project-templates/threejs/package.json +3 -1
- package/project-templates/threejs/skills/_shared/scripts/dev-start.mjs +3 -3
- package/project-templates/threejs/skills/_shared/scripts/disclosure-config.mjs +65 -39
- package/project-templates/threejs/skills/_shared/scripts/harness-smoke.mjs +3 -1
- package/project-templates/threejs/skills/_shared/scripts/lib/fusion-intent.mjs +88 -0
- package/project-templates/threejs/skills/_shared/scripts/lib/skill-fidelity.mjs +185 -0
- package/project-templates/threejs/skills/_shared/scripts/state-get.mjs +124 -7
- package/project-templates/threejs/skills/_shared/scripts/state-store.mjs +25 -2
- package/project-templates/threejs/skills/_shared/scripts/validate-level-sketch.mjs +444 -0
- package/project-templates/threejs/skills/_shared/scripts/verify-design-consistency.mjs +728 -0
- package/project-templates/threejs/skills/playable-record/scripts/lib/dev-server.mjs +46 -11
- package/project-templates/threejs/skills/playable-record/scripts/record-playable.mjs +2 -1
- package/project-templates/threejs/skills/playable-record/scripts/verify-contract.mjs +4 -4
- package/project-templates/threejs/skills/playable-record/scripts/verify-firstwin.mjs +3 -3
- package/project-templates/threejs/skills/playable-record/scripts/verify-fusion.mjs +37 -2
- package/project-templates/threejs/skills/playable-record/scripts/verify-slice.mjs +2 -2
- package/project-templates/threejs/templates/design-brief.template.md +42 -11
- package/project-templates/threejs/templates/design-methodology.md +1 -2
- package/project-templates/threejs/templates/design.template.md +77 -0
- package/project-templates/threejs/templates/five-axis-framework.md +50 -1
- package/project-templates/threejs/templates/game-designer-creative-process.template.md +99 -0
- package/project-templates/threejs/templates/level-sketch.template.json +56 -0
- package/project-templates/threejs/templates/north-star.template.md +43 -0
- package/project-templates/threejs/templates/project-state.template.md +1 -1
- package/project-templates/threejs/vite.config.ts +4 -5
- package/project-template/docs/DESIGN.md +0 -65
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 积分UI配置接口
|
|
3
|
+
*/
|
|
4
|
+
export interface ScoreUIConfig {
|
|
5
|
+
fontSize?: number;
|
|
6
|
+
fontFamily?: string;
|
|
7
|
+
color?: string;
|
|
8
|
+
bgColor?: string;
|
|
9
|
+
paddingX?: number;
|
|
10
|
+
paddingY?: number;
|
|
11
|
+
prefix?: string;
|
|
12
|
+
scale?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 完整配置类型(所有属性都必填)
|
|
17
|
+
*/
|
|
18
|
+
type FullScoreUIConfig = Required<ScoreUIConfig>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* 默认配置
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULT_CONFIG: FullScoreUIConfig = {
|
|
24
|
+
fontSize: 32,
|
|
25
|
+
fontFamily: 'Arial, sans-serif',
|
|
26
|
+
color: '#ffff00',
|
|
27
|
+
bgColor: '#00000066',
|
|
28
|
+
paddingX: 16,
|
|
29
|
+
paddingY: 8,
|
|
30
|
+
prefix: 'Score: ',
|
|
31
|
+
scale: 1,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/** 推荐的默认每次匹配得分 */
|
|
35
|
+
export const DEFAULT_POINTS_PER_MATCH = 5;
|
|
36
|
+
|
|
37
|
+
/** 推荐的默认 X 坐标 */
|
|
38
|
+
export const DEFAULT_X = 40;
|
|
39
|
+
|
|
40
|
+
/** 推荐的默认 Y 坐标 */
|
|
41
|
+
export const DEFAULT_Y = 15;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 积分UI组件(纯DOM+CSS实现)
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export class ScoreUI {
|
|
48
|
+
private element!: HTMLDivElement;
|
|
49
|
+
private config: FullScoreUIConfig;
|
|
50
|
+
private score: number = 0;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param x X 坐标(像素)
|
|
54
|
+
* @param y Y 坐标(像素)
|
|
55
|
+
* @param initialScore 初始分数
|
|
56
|
+
* @param config UI 配置
|
|
57
|
+
*/
|
|
58
|
+
constructor(x: number = DEFAULT_X, y: number = DEFAULT_Y, initialScore: number = 0, config?: ScoreUIConfig) {
|
|
59
|
+
this.score = initialScore;
|
|
60
|
+
this.config = this.mergeConfig(config);
|
|
61
|
+
this.create(x, y);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 合并配置
|
|
66
|
+
*/
|
|
67
|
+
private mergeConfig(userConfig?: ScoreUIConfig): FullScoreUIConfig {
|
|
68
|
+
if (!userConfig) {
|
|
69
|
+
return { ...DEFAULT_CONFIG };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
fontSize: userConfig.fontSize ?? DEFAULT_CONFIG.fontSize,
|
|
74
|
+
fontFamily: userConfig.fontFamily ?? DEFAULT_CONFIG.fontFamily,
|
|
75
|
+
color: userConfig.color ?? DEFAULT_CONFIG.color,
|
|
76
|
+
bgColor: userConfig.bgColor ?? DEFAULT_CONFIG.bgColor,
|
|
77
|
+
paddingX: userConfig.paddingX ?? DEFAULT_CONFIG.paddingX,
|
|
78
|
+
paddingY: userConfig.paddingY ?? DEFAULT_CONFIG.paddingY,
|
|
79
|
+
prefix: userConfig.prefix ?? DEFAULT_CONFIG.prefix,
|
|
80
|
+
scale: userConfig.scale ?? DEFAULT_CONFIG.scale,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private create(x: number, y: number): void {
|
|
85
|
+
const { fontSize, fontFamily, color, bgColor, paddingX, paddingY, prefix, scale: s } = this.config;
|
|
86
|
+
const scaledFontSize = Math.round(fontSize * s);
|
|
87
|
+
const scaledPaddingX = Math.round(paddingX * s);
|
|
88
|
+
const scaledPaddingY = Math.round(paddingY * s);
|
|
89
|
+
|
|
90
|
+
// 创建 DOM 元素
|
|
91
|
+
this.element = document.createElement('div');
|
|
92
|
+
this.element.className = 'score-ui';
|
|
93
|
+
this.element.textContent = `${prefix}${this.score}`;
|
|
94
|
+
|
|
95
|
+
// 应用样式
|
|
96
|
+
Object.assign(this.element.style, {
|
|
97
|
+
position: 'fixed',
|
|
98
|
+
left: `${x}px`,
|
|
99
|
+
top: `${y}px`,
|
|
100
|
+
fontSize: `${scaledFontSize}px`,
|
|
101
|
+
fontFamily: fontFamily,
|
|
102
|
+
color: color,
|
|
103
|
+
fontWeight: 'bold',
|
|
104
|
+
backgroundColor: bgColor,
|
|
105
|
+
padding: `${scaledPaddingY}px ${scaledPaddingX}px`,
|
|
106
|
+
borderRadius: '4px',
|
|
107
|
+
zIndex: '100',
|
|
108
|
+
pointerEvents: 'none',
|
|
109
|
+
userSelect: 'none',
|
|
110
|
+
whiteSpace: 'nowrap',
|
|
111
|
+
// 响应式:根据视口宽度自动缩放
|
|
112
|
+
transform: 'scale(var(--score-ui-scale, 1))',
|
|
113
|
+
transformOrigin: 'top left',
|
|
114
|
+
} as CSSStyleDeclaration);
|
|
115
|
+
|
|
116
|
+
// 添加到 body
|
|
117
|
+
document.body.appendChild(this.element);
|
|
118
|
+
|
|
119
|
+
// 响应式处理
|
|
120
|
+
this.setupResponsive();
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 设置响应式缩放
|
|
125
|
+
* 移动端下自动放大,PC端保持原尺寸
|
|
126
|
+
*/
|
|
127
|
+
private setupResponsive(): void {
|
|
128
|
+
const updateScale = () => {
|
|
129
|
+
const currentWidth = window.innerWidth;
|
|
130
|
+
const currentHeight = window.innerHeight;
|
|
131
|
+
|
|
132
|
+
// 判断是否为移动设备(基于屏幕尺寸)
|
|
133
|
+
const isMobile = currentWidth < 768 || (currentWidth < 1024 && currentHeight < 768);
|
|
134
|
+
|
|
135
|
+
let scale: number;
|
|
136
|
+
if (isMobile) {
|
|
137
|
+
// 移动端:基于 375px 基准,最小 0.8 倍,最大 1.2 倍
|
|
138
|
+
const baseWidth = 375;
|
|
139
|
+
scale = Math.max(0.4, Math.min(currentWidth / baseWidth, 0.5));
|
|
140
|
+
} else {
|
|
141
|
+
// PC端:基于 1920px 基准,最小 0.6 倍,最大 1 倍
|
|
142
|
+
const baseWidth = 1920;
|
|
143
|
+
scale = Math.max(0.6, Math.min(currentWidth / baseWidth, 1));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
document.documentElement.style.setProperty('--score-ui-scale', scale.toString());
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
updateScale();
|
|
150
|
+
window.addEventListener('resize', updateScale);
|
|
151
|
+
|
|
152
|
+
// 保存清理函数
|
|
153
|
+
(this.element as any)._cleanupResize = () => {
|
|
154
|
+
window.removeEventListener('resize', updateScale);
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 增加分数(默认使用 DEFAULT_POINTS_PER_MATCH)
|
|
160
|
+
*/
|
|
161
|
+
public add(points: number = DEFAULT_POINTS_PER_MATCH): void {
|
|
162
|
+
this.score += points;
|
|
163
|
+
this.refresh();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 获取当前分数
|
|
168
|
+
*/
|
|
169
|
+
public getScore(): number {
|
|
170
|
+
return this.score;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 直接设置分数
|
|
175
|
+
*/
|
|
176
|
+
public update(score: number): void {
|
|
177
|
+
this.score = score;
|
|
178
|
+
this.refresh();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
private refresh(): void {
|
|
182
|
+
if (this.element) {
|
|
183
|
+
this.element.textContent = `${this.config.prefix}${this.score}`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* 获取配置(用于调试或外部读取)
|
|
189
|
+
*/
|
|
190
|
+
public getConfig(): FullScoreUIConfig {
|
|
191
|
+
return { ...this.config };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 销毁组件
|
|
196
|
+
*/
|
|
197
|
+
public destroy(): void {
|
|
198
|
+
if (this.element) {
|
|
199
|
+
// 清理响应式监听器
|
|
200
|
+
const cleanup = (this.element as any)._cleanupResize;
|
|
201
|
+
if (cleanup) cleanup();
|
|
202
|
+
|
|
203
|
+
// 从 DOM 移除
|
|
204
|
+
this.element.remove();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as Phaser from 'phaser';
|
|
2
|
+
import { PlayButton } from './PlayButton';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 通用成功 UI 组件
|
|
6
|
+
* 显示半透明遮罩 + "You Win!" + PlayButton
|
|
7
|
+
*
|
|
8
|
+
* 纹理依赖(间接通过 PlayButton):
|
|
9
|
+
* - interact 合图中的 playBtn 帧
|
|
10
|
+
*/
|
|
11
|
+
export class SuccessUI {
|
|
12
|
+
private scene: Phaser.Scene;
|
|
13
|
+
|
|
14
|
+
constructor(scene: Phaser.Scene) {
|
|
15
|
+
this.scene = scene;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 显示成功浮层
|
|
20
|
+
* @param depth 渲染层级(默认 300,遮罩层)
|
|
21
|
+
*/
|
|
22
|
+
public show(depth: number = 300): void {
|
|
23
|
+
const { width, height } = this.scene.scale;
|
|
24
|
+
|
|
25
|
+
// 半透明遮罩
|
|
26
|
+
const overlay = this.scene.add.graphics().setDepth(depth);
|
|
27
|
+
overlay.fillStyle(0x000000, 0.6);
|
|
28
|
+
overlay.fillRect(0, 0, width, height);
|
|
29
|
+
|
|
30
|
+
const contentDepth = depth + 1;
|
|
31
|
+
|
|
32
|
+
// "You Win!" 文字
|
|
33
|
+
this.scene.add.text(width / 2, height / 2 - 40, 'You Win!', {
|
|
34
|
+
fontFamily: 'Arial, sans-serif',
|
|
35
|
+
fontSize: '56px',
|
|
36
|
+
color: '#ffffff',
|
|
37
|
+
fontStyle: 'bold'
|
|
38
|
+
}).setOrigin(0.5).setDepth(contentDepth);
|
|
39
|
+
|
|
40
|
+
// Play 按钮
|
|
41
|
+
new PlayButton(this.scene).show(width / 2, height / 2 + 50, 0.45, contentDepth);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI 组件统一导出
|
|
3
|
+
*/
|
|
4
|
+
export { BrainAgeUI } from './BrainAgeUI';
|
|
5
|
+
export type { BrainAgeUIConfig, BrainAgeGameConfig } from './BrainAgeUI';
|
|
6
|
+
|
|
7
|
+
export { CountdownUI, DEFAULT_COUNTDOWN, DEFAULT_WARN_TIME } from './CountdownUI';
|
|
8
|
+
export type { CountdownUIConfig } from './CountdownUI';
|
|
9
|
+
|
|
10
|
+
export { ScoreUI, DEFAULT_POINTS_PER_MATCH, DEFAULT_X, DEFAULT_Y } from './ScoreUI';
|
|
11
|
+
export type { ScoreUIConfig } from './ScoreUI';
|
|
12
|
+
|
|
13
|
+
export { SuccessUI } from './SuccessUI';
|
|
14
|
+
|
|
15
|
+
export { PlayButton } from './PlayButton';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"outDir": "./dist",
|
|
4
|
+
"target": "es5",
|
|
5
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"noFallthroughCasesInSwitch": true,
|
|
13
|
+
"strictPropertyInitialization": false,
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"moduleResolution": "bundler",
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"resolveJsonModule": true,
|
|
18
|
+
"isolatedModules": true,
|
|
19
|
+
"paths": {
|
|
20
|
+
"assets/*": ["./assets/*"],
|
|
21
|
+
"@/*": ["./src/*"],
|
|
22
|
+
"src/*": ["./src/*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"exclude": ["node_modules", "tests"]
|
|
26
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import JSON5 from "json5";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
|
|
6
|
+
// 自定义 Vite 插件:支持 .json5 文件导入
|
|
7
|
+
function json5Plugin() {
|
|
8
|
+
return {
|
|
9
|
+
name: "vite-plugin-json5",
|
|
10
|
+
transform(code: string, id: string) {
|
|
11
|
+
if (id.endsWith(".json5")) {
|
|
12
|
+
const raw = fs.readFileSync(id, "utf-8");
|
|
13
|
+
const parsed = JSON5.parse(raw);
|
|
14
|
+
return {
|
|
15
|
+
code: `export default ${JSON.stringify(parsed)};`,
|
|
16
|
+
map: null,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
// 项目根目录(index.html 所在位置)
|
|
25
|
+
root: ".",
|
|
26
|
+
|
|
27
|
+
// 路径别名,匹配 tsconfig 中的 paths 配置
|
|
28
|
+
resolve: {
|
|
29
|
+
alias: {
|
|
30
|
+
assets: path.resolve(__dirname, "assets"),
|
|
31
|
+
"@": path.resolve(__dirname, "src"),
|
|
32
|
+
src: path.resolve(__dirname, "src"),
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
plugins: [json5Plugin()],
|
|
37
|
+
|
|
38
|
+
// 全局常量定义,匹配 @playcraft/devkit 的 defines
|
|
39
|
+
define: {
|
|
40
|
+
__DEV__: JSON.stringify(true),
|
|
41
|
+
AD_NETWORK: JSON.stringify("preview"),
|
|
42
|
+
AD_PROTOCOL: JSON.stringify("none"),
|
|
43
|
+
GOOGLE_PLAY_URL: JSON.stringify("https://play.google.com/store/apps/details?id=com.nextinitiatives.minigames.mpp"),
|
|
44
|
+
APP_STORE_URL: JSON.stringify("https://apps.apple.com/app/id6758609907"),
|
|
45
|
+
APP: JSON.stringify("playable-template-phaser"),
|
|
46
|
+
NAME: JSON.stringify("Phaser Template"),
|
|
47
|
+
VERSION: JSON.stringify("1.0.0"),
|
|
48
|
+
LANGUAGE: JSON.stringify("auto"),
|
|
49
|
+
ORIENTATION: JSON.stringify("both"),
|
|
50
|
+
BUILD_HASH: JSON.stringify("dev"),
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// 开发服务器配置
|
|
54
|
+
server: {
|
|
55
|
+
port: 3000,
|
|
56
|
+
open: true,
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
// 构建配置
|
|
60
|
+
build: {
|
|
61
|
+
outDir: "dist",
|
|
62
|
+
sourcemap: true,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# 新手开发指南
|
|
2
|
+
|
|
3
|
+
欢迎使用 Phaser 可玩广告模板!本指南将帮助你快速上手。
|
|
4
|
+
|
|
5
|
+
## 第一步:安装依赖
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 第二步:启动开发服务器
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# 推荐:使用 Vite(速度快,支持 HMR)
|
|
15
|
+
npm run dev
|
|
16
|
+
|
|
17
|
+
# 或使用 playable-scripts(与构建环境一致)
|
|
18
|
+
npm run dev:wp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
浏览器会自动打开 `http://localhost:3000`
|
|
22
|
+
|
|
23
|
+
## 第三步:修改主题配置
|
|
24
|
+
|
|
25
|
+
### 方式一:修改配置值
|
|
26
|
+
|
|
27
|
+
编辑 `src/theme/blue-theme/theme.data.json5`:
|
|
28
|
+
|
|
29
|
+
```json5
|
|
30
|
+
{
|
|
31
|
+
name: '我的主题',
|
|
32
|
+
id: 'my-theme',
|
|
33
|
+
|
|
34
|
+
visual: {
|
|
35
|
+
backgroundColor: 0x123456, // 修改背景色
|
|
36
|
+
primaryColor: 0x654321,
|
|
37
|
+
// ...
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
gameplay: {
|
|
41
|
+
difficulty: 8, // 修改难度
|
|
42
|
+
enableHints: false,
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 方式二:切换主题
|
|
48
|
+
|
|
49
|
+
编辑 `src/theme/index.ts`:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
export { default } from './blue-theme'; // 蓝色主题
|
|
53
|
+
// export { default } from './green-theme'; // 绿色主题
|
|
54
|
+
// export { default } from './red-theme'; // 红色主题
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 第四步:添加资源
|
|
58
|
+
|
|
59
|
+
### 添加公共资源
|
|
60
|
+
|
|
61
|
+
1. 将资源放到 `assets/` 目录
|
|
62
|
+
2. 在代码中 import:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import myImage from 'assets/my-image.png';
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 添加主题特定资源
|
|
69
|
+
|
|
70
|
+
1. 将资源放到 `src/theme/blue-theme/assets/`
|
|
71
|
+
2. 在主题的 `index.ts` 中 import 并映射:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import myImage from './assets/my-image.png';
|
|
75
|
+
|
|
76
|
+
const assetRecordByPath: Record<string, string> = {
|
|
77
|
+
'./assets/my-image.png': myImage,
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
3. 在 `theme.schema.json5` 中定义:
|
|
82
|
+
|
|
83
|
+
```json5
|
|
84
|
+
assets: {
|
|
85
|
+
myImage: {
|
|
86
|
+
type: "string",
|
|
87
|
+
default: "./assets/my-image.png",
|
|
88
|
+
description: "我的图片",
|
|
89
|
+
xplatform: { value_type: "path", mime_type: "image/png" },
|
|
90
|
+
},
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
4. 在代码中使用:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { GameThemeConfig } from './config/ThemeConfig';
|
|
98
|
+
const imageUrl = GameThemeConfig.ASSET_MY_IMAGE;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 第五步:修改游戏逻辑
|
|
102
|
+
|
|
103
|
+
编辑 `src/scenes/MainScene.ts`,这是主游戏场景。
|
|
104
|
+
|
|
105
|
+
### 读取配置
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { GameThemeConfig } from '../config/ThemeConfig';
|
|
109
|
+
|
|
110
|
+
// 读取配置
|
|
111
|
+
const difficulty = GameThemeConfig.DIFFICULTY;
|
|
112
|
+
const bgColor = GameThemeConfig.BACKGROUND_COLOR;
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 添加游戏元素
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
create() {
|
|
119
|
+
// 添加精灵
|
|
120
|
+
const sprite = this.add.sprite(100, 100, 'myImage');
|
|
121
|
+
|
|
122
|
+
// 添加文本
|
|
123
|
+
const text = this.add.text(100, 200, 'Hello!', {
|
|
124
|
+
fontSize: '32px',
|
|
125
|
+
color: GameThemeConfig.TEXT_COLOR
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// 添加交互
|
|
129
|
+
sprite.setInteractive();
|
|
130
|
+
sprite.on('pointerdown', () => {
|
|
131
|
+
console.log('点击了精灵!');
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 第六步:构建生产版本
|
|
137
|
+
|
|
138
|
+
### 构建单个渠道
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
npm run build -- google
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
输出在 `dist/` 目录。
|
|
145
|
+
|
|
146
|
+
### 批量构建所有渠道
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
npm run builds
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
输出在 `dist-all/` 目录。
|
|
153
|
+
|
|
154
|
+
## 常见任务
|
|
155
|
+
|
|
156
|
+
### 修改 Loading 页面
|
|
157
|
+
|
|
158
|
+
编辑 `src/theme/theme.schema.json5` 的 `loading` 部分:
|
|
159
|
+
|
|
160
|
+
```json5
|
|
161
|
+
loading: {
|
|
162
|
+
appTitle: {
|
|
163
|
+
type: "string",
|
|
164
|
+
default: "My Game",
|
|
165
|
+
description: "应用标题",
|
|
166
|
+
},
|
|
167
|
+
// ...
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 添加音频
|
|
172
|
+
|
|
173
|
+
1. 将音频文件放到 `assets/`
|
|
174
|
+
2. 在 `src/scenes/PreloadScene.ts` 中加载:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
this.load.audio('bgm', 'assets/bgm.mp3');
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
3. 在 `MainScene.ts` 中播放:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
this.audioManager.playBGM('bgm');
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### 调试渠道
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# 本地预览时模拟 Google Ads 渠道
|
|
190
|
+
npm run dev
|
|
191
|
+
|
|
192
|
+
# 模拟 Facebook 渠道
|
|
193
|
+
npm run dev:wp facebook
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## 获取帮助
|
|
197
|
+
|
|
198
|
+
- 查看 [README.md](./README.md) 了解详细功能
|
|
199
|
+
- 查看 [CLAUDE.md](./CLAUDE.md) 了解架构设计
|
|
200
|
+
- 查看 [Phaser 官方文档](https://phaser.io/learn)
|
|
201
|
+
- 查看主题元数据:`src/theme/theme.metadata.md`
|
|
202
|
+
|
|
203
|
+
## 下一步
|
|
204
|
+
|
|
205
|
+
- 学习 Phaser 基础:https://phaser.io/tutorials
|
|
206
|
+
- 了解可玩广告规范:各渠道的尺寸和功能限制
|
|
207
|
+
- 探索 UI 组件:`src/ui/` 目录中的示例组件
|
|
208
|
+
|
|
209
|
+
祝开发顺利!🎮
|