@playcraft/cli 0.0.52 → 0.0.55

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.
Files changed (79) hide show
  1. package/dist/commands/create.js +164 -98
  2. package/dist/index.js +4 -1
  3. package/dist/scaffold/templates.js +35 -0
  4. package/package.json +3 -3
  5. package/project-templates/playable-template-phaser/.playcraftignore +10 -0
  6. package/project-templates/playable-template-phaser/CLAUDE.md +178 -0
  7. package/project-templates/playable-template-phaser/PLAYCRAFT-MIGRATION.md +328 -0
  8. package/project-templates/playable-template-phaser/README.md +381 -0
  9. package/project-templates/playable-template-phaser/assets/brain.png +0 -0
  10. package/project-templates/playable-template-phaser/assets/button.png +0 -0
  11. package/project-templates/playable-template-phaser/assets/interact.png +0 -0
  12. package/project-templates/playable-template-phaser/assets/logo.webp +0 -0
  13. package/project-templates/playable-template-phaser/assets/warn_brain.png +0 -0
  14. package/project-templates/playable-template-phaser/builds.config.js +12 -0
  15. package/project-templates/playable-template-phaser/globals.d.ts +2 -0
  16. package/project-templates/playable-template-phaser/index.html +12 -0
  17. package/project-templates/playable-template-phaser/package.json +45 -0
  18. package/project-templates/playable-template-phaser/scripts/base64-to-mp3.js +340 -0
  19. package/project-templates/playable-template-phaser/scripts/convert-to-webp.js +370 -0
  20. package/project-templates/playable-template-phaser/src/Game.ts +154 -0
  21. package/project-templates/playable-template-phaser/src/config/LoadingConfig.ts +40 -0
  22. package/project-templates/playable-template-phaser/src/config/ThemeConfig.ts +81 -0
  23. package/project-templates/playable-template-phaser/src/index.css +18 -0
  24. package/project-templates/playable-template-phaser/src/index.html +9 -0
  25. package/project-templates/playable-template-phaser/src/index.ts +30 -0
  26. package/project-templates/playable-template-phaser/src/json5.d.ts +4 -0
  27. package/project-templates/playable-template-phaser/src/managers/AudioManager.ts +559 -0
  28. package/project-templates/playable-template-phaser/src/scenes/MainScene.ts +301 -0
  29. package/project-templates/playable-template-phaser/src/scenes/PreloadScene.ts +256 -0
  30. package/project-templates/playable-template-phaser/src/theme/README.md +194 -0
  31. package/project-templates/playable-template-phaser/src/theme/blue-theme/assets/.gitkeep +24 -0
  32. package/project-templates/playable-template-phaser/src/theme/blue-theme/index.ts +27 -0
  33. package/project-templates/playable-template-phaser/src/theme/blue-theme/theme.data.json5 +19 -0
  34. package/project-templates/playable-template-phaser/src/theme/green-theme/assets/.gitkeep +3 -0
  35. package/project-templates/playable-template-phaser/src/theme/green-theme/index.ts +20 -0
  36. package/project-templates/playable-template-phaser/src/theme/green-theme/theme.data.json5 +19 -0
  37. package/project-templates/playable-template-phaser/src/theme/index.ts +1 -0
  38. package/project-templates/playable-template-phaser/src/theme/red-theme/assets/.gitkeep +3 -0
  39. package/project-templates/playable-template-phaser/src/theme/red-theme/index.ts +20 -0
  40. package/project-templates/playable-template-phaser/src/theme/red-theme/theme.data.json5 +19 -0
  41. package/project-templates/playable-template-phaser/src/theme/theme.metadata.md +60 -0
  42. package/project-templates/playable-template-phaser/src/theme/theme.schema.json5 +149 -0
  43. package/project-templates/playable-template-phaser/src/ui/BrainAgeUI.ts +681 -0
  44. package/project-templates/playable-template-phaser/src/ui/CountdownUI.ts +565 -0
  45. package/project-templates/playable-template-phaser/src/ui/PlayButton.ts +51 -0
  46. package/project-templates/playable-template-phaser/src/ui/ScoreUI.ts +207 -0
  47. package/project-templates/playable-template-phaser/src/ui/SuccessUI.ts +43 -0
  48. package/project-templates/playable-template-phaser/src/ui/index.ts +15 -0
  49. package/project-templates/playable-template-phaser/tsconfig.json +26 -0
  50. package/project-templates/playable-template-phaser/vite.config.ts +64 -0
  51. 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
  52. package/project-templates/playable-template-three/README.md +795 -0
  53. package/project-templates/playable-template-three/assets/Stork.glb +0 -0
  54. package/project-templates/playable-template-three/assets/button.png +0 -0
  55. package/project-templates/playable-template-three/assets/logo.webp +0 -0
  56. package/project-templates/playable-template-three/build.json +7 -0
  57. package/project-templates/playable-template-three/builds.config.example.js +151 -0
  58. package/project-templates/playable-template-three/builds.config.js +158 -0
  59. package/project-templates/playable-template-three/package.json +36 -0
  60. package/project-templates/playable-template-three/scripts/convert-to-webp.js +370 -0
  61. package/project-templates/playable-template-three/scripts/theme-builds.js +514 -0
  62. package/project-templates/playable-template-three/src/Game.ts +215 -0
  63. package/project-templates/playable-template-three/src/config/LoadingConfig.ts +27 -0
  64. package/project-templates/playable-template-three/src/config/ThemeConfig.ts +36 -0
  65. package/project-templates/playable-template-three/src/global.d.ts +108 -0
  66. package/project-templates/playable-template-three/src/index.css +18 -0
  67. package/project-templates/playable-template-three/src/index.html +9 -0
  68. package/project-templates/playable-template-three/src/index.ts +20 -0
  69. package/project-templates/playable-template-three/src/managers/AudioManager.ts +538 -0
  70. package/project-templates/playable-template-three/src/scenes/PreloadScene.ts +305 -0
  71. package/project-templates/playable-template-three/src/theme/README.md +225 -0
  72. package/project-templates/playable-template-three/src/theme/blue-theme/assets/.gitkeep +28 -0
  73. package/project-templates/playable-template-three/src/theme/blue-theme/index.ts +45 -0
  74. package/project-templates/playable-template-three/src/theme/current.ts +12 -0
  75. package/project-templates/playable-template-three/src/theme/green-theme/assets/.gitkeep +3 -0
  76. package/project-templates/playable-template-three/src/theme/green-theme/index.ts +34 -0
  77. package/project-templates/playable-template-three/src/theme/red-theme/assets/.gitkeep +3 -0
  78. package/project-templates/playable-template-three/src/theme/red-theme/index.ts +34 -0
  79. package/project-templates/playable-template-three/tsconfig.json +24 -0
@@ -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
+ 祝开发顺利!🎮