整理中文文档结构与索引
This commit is contained in:
414
doc/archive/experience/H5体验接入方案.md
Normal file
414
doc/archive/experience/H5体验接入方案.md
Normal file
@@ -0,0 +1,414 @@
|
||||
# H5 体验接入方案
|
||||
|
||||
本文档用于定义当前项目中 **原生小程序 + H5 定制内容** 的混合接入方案。
|
||||
|
||||
目标:
|
||||
|
||||
- 保留原生地图与实时游戏主流程
|
||||
- 把高频变化、强定制的内容页交给 H5
|
||||
- 保证 H5 失败时,原生仍可完整兜底
|
||||
- 为后续客户定制、品牌包装、互动任务扩展留出稳定接口
|
||||
|
||||
---
|
||||
|
||||
## 1. 结论
|
||||
|
||||
当前最合适的方向不是“所有定制都 H5 化”,而是:
|
||||
|
||||
**原生负责核心游戏层,H5 负责定制体验层。**
|
||||
|
||||
也就是:
|
||||
|
||||
- 地图、打点、GPS、指北针、HUD、规则状态机继续原生
|
||||
- 结算页、文创详情、拍照任务、语音留言、小游戏、品牌包装页交给 H5
|
||||
|
||||
---
|
||||
|
||||
## 2. 适合 H5 化的内容
|
||||
|
||||
当前最适合 H5 承接的是:
|
||||
|
||||
- 结算页
|
||||
- 打点后的定制**详情页/互动页**
|
||||
- 文创详情页
|
||||
- 活动品牌页
|
||||
- 富图文任务页
|
||||
- 拍照上传 / 语音留言 / 小游戏类互动页
|
||||
- 表单、问卷、抽奖、作品提交页
|
||||
|
||||
不建议 H5 化的部分:
|
||||
|
||||
- 地图主界面
|
||||
- 打点逻辑
|
||||
- 自动转图
|
||||
- 指北针
|
||||
- HUD
|
||||
- GPS / 心率等实时能力主链
|
||||
- 需要强实时状态同步的高频游戏弹层
|
||||
- 游戏中的即时原生内容弹窗
|
||||
|
||||
一句话:
|
||||
|
||||
**核心实时游戏层保留原生,变化快的定制内容层交给 H5。**
|
||||
|
||||
---
|
||||
|
||||
## 2.1 当前阶段的定案
|
||||
|
||||
经过真机验证,当前项目已经明确:
|
||||
|
||||
- 小程序 `web-view` 在企业主体环境下可以正常打开
|
||||
- 但它不适合作为“原生弹窗里的局部 H5 内容区”使用
|
||||
- 真机上更接近整页原生容器,局部裁切、壳子覆盖、原生关闭按钮都不稳定
|
||||
|
||||
因此当前正式定案为:
|
||||
|
||||
- **打点后的即时内容:原生内容卡**
|
||||
- **H5:只作为详情页 / 互动任务页 / 全屏结果页**
|
||||
|
||||
也就是说:
|
||||
|
||||
- `content popup` 继续原生
|
||||
- 原生内容卡上提供 `查看详情`
|
||||
- 点 `查看详情` 后再进入 H5
|
||||
- H5 打不开时,原生内容卡继续兜底
|
||||
|
||||
---
|
||||
|
||||
## 3. 总体架构
|
||||
|
||||
推荐分成三层:
|
||||
|
||||
### 3.1 原生层
|
||||
|
||||
职责:
|
||||
|
||||
- 地图与渲染
|
||||
- GPS / 指北针 / 自动转图
|
||||
- 打点状态机
|
||||
- HUD
|
||||
- 心率 / telemetry
|
||||
- 原生内容卡兜底
|
||||
- 原生结果页兜底
|
||||
- 核心状态与本地缓存
|
||||
|
||||
### 3.2 H5 体验层
|
||||
|
||||
职责:
|
||||
|
||||
- 定制内容展示
|
||||
- 品牌包装
|
||||
- 富交互任务
|
||||
- 定制结算页
|
||||
- 富图文与媒体内容
|
||||
|
||||
### 3.3 Bridge 层
|
||||
|
||||
职责:
|
||||
|
||||
- 原生向 H5 注入上下文
|
||||
- H5 向原生请求能力
|
||||
- H5 把结果回传原生
|
||||
|
||||
---
|
||||
|
||||
## 4. 两种 H5 页面类型
|
||||
|
||||
### 4.1 Content Experience Page
|
||||
|
||||
用于游戏中途的**详情体验页**或**互动任务页**。
|
||||
|
||||
典型场景:
|
||||
|
||||
- 控制点打卡后点击 `查看详情`
|
||||
- 控制点点击后进入图文详情页
|
||||
- 拍照上传任务
|
||||
- 语音留言任务
|
||||
- 小游戏互动页
|
||||
- 问答/表单类互动页
|
||||
|
||||
### 4.2 Result Experience Page
|
||||
|
||||
用于游戏结束后的定制结算页。
|
||||
|
||||
典型场景:
|
||||
|
||||
- 活动定制结算
|
||||
- 奖章 / 解锁内容
|
||||
- 排名 / 分享
|
||||
- 作品提交
|
||||
- 品牌化结束页
|
||||
|
||||
---
|
||||
|
||||
## 5. 原生兜底原则
|
||||
|
||||
这是最重要的约束。
|
||||
|
||||
### 原则 1:核心流程先在原生完成
|
||||
|
||||
例如:
|
||||
|
||||
- 打点成功必须先由原生确认
|
||||
- 比赛结束必须先由原生确认
|
||||
- H5 只是附加体验,不拥有核心状态
|
||||
- 原生内容卡必须先可独立工作
|
||||
|
||||
### 原则 2:H5 打不开时回退原生
|
||||
|
||||
如果:
|
||||
|
||||
- 网络失败
|
||||
- H5 地址失效
|
||||
- 加载超时
|
||||
- Bridge 初始化失败
|
||||
|
||||
则直接回退:
|
||||
|
||||
- 原生内容卡
|
||||
- 原生结果页
|
||||
|
||||
### 原则 3:H5 不控制比赛状态
|
||||
|
||||
H5 可以展示、收集信息、提交任务结果。
|
||||
但不能决定:
|
||||
|
||||
- 是否打卡成功
|
||||
- 是否比赛完成
|
||||
- 是否跳点成功
|
||||
|
||||
这些只能由原生控制。
|
||||
|
||||
### 原则 4:H5 是可选增强,不是主流程依赖
|
||||
|
||||
即使 H5 没有打开:
|
||||
|
||||
- 游戏仍应可继续
|
||||
- 用户仍能完成路线
|
||||
- 用户仍能看到最小内容或最小结果
|
||||
|
||||
---
|
||||
|
||||
## 6. 配置模型建议
|
||||
|
||||
后续建议对“内容体验”和“结果体验”都支持两种类型:
|
||||
|
||||
- `native`
|
||||
- `h5`
|
||||
|
||||
### 6.1 内容体验配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"contentExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/control-3",
|
||||
"bridge": "content-v1",
|
||||
"fallback": "native"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这个字段当前应理解为:
|
||||
|
||||
- `contentExperience` = 原生内容卡上的 H5 **详情/互动扩展**
|
||||
- 不是直接顶替原生内容弹窗
|
||||
|
||||
或:
|
||||
|
||||
```json
|
||||
{
|
||||
"contentExperience": {
|
||||
"type": "native"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 结果页配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"resultExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/result/score-o",
|
||||
"bridge": "result-v1",
|
||||
"fallback": "native"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 建议扩展字段
|
||||
|
||||
后续还可以逐步加入:
|
||||
|
||||
- `template`
|
||||
- `theme`
|
||||
- `timeoutMs`
|
||||
- `allowClose`
|
||||
- `prefetch`
|
||||
- `requiresNetwork`
|
||||
|
||||
---
|
||||
|
||||
## 7. 内容页与结果页的推荐职责
|
||||
|
||||
### 原生最小内容卡
|
||||
|
||||
负责:
|
||||
|
||||
- 最小图文说明
|
||||
- 最小点击查看
|
||||
- 自动弹出兜底
|
||||
|
||||
### H5 内容页
|
||||
|
||||
负责:
|
||||
|
||||
- 强样式定制
|
||||
- 多媒体内容
|
||||
- 任务型互动
|
||||
- 客户活动包装
|
||||
|
||||
### 原生最小结果页
|
||||
|
||||
负责:
|
||||
|
||||
- 结果一定可见
|
||||
- 成绩一定可回顾
|
||||
- 无网络也能展示基础结果
|
||||
|
||||
### H5 结果页
|
||||
|
||||
负责:
|
||||
|
||||
- 品牌化包装
|
||||
- 排名/分享
|
||||
- 作品提交
|
||||
- 奖章、解锁、收集册
|
||||
|
||||
---
|
||||
|
||||
## 8. 性能与体验要求
|
||||
|
||||
H5 接入时必须注意:
|
||||
|
||||
- 不阻塞原生主流程
|
||||
- 不把高频实时状态强行桥接到 H5
|
||||
- 不在地图进行中频繁开重页面
|
||||
- 低端机上优先简化交互和媒体资源
|
||||
|
||||
推荐策略:
|
||||
|
||||
- 内容详情页可以 H5
|
||||
- 地图中高频反馈继续原生
|
||||
- 结算增强页可以 H5
|
||||
- 结果最小摘要必须原生兜底
|
||||
|
||||
---
|
||||
|
||||
## 9. 当前建议实施顺序
|
||||
|
||||
### 第一步
|
||||
|
||||
先实现:
|
||||
|
||||
- 原生最小兜底内容卡
|
||||
- 原生最小结果页
|
||||
|
||||
### 第二步
|
||||
|
||||
新增一个通用 H5 容器页,用于承接:
|
||||
|
||||
- 内容页
|
||||
- 结果页
|
||||
|
||||
### 第三步
|
||||
|
||||
定义 Bridge 协议,并先支持最核心动作:
|
||||
|
||||
- 关闭
|
||||
- 获取上下文
|
||||
- 拍照
|
||||
- 录音
|
||||
- 提交结果
|
||||
|
||||
### 第四步
|
||||
|
||||
再让配置决定:
|
||||
|
||||
- 当前活动走原生
|
||||
- 还是走 H5
|
||||
|
||||
### 第五步
|
||||
|
||||
最后再逐步扩到:
|
||||
|
||||
- 上传能力
|
||||
- 分享能力
|
||||
- 小游戏任务
|
||||
- 作品提交
|
||||
|
||||
---
|
||||
|
||||
## 10. 下一步建议
|
||||
|
||||
当前最适合的下一步不是直接写复杂 H5 页面,而是:
|
||||
|
||||
1. 先定义原生与 H5 的统一入口模型
|
||||
2. 先把 Bridge 协议做小而稳
|
||||
3. 先做一个通用 H5 容器页
|
||||
4. 先让一个简单内容页或一个简单结果页跑通
|
||||
|
||||
---
|
||||
|
||||
## 11. 当前建议结论
|
||||
|
||||
最稳的方案不是“把定制内容都做成 H5”,而是:
|
||||
|
||||
**原生保底,H5 承接定制体验。**
|
||||
|
||||
这样既能支持客户高频变化需求,也不会破坏核心游戏体验。
|
||||
|
||||
---
|
||||
|
||||
## 12. 当前主体能力约束补充
|
||||
|
||||
最近实际排查已经确认:
|
||||
|
||||
- 当前最初使用的是**个人主体**小程序
|
||||
|
||||
在这个前提下,`web-view` 能力可能直接受到限制。
|
||||
这意味着:
|
||||
|
||||
- H5 页面本身可在浏览器打开
|
||||
- 小程序里仍然可能无法通过 `web-view` 打开
|
||||
|
||||
因此当前 H5 接入方案需要增加一个现实前提:
|
||||
|
||||
### 12.1 个人主体下
|
||||
|
||||
可以先做:
|
||||
|
||||
- 容器页
|
||||
- Bridge 协议
|
||||
- 配置结构
|
||||
- 原生兜底逻辑
|
||||
|
||||
但不要指望所有 H5 内容页都能在当前环境稳定跑通。
|
||||
|
||||
### 12.2 企业主体下
|
||||
|
||||
企业主体审核通过后,再优先回归:
|
||||
|
||||
- 最小 `web-view` 测试页
|
||||
- 内容体验页 H5
|
||||
- 结果页 H5
|
||||
|
||||
也就是说:
|
||||
|
||||
当前 H5 方案仍然成立,但在企业主体生效前,应按“预留 + 待验证”看待。
|
||||
|
||||
详细说明见:
|
||||
|
||||
- [platform-capability-notes.md](D:/dev/cmr-mini/doc/debug/平台能力说明.md)
|
||||
|
||||
233
doc/archive/experience/体验壳子方案.md
Normal file
233
doc/archive/experience/体验壳子方案.md
Normal file
@@ -0,0 +1,233 @@
|
||||
# Experience Shell 方案
|
||||
|
||||
本文档用于定义小程序中 H5 定制内容的承载方式。目标不是把 H5 做成真正的同页弹窗,而是做成:
|
||||
|
||||
- 独立页面路由
|
||||
- 原生壳子控制外观
|
||||
- `web-view` 只负责内容区
|
||||
|
||||
这样既保留了 H5 的定制能力,也能让用户感受更接近“弹窗”或“抽屉”。
|
||||
|
||||
---
|
||||
|
||||
## 1. 设计目标
|
||||
|
||||
当前 H5 内容页已经能打开,但整页全屏切换比较生硬,用户体验不够好。
|
||||
新的 `experience-shell` 目标是:
|
||||
|
||||
- 视觉上像弹窗
|
||||
- 保持原生关闭、回退、失败兜底逻辑
|
||||
- 不把地图主页面和 `web-view` 强绑在一起
|
||||
- 为后续结果页 H5、文创内容 H5 复用
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心原则
|
||||
|
||||
### 2.1 不做真正同页 H5 弹窗
|
||||
|
||||
微信小程序里的 `web-view` 更适合放在独立页面中承载。
|
||||
不要尝试把 `web-view` 直接叠在地图页上方做真弹窗,否则后续很容易遇到:
|
||||
|
||||
- 层级冲突
|
||||
- 手势冲突
|
||||
- iOS / Android 表现不一致
|
||||
- 遮罩和关闭逻辑变脏
|
||||
|
||||
### 2.2 原生壳子 + H5 内容区
|
||||
|
||||
最终结构应该是:
|
||||
|
||||
- 原生遮罩
|
||||
- 原生标题栏
|
||||
- 原生关闭按钮
|
||||
- `web-view` 内容区
|
||||
|
||||
也就是:
|
||||
|
||||
```text
|
||||
experience-shell
|
||||
├─ backdrop
|
||||
├─ native header
|
||||
└─ web-view body
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 支持的展示方式
|
||||
|
||||
第一阶段只支持 3 种:
|
||||
|
||||
- `sheet`
|
||||
- `dialog`
|
||||
- `fullscreen`
|
||||
|
||||
### 3.1 `sheet`
|
||||
|
||||
适合:
|
||||
|
||||
- 打点后的文创内容
|
||||
- 拍照任务
|
||||
- 轻互动内容
|
||||
|
||||
视觉:
|
||||
|
||||
- 自底部升起
|
||||
- 圆角卡片
|
||||
- 半透明暗背景
|
||||
|
||||
### 3.2 `dialog`
|
||||
|
||||
适合:
|
||||
|
||||
- 结果页
|
||||
- 中短内容
|
||||
- 重要说明
|
||||
|
||||
视觉:
|
||||
|
||||
- 居中大卡片
|
||||
- 更聚焦
|
||||
|
||||
### 3.3 `fullscreen`
|
||||
|
||||
适合:
|
||||
|
||||
- 长内容
|
||||
- 强定制专题页
|
||||
- 复杂表单/小游戏
|
||||
|
||||
---
|
||||
|
||||
## 4. 配置结构
|
||||
|
||||
H5 内容配置建议支持:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/control-1",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "sheet"
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
- `type`
|
||||
当前支持 `native` / `h5`
|
||||
- `url`
|
||||
H5 页面地址
|
||||
- `bridge`
|
||||
bridge 版本
|
||||
- `presentation`
|
||||
展示方式,支持:
|
||||
- `sheet`
|
||||
- `dialog`
|
||||
- `fullscreen`
|
||||
|
||||
默认值建议:
|
||||
|
||||
- 内容体验默认 `sheet`
|
||||
- 结果页默认 `dialog`
|
||||
|
||||
---
|
||||
|
||||
## 5. 原生壳子职责
|
||||
|
||||
原生壳子负责:
|
||||
|
||||
- 遮罩
|
||||
- 标题、副标题
|
||||
- 关闭按钮
|
||||
- 页面进入/退出动画
|
||||
- H5 打开失败回退
|
||||
|
||||
原生壳子不负责:
|
||||
|
||||
- H5 页面内部业务逻辑
|
||||
- H5 具体视觉排版
|
||||
|
||||
---
|
||||
|
||||
## 6. 关闭与回退逻辑
|
||||
|
||||
### 6.1 原生关闭
|
||||
|
||||
原生必须始终支持:
|
||||
|
||||
- 右上/头部关闭
|
||||
- 返回键关闭
|
||||
- 失败时自动关闭并回退
|
||||
|
||||
### 6.2 H5 请求关闭
|
||||
|
||||
H5 可以通过 bridge 发:
|
||||
|
||||
- `close`
|
||||
|
||||
然后由原生统一关闭壳子页。
|
||||
|
||||
### 6.3 H5 失败回退
|
||||
|
||||
如果出现:
|
||||
|
||||
- URL 无效
|
||||
- 页面打不开
|
||||
- bridge 初始化失败
|
||||
|
||||
统一回退到:
|
||||
|
||||
- 原生内容卡
|
||||
- 原生结果页
|
||||
|
||||
---
|
||||
|
||||
## 7. 动画建议
|
||||
|
||||
### `sheet`
|
||||
|
||||
- 遮罩淡入
|
||||
- 面板自下而上出现
|
||||
|
||||
### `dialog`
|
||||
|
||||
- 遮罩淡入
|
||||
- 面板轻微放大进入
|
||||
|
||||
### `lite`
|
||||
|
||||
在低端机或 `lite` 模式下:
|
||||
|
||||
- 只保留 opacity
|
||||
- 降低位移动画强度
|
||||
|
||||
---
|
||||
|
||||
## 8. 推荐接入顺序
|
||||
|
||||
### 第一阶段
|
||||
|
||||
- 先把当前 `experience-webview` 升级成 shell
|
||||
- 先支持 `sheet`
|
||||
- 先接 `content-v1`
|
||||
|
||||
### 第二阶段
|
||||
|
||||
- 补 `dialog`
|
||||
- 结果页 H5 开始复用壳子
|
||||
|
||||
### 第三阶段
|
||||
|
||||
- 主题样式可配置
|
||||
- 过场动画接入
|
||||
|
||||
---
|
||||
|
||||
## 9. 一句话结论
|
||||
|
||||
小程序里的 H5 不应该直接作为“生硬全页”使用,也不应该强行做成“地图页上的真弹窗”。
|
||||
最稳的方案是:
|
||||
|
||||
**独立页面承载,但由原生壳子把它做成 `sheet / dialog / fullscreen` 三种体验形态。**
|
||||
|
||||
329
doc/archive/experience/内容体验层方案.md
Normal file
329
doc/archive/experience/内容体验层方案.md
Normal file
@@ -0,0 +1,329 @@
|
||||
# 游戏中文创体验层方案
|
||||
|
||||
## 1. 目标
|
||||
|
||||
为游戏过程中的文创内容建立一层独立承载能力,不把内容弹窗、图文卡片、讲解信息散落在:
|
||||
|
||||
- 规则层
|
||||
- 页面层
|
||||
- HUD 逻辑
|
||||
- 反馈层
|
||||
|
||||
这层的目标是:
|
||||
|
||||
- 在正确时机触发内容体验
|
||||
- 统一内容展示方式
|
||||
- 可配置、可复用、可扩展
|
||||
- 不破坏当前地图与规则主链
|
||||
|
||||
一句话:
|
||||
|
||||
**把“中途内容体验”从临时弹窗提升为正式能力层。**
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前现状
|
||||
|
||||
当前项目已经具备一部分基础:
|
||||
|
||||
- `control.displayContent`
|
||||
- `UiEffectDirector.showContentCard(...)`
|
||||
- 页面层已有 `contentCardVisible / contentCardTitle / contentCardBody`
|
||||
- 打点完成后可展示内容卡
|
||||
|
||||
这说明:
|
||||
|
||||
- 内容展示能力已经有雏形
|
||||
- 但触发方式还偏单一
|
||||
- 内容形式也还比较轻
|
||||
- 还没有形成正式的“内容体验层”模型
|
||||
|
||||
---
|
||||
|
||||
## 3. 设计原则
|
||||
|
||||
### 3.1 内容体验不等于短反馈
|
||||
|
||||
短反馈仍然属于:
|
||||
|
||||
- 音效
|
||||
- 震动
|
||||
- HUD 提示
|
||||
- 地图 pulse
|
||||
|
||||
文创体验属于更重的一层,应与 `FeedbackDirector` 区分。
|
||||
|
||||
### 3.2 内容体验不直接写死在规则里
|
||||
|
||||
规则层只负责:
|
||||
|
||||
- 是否触发
|
||||
- 触发什么体验条目
|
||||
|
||||
规则层不负责:
|
||||
|
||||
- 页面怎么弹
|
||||
- 卡片长什么样
|
||||
- 是否带图片、音频、讲解按钮
|
||||
|
||||
### 3.3 内容体验必须配置驱动
|
||||
|
||||
以后不同活动、不同地图、不同玩法需要不同内容。
|
||||
|
||||
所以这层必须可配置:
|
||||
|
||||
- 哪个点触发
|
||||
- 何时触发
|
||||
- 弹什么
|
||||
- 是否只弹一次
|
||||
- 优先级如何
|
||||
|
||||
---
|
||||
|
||||
## 4. 建议的新层级
|
||||
|
||||
建议增加一层:
|
||||
|
||||
- `ContentExperienceLayer`
|
||||
|
||||
放在概念上与这些层并列:
|
||||
|
||||
- `MapPresentation`
|
||||
- `HUD`
|
||||
- `Feedback`
|
||||
- `ResultScene`
|
||||
|
||||
职责:
|
||||
|
||||
- 接收体验触发
|
||||
- 管理当前激活内容项
|
||||
- 控制展示与关闭
|
||||
- 向页面层输出当前体验模型
|
||||
|
||||
---
|
||||
|
||||
## 5. 建议的数据模型
|
||||
|
||||
### 5.1 ExperienceEntry
|
||||
|
||||
```ts
|
||||
type ExperienceTrigger =
|
||||
| 'control_completed'
|
||||
| 'zone_entered'
|
||||
| 'session_finished'
|
||||
| 'manual'
|
||||
|
||||
type ExperienceDisplayMode =
|
||||
| 'content-card'
|
||||
| 'full-panel'
|
||||
| 'audio-guide'
|
||||
| 'unlock-card'
|
||||
|
||||
interface ExperienceEntry {
|
||||
id: string
|
||||
trigger: ExperienceTrigger
|
||||
controlId?: string
|
||||
zoneId?: string
|
||||
title: string
|
||||
body: string
|
||||
imageRef?: string
|
||||
audioRef?: string
|
||||
displayMode: ExperienceDisplayMode
|
||||
once: boolean
|
||||
priority: number
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 ExperienceRuntimeState
|
||||
|
||||
```ts
|
||||
interface ExperienceRuntimeState {
|
||||
activeEntryId: string | null
|
||||
dismissedEntryIds: string[]
|
||||
consumedEntryIds: string[]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 配置建议
|
||||
|
||||
建议在配置中增加一段:
|
||||
|
||||
```json
|
||||
{
|
||||
"resources": {
|
||||
"contentEntries": {
|
||||
"cp-3-story": {
|
||||
"title": "校史地标",
|
||||
"body": "这里是校园历史演变的重要节点。",
|
||||
"imageRef": "content/campus-history-01.png",
|
||||
"displayMode": "content-card"
|
||||
}
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"experience": {
|
||||
"entries": [
|
||||
{
|
||||
"id": "cp-3-story",
|
||||
"trigger": "control_completed",
|
||||
"controlId": "control-3",
|
||||
"once": true,
|
||||
"priority": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这意味着:
|
||||
|
||||
- 资源层管理内容资源
|
||||
- 玩法配置决定何时触发
|
||||
|
||||
---
|
||||
|
||||
## 7. 触发来源
|
||||
|
||||
第一阶段建议支持 3 种触发:
|
||||
|
||||
### 7.1 打点完成触发
|
||||
|
||||
最适合当前项目,价值最高。
|
||||
|
||||
例如:
|
||||
|
||||
- 完成某个控制点后弹一张文创卡
|
||||
- 开始点完成后弹赛事导览卡
|
||||
- 终点完成后弹纪念卡
|
||||
|
||||
### 7.2 区域进入触发
|
||||
|
||||
适合后续:
|
||||
|
||||
- 地标介绍
|
||||
- 迷雾探索
|
||||
- 特定区域故事点
|
||||
|
||||
### 7.3 结算后解锁触发
|
||||
|
||||
适合后续与结算页联动:
|
||||
|
||||
- 收藏卡
|
||||
- 奖章
|
||||
- 文创奖励
|
||||
|
||||
---
|
||||
|
||||
## 8. 页面表现建议
|
||||
|
||||
第一阶段先做最小闭环,不追求复杂视觉。
|
||||
|
||||
### 8.1 第一阶段
|
||||
|
||||
支持:
|
||||
|
||||
- 当前已有的 `content-card`
|
||||
- 标题
|
||||
- 正文
|
||||
- 关闭
|
||||
|
||||
### 8.2 第二阶段
|
||||
|
||||
再支持:
|
||||
|
||||
- 图片
|
||||
- 按钮
|
||||
- 章节式展开
|
||||
- 音频讲解
|
||||
|
||||
---
|
||||
|
||||
## 9. 与当前架构的关系
|
||||
|
||||
### 规则层
|
||||
|
||||
负责:
|
||||
|
||||
- 触发某条体验事件
|
||||
|
||||
不负责:
|
||||
|
||||
- 具体展示细节
|
||||
|
||||
### Feedback
|
||||
|
||||
继续负责:
|
||||
|
||||
- 短反馈
|
||||
- 动效
|
||||
- 音效
|
||||
|
||||
### ContentExperienceLayer
|
||||
|
||||
负责:
|
||||
|
||||
- 中等时长的信息体验
|
||||
|
||||
### 页面层
|
||||
|
||||
负责:
|
||||
|
||||
- 渲染当前体验模型
|
||||
|
||||
---
|
||||
|
||||
## 10. 第一阶段最小实施范围
|
||||
|
||||
建议第一阶段只做:
|
||||
|
||||
1. `control_completed -> experience entry`
|
||||
2. `content-card` 展示
|
||||
3. `once` 语义
|
||||
4. 手动关闭
|
||||
5. 配置驱动
|
||||
|
||||
不要一上来做:
|
||||
|
||||
- 图片轮播
|
||||
- 视频
|
||||
- 复杂音频控制
|
||||
- 多层交互
|
||||
|
||||
---
|
||||
|
||||
## 11. 推荐实施顺序
|
||||
|
||||
1. 定义 `ExperienceEntry`
|
||||
2. 在配置解析层接 `game.experience.entries`
|
||||
3. 在规则完成事件里派发体验触发
|
||||
4. MapEngine 增加体验状态承载
|
||||
5. 页面层继续复用当前 `content-card`
|
||||
6. 再逐步升级 UI
|
||||
|
||||
---
|
||||
|
||||
## 12. 长期价值
|
||||
|
||||
这层建好后,后续可以自然承接:
|
||||
|
||||
- 文创卡片
|
||||
- 地标解说
|
||||
- 解锁收藏
|
||||
- 故事节点
|
||||
- 活动内品牌内容
|
||||
|
||||
它不只服务当前顺序赛/积分赛,而是服务整条产品体验链。
|
||||
|
||||
---
|
||||
|
||||
## 13. 结论
|
||||
|
||||
当前最正确的方向不是继续在页面里零散补内容弹窗,而是:
|
||||
|
||||
**把游戏中途的文创与故事体验正式抽成一层独立的 `ContentExperienceLayer`。**
|
||||
|
||||
第一阶段先用“控制点完成触发内容卡”跑通最小闭环,后面再逐步扩成完整体验系统。
|
||||
|
||||
294
doc/archive/experience/结果页方案.md
Normal file
294
doc/archive/experience/结果页方案.md
Normal file
@@ -0,0 +1,294 @@
|
||||
# 游戏结算层方案
|
||||
|
||||
## 1. 目标
|
||||
|
||||
为游戏结束后的结果展示建立独立结算层,不把结算逻辑散落在:
|
||||
|
||||
- 规则层
|
||||
- HUD
|
||||
- 顶部提示
|
||||
- 页面临时弹窗
|
||||
|
||||
目标是:
|
||||
|
||||
- 统一承接结束态
|
||||
- 展示成绩与摘要信息
|
||||
- 支撑不同玩法的结算差异
|
||||
- 为后续文创奖励、奖章、分享做扩展位
|
||||
|
||||
一句话:
|
||||
|
||||
**把“比赛结束后显示点什么”提升为正式的结果场景能力。**
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前现状
|
||||
|
||||
当前项目已经有:
|
||||
|
||||
- `session_finished`
|
||||
- `gameSessionStatus = finished`
|
||||
- 基础成绩、里程、时长、心率等 telemetry
|
||||
- 游戏信息面板可读取当前状态快照
|
||||
|
||||
但还没有正式的:
|
||||
|
||||
- `ResultScene`
|
||||
- `SummaryModel`
|
||||
- 结束后专属页面承载
|
||||
|
||||
---
|
||||
|
||||
## 3. 设计原则
|
||||
|
||||
### 3.1 结算不应只是提示条
|
||||
|
||||
结束不是一个瞬时反馈,而是一次阶段切换。
|
||||
|
||||
所以它需要独立层,而不是只弹一句:
|
||||
|
||||
- 已完成
|
||||
- 已结束
|
||||
|
||||
### 3.2 结算要与玩法解耦
|
||||
|
||||
顺序赛、积分赛、后续幽灵赛、金币赛,结算内容不同。
|
||||
|
||||
所以应该有:
|
||||
|
||||
- 通用结算结构
|
||||
- 玩法补充区块
|
||||
|
||||
### 3.3 结算要可扩
|
||||
|
||||
后续可能加入:
|
||||
|
||||
- 奖章
|
||||
- 排名
|
||||
- 收藏卡
|
||||
- 文创解锁
|
||||
- 分享图
|
||||
|
||||
所以一开始就要留结构。
|
||||
|
||||
---
|
||||
|
||||
## 4. 建议的新层级
|
||||
|
||||
建议增加:
|
||||
|
||||
- `ResultScene`
|
||||
|
||||
概念上与这些层并列:
|
||||
|
||||
- `MapPresentation`
|
||||
- `HUD`
|
||||
- `Feedback`
|
||||
- `ContentExperienceLayer`
|
||||
|
||||
职责:
|
||||
|
||||
- 承接结束态
|
||||
- 持有结算模型
|
||||
- 控制显示与关闭
|
||||
- 为玩法结果提供统一展示结构
|
||||
|
||||
---
|
||||
|
||||
## 5. 建议的数据模型
|
||||
|
||||
### 5.1 SummaryModel
|
||||
|
||||
```ts
|
||||
interface ResultSummaryModel {
|
||||
title: string
|
||||
subtitle: string
|
||||
mode: string
|
||||
finished: boolean
|
||||
durationMs: number
|
||||
distanceMeters: number
|
||||
averageSpeedKmh: number | null
|
||||
calories: number | null
|
||||
averageHeartRateBpm: number | null
|
||||
completedCount: number
|
||||
skippedCount: number
|
||||
totalCount: number
|
||||
score: number | null
|
||||
extraRows: Array<{ label: string; value: string }>
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 ResultSceneState
|
||||
|
||||
```ts
|
||||
interface ResultSceneState {
|
||||
visible: boolean
|
||||
summary: ResultSummaryModel | null
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 第一阶段应展示什么
|
||||
|
||||
建议先做一版“基础结算页”,不要一上来做复杂演出。
|
||||
|
||||
### 通用区域
|
||||
|
||||
- 赛事名称
|
||||
- 玩法名称
|
||||
- 完成状态
|
||||
- 总用时
|
||||
- 总里程
|
||||
- 平均速度
|
||||
- 卡路里
|
||||
- 平均心率
|
||||
|
||||
### 玩法区域
|
||||
|
||||
顺序赛:
|
||||
|
||||
- 完成控制点数量
|
||||
- 跳过点数量
|
||||
- 总控制点数量
|
||||
|
||||
积分赛:
|
||||
|
||||
- 总得分
|
||||
- 已完成点数
|
||||
- 未完成点数
|
||||
|
||||
### 操作区
|
||||
|
||||
- 返回地图
|
||||
- 关闭
|
||||
- 后续再加重开 / 分享
|
||||
|
||||
---
|
||||
|
||||
## 7. 配置建议
|
||||
|
||||
建议在配置中预留:
|
||||
|
||||
```json
|
||||
{
|
||||
"game": {
|
||||
"result": {
|
||||
"enabled": true,
|
||||
"showTelemetry": true,
|
||||
"showCollectedContent": true,
|
||||
"showAwards": false,
|
||||
"template": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这意味着:
|
||||
|
||||
- 结算是否启用
|
||||
- 展示哪些区块
|
||||
- 用哪个模板
|
||||
|
||||
都可配置。
|
||||
|
||||
---
|
||||
|
||||
## 8. 与当前架构的关系
|
||||
|
||||
### 规则层
|
||||
|
||||
负责:
|
||||
|
||||
- 产出 `session_finished`
|
||||
|
||||
### Telemetry
|
||||
|
||||
负责:
|
||||
|
||||
- 提供里程、速度、心率、卡路里等数据
|
||||
|
||||
### MapEngine
|
||||
|
||||
负责:
|
||||
|
||||
- 在结束时汇总通用结算模型
|
||||
- 把结果快照送到页面层
|
||||
|
||||
### 页面层
|
||||
|
||||
负责:
|
||||
|
||||
- 渲染结算页
|
||||
|
||||
---
|
||||
|
||||
## 9. 第一阶段最小实施范围
|
||||
|
||||
建议第一阶段只做:
|
||||
|
||||
1. `session_finished -> ResultScene`
|
||||
2. 基础 summary 展示
|
||||
3. 顺序赛 / 积分赛的简单差异化字段
|
||||
4. 手动关闭 / 返回地图
|
||||
|
||||
先不要一上来做:
|
||||
|
||||
- 复杂章节动画
|
||||
- 排名
|
||||
- 分享图生成
|
||||
- 复杂奖章系统
|
||||
|
||||
---
|
||||
|
||||
## 10. 后续扩展方向
|
||||
|
||||
这层建好后,可以逐步加:
|
||||
|
||||
- 文创奖励
|
||||
- 奖章 / 成就
|
||||
- 排名
|
||||
- 解锁内容
|
||||
- 分享卡
|
||||
- 二次引导
|
||||
|
||||
---
|
||||
|
||||
## 11. 推荐实施顺序
|
||||
|
||||
1. 定义 `ResultSummaryModel`
|
||||
2. 在 `MapEngine` 汇总结束快照
|
||||
3. 页面层增加结果面板
|
||||
4. 顺序赛 / 积分赛各补一组玩法字段
|
||||
5. 再考虑动画、奖励和品牌内容
|
||||
|
||||
---
|
||||
|
||||
## 12. 与文创体验层的配合
|
||||
|
||||
后续建议:
|
||||
|
||||
- 文创体验层
|
||||
- 承接“游戏中途”的体验
|
||||
- 结算层
|
||||
- 承接“游戏结束后”的体验
|
||||
|
||||
二者不要混。
|
||||
|
||||
如果后续结算后要解锁文创卡片,可以由:
|
||||
|
||||
- `ResultScene`
|
||||
- 显示结算
|
||||
- 结算完成后
|
||||
- 再触发内容奖励卡
|
||||
|
||||
---
|
||||
|
||||
## 13. 结论
|
||||
|
||||
当前最合适的方向不是继续在结束时零散堆文案,而是:
|
||||
|
||||
**正式增加一层 `ResultScene`,承接顺序赛、积分赛以及未来更多玩法的统一结算体验。**
|
||||
|
||||
第一阶段先做基础 summary,后续再逐步接入文创奖励、奖章、排名和过场动画。
|
||||
|
||||
Reference in New Issue
Block a user