Files
cmr-mini/doc/gameplay/准备页地图预览方案.md

389 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 准备页地图预览方案
> 文档版本v1.0
> 最后更新2026-04-07 12:18:00
本文档用于说明活动准备页的地图预览能力如何设计与落地。
当前目标不是直接进入实现,而是先把方案边界、分层、前后端职责和分阶段路径定清。
---
## 1. 目标
准备页当前已经具备:
- 活动状态摘要
- 赛道选择
- 设备准备
- 进入地图
但“本局对象预览”仍然主要是文字占位,对玩家帮助有限。
准备页地图预览的目标是:
1. 在进入地图前,让玩家建立空间预期
2. 在多赛道活动中,让玩家能直观看到当前赛道差异
3. 让准备页更像“出发前准备”,而不是工程参数页
4. 不打断当前 runtime 主链,也不额外制造一套重资源地图体系
---
## 2. 推荐方案
当前推荐采用:
**低级别正式瓦片做底图,前端动态叠加赛道**
也就是:
- 底图来源:现有正式瓦片资源
- 底图级别:选择一个较低 zoom 作为预览缩略底图
- 叠加层:前端根据当前赛道数据在预览图上动态绘制起点、终点、控制点和腿线
这是一个“混合预览方案”:
- 不单独制作新的预览地图资源
- 不在前端完整拼装高精度交互地图
- 只在准备页做只读预览
---
## 3. 为什么选这个方案
### 3.1 不新增独立地图资源
如果单独为准备页制作预览地图资源,会带来:
- 资源重复
- 发布链复杂度上升
- 底图与正式地图不一致风险
使用低级别正式瓦片作为预览底图,可以保持:
- 同源
- 一致
- 低成本
### 3.2 多赛道切换更自然
多赛道场景下:
- 底图通常是同一张地图
- 差异主要在赛道叠加层
因此最合理的方式是:
- 底图固定
- 切换赛道时仅重绘 overlay
这样:
- 切换更快
- 数据结构更清楚
- 不需要为每个 variant 重新生成整张预览图
### 3.3 前后端职责清楚
后端负责:
- 提供底图预览所需元数据
- 提供赛道叠加所需坐标数据
前端负责:
- 展示底图
- 动态叠加赛道
- 在准备页进行只读预览
这符合当前项目一直坚持的分层原则。
---
## 4. 整体分层
准备页地图预览建议分成 4 层。
### 4.1 地图底图层
来源:
- 当前正式瓦片资源
形式:
- 低级别缩略底图
职责:
- 提供地点区域的空间背景
### 4.2 预览元数据层
来源:
- 后端预览元数据
职责:
- 告诉前端如何把经纬度投到预览图坐标系中
### 4.3 赛道叠加层
来源:
- variant 控制点与腿线数据
职责:
- 在准备页上画出当前赛道
### 4.4 准备页展示层
职责:
- 只读展示
- 切换赛道联动预览
- 不承担局内交互
---
## 5. 后端需要提供的最小字段
V1 不要求后端提供完整预览图 URL而是先提供“底图元数据 + 赛道 overlay 元数据”。
建议后端提供以下最小结构:
```json
{
"preview": {
"mode": "full",
"baseTiles": {
"tileBaseUrl": "https://.../tiles/",
"zoom": 15,
"tileSize": 256
},
"viewport": {
"width": 800,
"height": 450,
"minLon": 117.0000,
"minLat": 36.6000,
"maxLon": 117.0800,
"maxLat": 36.6600
},
"variants": [
{
"variantId": "variant_a",
"name": "A线",
"routeCode": "route-variant-a",
"controls": [
{ "id": "start", "kind": "start", "lon": 117.01, "lat": 36.61 },
{ "id": "c1", "kind": "control", "lon": 117.02, "lat": 36.615 },
{ "id": "finish", "kind": "finish", "lon": 117.03, "lat": 36.62 }
],
"legs": [
{ "from": "start", "to": "c1" },
{ "from": "c1", "to": "finish" }
]
}
]
}
}
```
其中关键字段是:
- `baseTiles.tileBaseUrl`
- `baseTiles.zoom`
- `viewport.width / height`
- `viewport.minLon / minLat / maxLon / maxLat`
- `variants[].controls`
- `variants[].legs`
这些字段足够前端做只读预览。
---
## 6. 前端如何消费
前端准备页的消费方式建议如下:
### 6.1 底图渲染
- 使用低级别瓦片作为底图来源
-`viewport``zoom` 计算需要的瓦片范围
- 只在准备页内绘制一张静态缩略底图
### 6.2 赛道叠加
- 根据 `viewport` 把控制点经纬度投影到预览图坐标
- 在 canvas 或同等绘制层上叠加:
- 起点
- 终点
- 控制点
- 腿线
### 6.3 多赛道切换
- 切换赛道时不重新换底图
- 只重绘叠加层
### 6.4 展示层级
准备页只做:
- 只读预览
- 不拖拽
- 不缩放
- 不交互打点
---
## 7. 多赛道场景如何处理
多赛道场景是这套方案的重点。
当前建议规则:
1. 同一活动下,所有 variant 共用一张底图
2. 当前选中的 variant 决定叠加层内容
3. 如果活动允许手动选赛道,切换赛道时预览同步切换
4. 如果活动是随机分配或后台指定:
- 准备页在最终绑定前可只显示地点底图
- 一旦后端返回最终绑定赛道,再显示该赛道 overlay
这套设计和当前多赛道 Variant 架构是一致的:
- 底图属于地图对象
- 叠加属于 variant 对象
---
## 8. 预览级别建议
建议预览能力分成 3 档:
### 8.1 `none`
- 不显示地图预览
- 只显示地点、地图、赛道文字信息
适用于:
- 不允许赛前预览的正式比赛
### 8.2 `summary`
- 显示底图
- 只显示简化赛道范围、起终点或大致区域
- 不暴露完整点位和腿线
适用于:
- 需要局前空间感,但不允许完整剧透路线
### 8.3 `full`
- 显示底图
- 显示完整点位与腿线
适用于:
- 体验活动
- 教学活动
- 低门槛公开活动
V1 建议先直接支持:
- `none`
- `full`
后面再补 `summary`
---
## 9. 分阶段实施建议
### 9.1 V1
只做:
- 低级别瓦片底图
- 前端动态赛道叠加
- 支持多赛道切换联动
- 只读展示
不做:
- 复杂预览交互
- 预览模式细分
- 缩放与拖拽
### 9.2 V2
补:
- `none / summary / full`
- 不同活动类型的预览策略
- 更细的赛道保密规则
### 9.3 V3
考虑扩展到:
- 活动详情页缩略预览
- 活动列表卡片缩略图
- 赛后结果页路线回看缩略图
---
## 10. 不建议的方案
当前不建议:
### 10.1 单独制作一套预览地图资源
问题:
- 成本高
- 一致性差
- 发布链复杂
### 10.2 前端直接现场拼完整高精度瓦片地图
问题:
- 性能波动大
- 首次加载慢
- 多端一致性差
### 10.3 后端为每个 variant 预生成完整大图
问题:
- 多赛道下资源重复
- 每次改赛道都要重生图
- 扩展性不如“底图固定 + 叠加切换”
---
## 11. 当前建议结论
准备页地图预览最推荐的路线是:
**使用低级别正式瓦片作为预览底图,由前端在准备页动态叠加当前赛道。**
这条路线的优点是:
- 不新增独立地图资源
- 底图与正式地图同源
- 多赛道切换成本低
- 前后端职责清晰
- 易于分阶段落地
当前建议优先推进:
1. 后端补预览元数据最小字段
2. 前端在准备页实现只读底图 + overlay
3. 先支持 `full`
4. 后续再扩 `summary / none`