@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.
- package/dist/commands/create.js +164 -98
- package/dist/index.js +4 -1
- package/dist/scaffold/templates.js +35 -0
- package/package.json +3 -3
- 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
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# PlayCraft 平台改造总结
|
|
2
|
+
|
|
3
|
+
本文档记录了 `playable-template-phaser` 从原有架构改造为 PlayCraft 平台架构的完整过程。
|
|
4
|
+
|
|
5
|
+
## 改造概述
|
|
6
|
+
|
|
7
|
+
**改造前**:使用 `@tencent/playable-sdk` + 硬编码配置
|
|
8
|
+
|
|
9
|
+
**改造后**:使用 `@playcraft/adsdk` + JSON5 Schema 配置化架构
|
|
10
|
+
|
|
11
|
+
## 改造内容
|
|
12
|
+
|
|
13
|
+
### 1. SDK 依赖替换
|
|
14
|
+
|
|
15
|
+
#### ✅ globals.d.ts
|
|
16
|
+
|
|
17
|
+
```diff
|
|
18
|
+
- /// <reference types="@tencent/playable-sdk/defines" />
|
|
19
|
+
- /// <reference types="@tencent/playable-scripts/defines" />
|
|
20
|
+
+ /// <reference types="@playcraft/adsdk/defines" />
|
|
21
|
+
+ /// <reference types="@playcraft/devkit/defines" />
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
#### ✅ package.json
|
|
25
|
+
|
|
26
|
+
- 添加 `vite`、`json5`、`typescript`、`@types/node`
|
|
27
|
+
- 添加 `json5-loader` 等构建工具
|
|
28
|
+
- 新增 `dev` 脚本(Vite)和 `dev:wp` 脚本
|
|
29
|
+
|
|
30
|
+
### 2. 本地开发支持
|
|
31
|
+
|
|
32
|
+
#### ✅ 新增文件
|
|
33
|
+
|
|
34
|
+
- `vite.config.ts` - Vite 配置,支持 JSON5 插件和路径别名
|
|
35
|
+
- `index.html` - Vite 入口 HTML
|
|
36
|
+
- `src/json5.d.ts` - JSON5 模块类型声明
|
|
37
|
+
|
|
38
|
+
### 3. 主题系统配置化
|
|
39
|
+
|
|
40
|
+
#### ✅ 新增配置协议
|
|
41
|
+
|
|
42
|
+
- `src/theme/theme.schema.json5` - 定义所有可配置项及默认值
|
|
43
|
+
- `src/theme/theme.metadata.md` - 主题元数据文档
|
|
44
|
+
|
|
45
|
+
#### ✅ 改造主题目录
|
|
46
|
+
|
|
47
|
+
每个主题目录(blue-theme、green-theme、red-theme):
|
|
48
|
+
|
|
49
|
+
- 新增 `theme.data.json5` - 配置覆盖文件
|
|
50
|
+
- 改造 `index.ts` - 导出 `themeData` 和 `assetRecordByPath`
|
|
51
|
+
|
|
52
|
+
**改造前**:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
const config: ThemeConfig = {
|
|
56
|
+
name: '蓝色主题',
|
|
57
|
+
backgroundColor: 0x4a90e2,
|
|
58
|
+
// ... 大量硬编码配置
|
|
59
|
+
};
|
|
60
|
+
export default config;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**改造后**:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import themeData from './theme.data.json5';
|
|
67
|
+
const assetRecordByPath = {
|
|
68
|
+
/* 资源映射 */
|
|
69
|
+
};
|
|
70
|
+
export default { themeData, assetRecordByPath };
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 4. 配置获取方式改造
|
|
74
|
+
|
|
75
|
+
#### ✅ ThemeConfig.ts
|
|
76
|
+
|
|
77
|
+
- 从硬编码接口改为通过 `sdk.getConfig()` 获取
|
|
78
|
+
- 使用 getter 延迟获取,避免模块顶层缓存问题
|
|
79
|
+
|
|
80
|
+
**改造前**:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
export interface ThemeConfig {
|
|
84
|
+
backgroundColor: number;
|
|
85
|
+
// ...
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**改造后**:
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
export const GameThemeConfig = {
|
|
93
|
+
get BACKGROUND_COLOR(): number {
|
|
94
|
+
return get('visual.backgroundColor', 0xf7d37f);
|
|
95
|
+
},
|
|
96
|
+
// ...
|
|
97
|
+
};
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
#### ✅ LoadingConfig.ts
|
|
101
|
+
|
|
102
|
+
- 同样改为通过 `sdk.getConfig()` 获取
|
|
103
|
+
- 移除硬编码的资源 import
|
|
104
|
+
|
|
105
|
+
### 5. 入口文件改造
|
|
106
|
+
|
|
107
|
+
#### ✅ src/index.ts
|
|
108
|
+
|
|
109
|
+
添加主题系统初始化:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import ThemeConfig from './theme/theme.schema.json5';
|
|
113
|
+
import Theme from './theme';
|
|
114
|
+
|
|
115
|
+
sdk.setConfig([ThemeConfig, Theme.themeData], {
|
|
116
|
+
assetRecordByPath: Theme.assetRecordByPath,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
sdk.playcraftInit((width, height) => {
|
|
120
|
+
// ...
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### 6. 场景文件改造
|
|
125
|
+
|
|
126
|
+
#### ✅ src/scenes/MainScene.ts
|
|
127
|
+
|
|
128
|
+
```diff
|
|
129
|
+
- import themeConfig from '../theme/index';
|
|
130
|
+
+ import { GameThemeConfig } from '../config/ThemeConfig';
|
|
131
|
+
|
|
132
|
+
- this.cameras.main.setBackgroundColor(themeConfig.backgroundColor);
|
|
133
|
+
+ this.cameras.main.setBackgroundColor(GameThemeConfig.BACKGROUND_COLOR);
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 7. 项目配置文件
|
|
137
|
+
|
|
138
|
+
#### ✅ 新增/更新
|
|
139
|
+
|
|
140
|
+
- `.playcraftignore` - 构建排除配置
|
|
141
|
+
- `CLAUDE.md` - 详细项目说明
|
|
142
|
+
- `PLAYCRAFT-MIGRATION.md` - 改造总结(本文档)
|
|
143
|
+
- `新手开发指南.md` - 更新后的开发指南
|
|
144
|
+
|
|
145
|
+
#### ✅ tsconfig.json
|
|
146
|
+
|
|
147
|
+
添加路径别名:
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
"paths": {
|
|
151
|
+
"assets/*": ["./assets/*"],
|
|
152
|
+
"@/*": ["./src/*"],
|
|
153
|
+
"src/*": ["./src/*"]
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### ✅ README.md
|
|
158
|
+
|
|
159
|
+
更新为 PlayCraft 平台说明
|
|
160
|
+
|
|
161
|
+
## 改造后的优势
|
|
162
|
+
|
|
163
|
+
### 1. 配置化
|
|
164
|
+
|
|
165
|
+
- ✅ 主题配置集中管理
|
|
166
|
+
- ✅ 配置与代码分离
|
|
167
|
+
- ✅ 支持 PlayCraft 平台在线编辑
|
|
168
|
+
|
|
169
|
+
### 2. 开发体验
|
|
170
|
+
|
|
171
|
+
- ✅ Vite 极速 HMR 热更新
|
|
172
|
+
- ✅ 更好的类型提示
|
|
173
|
+
- ✅ 配置使用 JSON5(支持注释)
|
|
174
|
+
|
|
175
|
+
### 3. 维护性
|
|
176
|
+
|
|
177
|
+
- ✅ 配置优先级清晰(schema → data)
|
|
178
|
+
- ✅ 资源路径自动解析
|
|
179
|
+
- ✅ 避免模块顶层缓存问题
|
|
180
|
+
|
|
181
|
+
### 4. 扩展性
|
|
182
|
+
|
|
183
|
+
- ✅ 易于添加新主题(只需写差异配置)
|
|
184
|
+
- ✅ 易于添加新配置项
|
|
185
|
+
- ✅ 支持批量构建
|
|
186
|
+
|
|
187
|
+
## 配置系统工作流程
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
1. sdk.setConfig([ThemeConfig, themeData], { assetRecordByPath })
|
|
191
|
+
↓
|
|
192
|
+
2. SDK 提取 schema 的 default 值作为基底配置
|
|
193
|
+
↓
|
|
194
|
+
3. 深度合并 基底配置 + themeData 覆盖值
|
|
195
|
+
↓
|
|
196
|
+
4. 递归解析资源路径(通过 assetRecordByPath 映射)
|
|
197
|
+
↓
|
|
198
|
+
5. sdk.getConfig() 返回最终配置
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## 使用示例
|
|
202
|
+
|
|
203
|
+
### 添加新配置项
|
|
204
|
+
|
|
205
|
+
1. 在 `theme.schema.json5` 中定义:
|
|
206
|
+
|
|
207
|
+
```json5
|
|
208
|
+
gameplay: {
|
|
209
|
+
maxScore: {
|
|
210
|
+
type: "integer",
|
|
211
|
+
default: 1000,
|
|
212
|
+
description: "最高分数",
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
2. 在 `ThemeConfig.ts` 中添加 getter:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
get MAX_SCORE(): number { return get('gameplay.maxScore', 1000); }
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
3. 在代码中使用:
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
const maxScore = GameThemeConfig.MAX_SCORE;
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 添加新资源
|
|
230
|
+
|
|
231
|
+
1. 在 `theme.schema.json5` 中定义路径:
|
|
232
|
+
|
|
233
|
+
```json5
|
|
234
|
+
assets: {
|
|
235
|
+
logo: {
|
|
236
|
+
type: "string",
|
|
237
|
+
default: "./assets/logo.webp",
|
|
238
|
+
xplatform: { value_type: "path", mime_type: "image/webp" },
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
2. 在主题 `index.ts` 中映射:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import logoWebp from 'assets/logo.webp';
|
|
247
|
+
const assetRecordByPath = {
|
|
248
|
+
'./assets/logo.webp': logoWebp,
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
3. 在配置中获取:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
get ASSET_LOGO(): string { return get('assets.logo', ''); }
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## 注意事项
|
|
259
|
+
|
|
260
|
+
### ⚠️ 必须使用 getter
|
|
261
|
+
|
|
262
|
+
配置获取器必须使用 getter 而非顶层常量:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// ❌ 错误:模块加载时立即执行,此时 setConfig 还没调用
|
|
266
|
+
const CONFIG = sdk.getConfig();
|
|
267
|
+
|
|
268
|
+
// ✅ 正确:运行时获取
|
|
269
|
+
get CONFIG() { return sdk.getConfig(); }
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### ⚠️ schema 必须有 $schema 字段
|
|
273
|
+
|
|
274
|
+
```json5
|
|
275
|
+
{
|
|
276
|
+
$schema: 'http://json-schema.org/draft-07/schema#', // 必须!
|
|
277
|
+
// ...
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### ⚠️ 资源路径必须一致
|
|
282
|
+
|
|
283
|
+
```json5
|
|
284
|
+
// schema 中的路径
|
|
285
|
+
default: "./assets/logo.webp"
|
|
286
|
+
|
|
287
|
+
// assetRecordByPath 中的 key 必须完全一致
|
|
288
|
+
'./assets/logo.webp': logoWebp
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## 检查清单
|
|
292
|
+
|
|
293
|
+
- [x] globals.d.ts 类型引用已更新
|
|
294
|
+
- [x] package.json 依赖已更新
|
|
295
|
+
- [x] vite.config.ts 已创建
|
|
296
|
+
- [x] index.html 已创建
|
|
297
|
+
- [x] src/json5.d.ts 已创建
|
|
298
|
+
- [x] theme.schema.json5 已创建
|
|
299
|
+
- [x] theme.metadata.md 已创建
|
|
300
|
+
- [x] 所有主题已改造(theme.data.json5 + index.ts)
|
|
301
|
+
- [x] src/index.ts 已添加 setConfig
|
|
302
|
+
- [x] ThemeConfig.ts 已改为 sdk.getConfig()
|
|
303
|
+
- [x] LoadingConfig.ts 已改为 sdk.getConfig()
|
|
304
|
+
- [x] MainScene.ts 已更新配置引用
|
|
305
|
+
- [x] tsconfig.json 已更新路径别名
|
|
306
|
+
- [x] .playcraftignore 已创建
|
|
307
|
+
- [x] CLAUDE.md 已创建
|
|
308
|
+
- [x] README.md 已更新
|
|
309
|
+
- [x] 所有 lint 错误已修复
|
|
310
|
+
- [x] 新手开发指南已更新
|
|
311
|
+
|
|
312
|
+
## 下一步
|
|
313
|
+
|
|
314
|
+
1. 运行 `npm install` 安装新依赖
|
|
315
|
+
2. 运行 `npm run dev` 测试 Vite 开发服务器
|
|
316
|
+
3. 运行 `npm run dev:wp` 测试 playable-scripts 开发服务器
|
|
317
|
+
4. 运行 `npm run builds` 测试批量构建
|
|
318
|
+
|
|
319
|
+
## 参考文档
|
|
320
|
+
|
|
321
|
+
- [PlayCraft 平台改造 Skill](../skills/playable-platform-refactor/SKILL.md)
|
|
322
|
+
- [项目详细说明](./CLAUDE.md)
|
|
323
|
+
- [开发指南](./新手开发指南.md)
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
改造完成时间:2026-04-24
|
|
328
|
+
改造完成者:AI Assistant
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
# Playable Template - Phaser
|
|
2
|
+
|
|
3
|
+
基于 Phaser 3 游戏框架的可玩广告开发模板,使用 PlayCraft 平台架构,支持 TypeScript。
|
|
4
|
+
|
|
5
|
+
## 技术栈
|
|
6
|
+
|
|
7
|
+
- [Phaser 3](https://phaser.io/) - 高性能 2D 游戏框架
|
|
8
|
+
- [@playcraft/adsdk](https://www.npmjs.com/package/@playcraft/adsdk) - 可玩广告 SDK
|
|
9
|
+
- [@playcraft/devkit](https://www.npmjs.com/package/@playcraft/devkit) - 构建工具
|
|
10
|
+
- [Vite](https://vitejs.dev/) - 本地开发服务器(支持 HMR)
|
|
11
|
+
|
|
12
|
+
## 功能特性
|
|
13
|
+
|
|
14
|
+
- ✅ Phaser 3 集成,支持高性能 2D 游戏开发
|
|
15
|
+
- ✅ TypeScript 支持
|
|
16
|
+
- ✅ **配置化主题系统** - JSON5 Schema + 覆盖配置
|
|
17
|
+
- ✅ **Vite 本地开发** - 超快的 HMR 热更新
|
|
18
|
+
- ✅ **响应式适配** - 自动适配横竖屏和不同设备
|
|
19
|
+
- ✅ **批量构建** - 支持多主题、多渠道批量打包
|
|
20
|
+
- ✅ SDK 事件处理(resize、pause、resume、volume 等)
|
|
21
|
+
|
|
22
|
+
## 快速开始
|
|
23
|
+
|
|
24
|
+
### 1. 安装依赖
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. 启动开发服务器
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# 使用 Vite 开发服务器(推荐,速度快,支持 HMR)
|
|
34
|
+
npm run dev
|
|
35
|
+
|
|
36
|
+
# 使用 playable-scripts 开发服务器(与构建环境一致)
|
|
37
|
+
npm run dev:wp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
开发服务器默认运行在 `http://localhost:3000`(Vite)或 `http://localhost:8080`(playable-scripts)
|
|
41
|
+
|
|
42
|
+
### 3. 构建生产版本
|
|
43
|
+
|
|
44
|
+
#### 单渠道构建
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm run build -- <network>
|
|
48
|
+
|
|
49
|
+
# 示例
|
|
50
|
+
npm run build -- google # Google Ads
|
|
51
|
+
npm run build -- facebook # Meta
|
|
52
|
+
npm run build -- unity # Unity Ads
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 批量构建
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run builds # 构建所有主题和渠道
|
|
59
|
+
npm run builds -- -t "theme1,theme2" # 构建指定主题
|
|
60
|
+
npm run builds -- -c "google,facebook" # 构建指定渠道
|
|
61
|
+
npm run builds -- -t "theme1" -c "google" # 组合使用
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### 打包为 PlayCraft 模板
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run pack-to-playcraft-template-zip
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 脚本命令
|
|
71
|
+
|
|
72
|
+
| 命令 | 说明 |
|
|
73
|
+
| ---------------------------------------- | -------------------------------- |
|
|
74
|
+
| `npm run dev` | 启动 Vite 开发服务器(推荐) |
|
|
75
|
+
| `npm run dev:wp` | 启动 playable-scripts 开发服务器 |
|
|
76
|
+
| `npm run build -- <network>` | 构建指定渠道 |
|
|
77
|
+
| `npm run builds` | 批量构建所有主题和渠道 |
|
|
78
|
+
| `npm run pack-to-playcraft-template-zip` | 打包为 PlayCraft 模板 ZIP |
|
|
79
|
+
| `npm run webp` | 将图片转为 WebP 格式(质量 90) |
|
|
80
|
+
| `npm run webp:80` | 将图片转为 WebP 格式(质量 80) |
|
|
81
|
+
|
|
82
|
+
## 项目结构
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
playable-template-phaser/
|
|
86
|
+
├── assets/ # 公共资源目录
|
|
87
|
+
│ └── logo.webp
|
|
88
|
+
├── src/
|
|
89
|
+
│ ├── theme/ # 主题系统
|
|
90
|
+
│ │ ├── theme.schema.json5 # 配置协议(默认值)
|
|
91
|
+
│ │ ├── theme.metadata.md # 主题元数据
|
|
92
|
+
│ │ ├── blue-theme/ # 蓝色主题
|
|
93
|
+
│ │ │ ├── index.ts # 主题入口
|
|
94
|
+
│ │ │ ├── theme.data.json5 # 配置覆盖
|
|
95
|
+
│ │ │ └── assets/ # 主题资源
|
|
96
|
+
│ │ ├── green-theme/ # 绿色主题
|
|
97
|
+
│ │ ├── red-theme/ # 红色主题
|
|
98
|
+
│ │ └── index.ts # 主题统一出口
|
|
99
|
+
│ ├── scenes/ # Phaser 场景
|
|
100
|
+
│ │ ├── PreloadScene.ts # 预加载场景
|
|
101
|
+
│ │ └── MainScene.ts # 主游戏场景
|
|
102
|
+
│ ├── config/ # 配置管理
|
|
103
|
+
│ │ ├── ThemeConfig.ts # 主题配置获取器
|
|
104
|
+
│ │ └── LoadingConfig.ts # Loading 配置
|
|
105
|
+
│ ├── managers/ # 管理器
|
|
106
|
+
│ │ └── AudioManager.ts # 音频管理器
|
|
107
|
+
│ ├── ui/ # UI 组件
|
|
108
|
+
│ ├── Game.ts # Phaser.Game 配置
|
|
109
|
+
│ ├── index.ts # 入口文件
|
|
110
|
+
│ ├── index.css # 样式文件
|
|
111
|
+
│ └── json5.d.ts # JSON5 类型声明
|
|
112
|
+
├── vite.config.ts # Vite 配置
|
|
113
|
+
├── index.html # Vite 入口 HTML
|
|
114
|
+
├── builds.config.js # 批量构建配置
|
|
115
|
+
├── tsconfig.json # TypeScript 配置
|
|
116
|
+
├── globals.d.ts # 全局类型声明
|
|
117
|
+
├── .playcraftignore # 构建排除配置
|
|
118
|
+
├── CLAUDE.md # 项目说明(详细版)
|
|
119
|
+
└── package.json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## 主题系统
|
|
123
|
+
|
|
124
|
+
### 配置化架构
|
|
125
|
+
|
|
126
|
+
项目采用 PlayCraft 平台的配置化架构:
|
|
127
|
+
|
|
128
|
+
1. **配置协议**(`theme.schema.json5`)- 定义所有可配置项及默认值
|
|
129
|
+
2. **配置覆盖**(`theme.data.json5`)- 各主题只需写与默认值不同的配置
|
|
130
|
+
3. **资源映射**(`assetRecordByPath`)- 自动将配置中的路径解析为真实 URL
|
|
131
|
+
|
|
132
|
+
### 配置优先级
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
theme.data.json5(主题覆盖)> theme.schema.json5(默认值)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 切换主题
|
|
139
|
+
|
|
140
|
+
修改 `src/theme/index.ts`:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
export { default } from './blue-theme'; // 蓝色主题
|
|
144
|
+
// export { default } from './green-theme'; // 绿色主题
|
|
145
|
+
// export { default } from './red-theme'; // 红色主题
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 添加新主题
|
|
149
|
+
|
|
150
|
+
1. 复制现有主题目录(如 `blue-theme`)
|
|
151
|
+
2. 修改 `theme.data.json5` 配置
|
|
152
|
+
3. 添加主题特定资源到 `assets/` 目录
|
|
153
|
+
4. 更新 `index.ts` 的资源映射
|
|
154
|
+
5. 在 `theme/index.ts` 切换主题
|
|
155
|
+
|
|
156
|
+
### 主题列表
|
|
157
|
+
|
|
158
|
+
| 主题 ID | 难度 | 提示 | 说明 |
|
|
159
|
+
| ------- | ---- | ---- | ------------------------------------- |
|
|
160
|
+
| blue | 5 | ✅ | 蓝色主题 - 适合海洋、天空、科技类游戏 |
|
|
161
|
+
| green | 3 | ✅ | 绿色主题 - 适合自然、森林、环保类游戏 |
|
|
162
|
+
| red | 7 | ❌ | 红色主题 - 适合动作、冒险、激情类游戏 |
|
|
163
|
+
|
|
164
|
+
## 配置系统
|
|
165
|
+
|
|
166
|
+
### 读取配置
|
|
167
|
+
|
|
168
|
+
使用 `sdk.getConfig()` 或封装的配置获取器:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { GameThemeConfig } from './config/ThemeConfig';
|
|
172
|
+
|
|
173
|
+
// 获取配置值
|
|
174
|
+
const backgroundColor = GameThemeConfig.BACKGROUND_COLOR;
|
|
175
|
+
const difficulty = GameThemeConfig.DIFFICULTY;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 资源路径解析
|
|
179
|
+
|
|
180
|
+
资源路径通过 `assetRecordByPath` 自动解析为真实 URL:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// theme.schema.json5 中定义路径
|
|
184
|
+
assets: {
|
|
185
|
+
logo: {
|
|
186
|
+
default: "./assets/logo.webp"
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// theme/index.ts 中映射路径
|
|
191
|
+
import logoWebp from 'assets/logo.webp';
|
|
192
|
+
const assetRecordByPath = {
|
|
193
|
+
'./assets/logo.webp': logoWebp,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// 代码中获取 URL
|
|
197
|
+
const logoUrl = GameThemeConfig.ASSET_LOGO; // 解析后的真实 URL
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## 响应式适配
|
|
201
|
+
|
|
202
|
+
模板采用 `WIDTH_CONTROLS_HEIGHT` 缩放模式:
|
|
203
|
+
|
|
204
|
+
- ✅ 固定设计宽度(1280px)
|
|
205
|
+
- ✅ 高度自适应
|
|
206
|
+
- ✅ 自动画布缩放
|
|
207
|
+
- ✅ 横竖屏切换时自动刷新
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Game.ts
|
|
211
|
+
const DESIGN_WIDTH = 1280;
|
|
212
|
+
|
|
213
|
+
export class Game extends Phaser.Game {
|
|
214
|
+
constructor(width: number, height: number) {
|
|
215
|
+
const gameWidth = DESIGN_WIDTH;
|
|
216
|
+
const gameHeight = height * (DESIGN_WIDTH / width);
|
|
217
|
+
|
|
218
|
+
super({
|
|
219
|
+
width: gameWidth,
|
|
220
|
+
height: gameHeight,
|
|
221
|
+
scale: {
|
|
222
|
+
mode: Phaser.Scale.WIDTH_CONTROLS_HEIGHT,
|
|
223
|
+
autoCenter: Phaser.Scale.CENTER_BOTH,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## SDK 使用
|
|
231
|
+
|
|
232
|
+
### 初始化
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
import { sdk } from '@playcraft/adsdk';
|
|
236
|
+
import ThemeConfig from './theme/theme.schema.json5';
|
|
237
|
+
import Theme from './theme';
|
|
238
|
+
|
|
239
|
+
// 1. 设置配置(必须在 playcraftInit 之前)
|
|
240
|
+
sdk.setConfig([ThemeConfig, Theme.themeData], {
|
|
241
|
+
assetRecordByPath: Theme.assetRecordByPath,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// 2. 初始化 SDK
|
|
245
|
+
sdk.playcraftInit((width: number, height: number) => {
|
|
246
|
+
const game = new Game(width, height);
|
|
247
|
+
|
|
248
|
+
// 3. 监听事件
|
|
249
|
+
sdk.on('playcraftResize', game.resize, game);
|
|
250
|
+
sdk.on('playcraftPause', game.pause, game);
|
|
251
|
+
sdk.on('playcraftResume', game.resume, game);
|
|
252
|
+
sdk.on('playcraftVolume', game.volume, game);
|
|
253
|
+
sdk.on('playcraftFinish', game.finish, game);
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### SDK 事件
|
|
258
|
+
|
|
259
|
+
| 事件 | 说明 |
|
|
260
|
+
| ----------------- | ------------ |
|
|
261
|
+
| `playcraftResize` | 屏幕尺寸变化 |
|
|
262
|
+
| `playcraftPause` | 游戏暂停 |
|
|
263
|
+
| `playcraftResume` | 游戏恢复 |
|
|
264
|
+
| `playcraftVolume` | 音量变化 |
|
|
265
|
+
| `playcraftFinish` | 游戏结束 |
|
|
266
|
+
|
|
267
|
+
### SDK 生命周期
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
sdk.playcraftInit(); // 初始化,获取容器尺寸
|
|
271
|
+
sdk.start(); // 游戏资源加载完成后调用
|
|
272
|
+
sdk.finish(); // 游戏结束时调用
|
|
273
|
+
sdk.install(); // 跳转应用商店
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## 批量构建配置
|
|
277
|
+
|
|
278
|
+
创建 `builds.config.js`:
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
module.exports = {
|
|
282
|
+
// 项目名称(用于 html title 生成)
|
|
283
|
+
title: 'Phaser-Template',
|
|
284
|
+
|
|
285
|
+
// 可玩广告对应的 App 名称
|
|
286
|
+
appName: 'Sola Mahjong',
|
|
287
|
+
|
|
288
|
+
// 商店链接(可选)
|
|
289
|
+
googlePlayUrl: 'https://play.google.com/...',
|
|
290
|
+
appStoreUrl: 'https://apps.apple.com/...',
|
|
291
|
+
|
|
292
|
+
// 渠道列表(可选,有默认值)
|
|
293
|
+
channels: ['google', 'facebook', 'unity', 'bigoads'],
|
|
294
|
+
|
|
295
|
+
// 主题配置(可选)
|
|
296
|
+
themes: {
|
|
297
|
+
enabled: true,
|
|
298
|
+
sourceDir: 'src/theme',
|
|
299
|
+
entryFile: 'src/theme/index.ts',
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
// 文件命名(可选,有默认值)
|
|
303
|
+
naming: {
|
|
304
|
+
language: 'EN',
|
|
305
|
+
format: '无',
|
|
306
|
+
supplier: 'AIX',
|
|
307
|
+
follower: 'ZQL',
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
// 构建配置(可选,有默认值)
|
|
311
|
+
build: {
|
|
312
|
+
outputDir: 'dist-all',
|
|
313
|
+
continueOnError: true,
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
// 混淆配置(可选)
|
|
317
|
+
obfuscate: {
|
|
318
|
+
level: 2, // 0=不混淆, 1=简单, 2=标准, 3=最高
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## 支持的渠道
|
|
324
|
+
|
|
325
|
+
- google (Google Ads)
|
|
326
|
+
- facebook (Meta)
|
|
327
|
+
- tiktok (TikTok)
|
|
328
|
+
- applovin (AppLovin)
|
|
329
|
+
- ironSource (IronSource)
|
|
330
|
+
- unity (Unity Ads)
|
|
331
|
+
- moloco (Moloco)
|
|
332
|
+
- liftoff (Liftoff)
|
|
333
|
+
- bigoads (BigoAds)
|
|
334
|
+
- adikteev (Adikteev)
|
|
335
|
+
- inmobi (InMobi)
|
|
336
|
+
- snapchat (Snapchat)
|
|
337
|
+
|
|
338
|
+
## 环境要求
|
|
339
|
+
|
|
340
|
+
- Node.js >= 16.0.0
|
|
341
|
+
- npm >= 7.0.0
|
|
342
|
+
|
|
343
|
+
## 常见问题
|
|
344
|
+
|
|
345
|
+
### Q1: 资源 URL 为空
|
|
346
|
+
|
|
347
|
+
**原因**:`assetRecordByPath` 缺少路径映射
|
|
348
|
+
|
|
349
|
+
**解决**:在主题 `index.ts` 中添加资源映射
|
|
350
|
+
|
|
351
|
+
### Q2: 配置值为 undefined
|
|
352
|
+
|
|
353
|
+
**原因**:`theme.schema.json5` 缺少该字段的 `default` 值
|
|
354
|
+
|
|
355
|
+
**解决**:在 schema 中添加字段定义及默认值
|
|
356
|
+
|
|
357
|
+
### Q3: 模块顶层缓存导致配置为空
|
|
358
|
+
|
|
359
|
+
**原因**:在模块加载时立即读取配置,此时 `sdk.setConfig()` 还没执行
|
|
360
|
+
|
|
361
|
+
**解决**:使用 getter 延迟获取,或在运行时获取配置
|
|
362
|
+
|
|
363
|
+
## 相关技能
|
|
364
|
+
|
|
365
|
+
如需进行以下操作,请加载对应技能:
|
|
366
|
+
|
|
367
|
+
- **SDK 埋点检查**:`playable-sdk-tracking`
|
|
368
|
+
- **构建产物检查**:`playable-output-checker`
|
|
369
|
+
- **项目初始化**:`playable-project-scaffold`
|
|
370
|
+
- **资源提取/重打包**:`game-asset-extractor`
|
|
371
|
+
|
|
372
|
+
## 参考资料
|
|
373
|
+
|
|
374
|
+
- [Phaser 3 官方文档](https://photonstorm.github.io/phaser3-docs/)
|
|
375
|
+
- [Phaser 3 示例](https://phaser.io/examples)
|
|
376
|
+
- [PlayCraft 平台改造指南](./playable-template/skills/playable-platform-refactor/SKILL.md)
|
|
377
|
+
- [项目详细说明](./CLAUDE.md)
|
|
378
|
+
|
|
379
|
+
## 许可证
|
|
380
|
+
|
|
381
|
+
MIT
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|