完善样式系统与调试链路底座
This commit is contained in:
@@ -46,6 +46,30 @@
|
||||
- 想知道字段应该怎么写
|
||||
- 想确认默认行为时
|
||||
|
||||
### [track-visualization-proposal.md](D:/dev/cmr-mini/doc/track-visualization-proposal.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 说明 `none / full / tail` 三种轨迹模式
|
||||
- 说明拖尾轨迹的默认策略与推荐参数
|
||||
- 说明当前轨迹样式的配置结构
|
||||
|
||||
### [gps-marker-style-system-proposal.md](D:/dev/cmr-mini/doc/gps-marker-style-system-proposal.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 说明 GPS 点样式系统的目标分层
|
||||
- 说明默认样式、朝向小三角和品牌 logo 扩展思路
|
||||
- 说明第一阶段最小实现字段和长期演进方向
|
||||
|
||||
### [gps-marker-animation-system-proposal.md](D:/dev/cmr-mini/doc/gps-marker-animation-system-proposal.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 说明 GPS 点动画系统的状态分层
|
||||
- 说明 `idle / moving / fast-moving / warning` 的第一阶段实现思路
|
||||
- 说明动画 profile、运行时内部字段和 `standard / lite` 降级策略
|
||||
|
||||
---
|
||||
|
||||
## 3. 默认配置模板
|
||||
@@ -64,6 +88,36 @@
|
||||
- 想直接照着填配置
|
||||
- 想知道最小可运行模板长什么样
|
||||
|
||||
### [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 提供“最小可跑”的游戏配置模板
|
||||
- 去掉绝大部分选配项
|
||||
- 适合快速起步、联调和排查配置链
|
||||
|
||||
### [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 提供顺序赛最小可跑模板
|
||||
- 适合快速起顺序赛活动
|
||||
|
||||
### [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 提供积分赛最小可跑模板
|
||||
- 适合快速起积分赛活动
|
||||
|
||||
### [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
|
||||
作用:
|
||||
|
||||
- 提供“当前开发状态最全”的配置模板
|
||||
- 汇总目前客户端已实现或已消费的主要字段
|
||||
- 适合后端、后台和联调统一对齐
|
||||
|
||||
---
|
||||
|
||||
## 4. 按玩法拆分的配置模板文档
|
||||
@@ -137,10 +191,13 @@
|
||||
|
||||
1. [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
|
||||
2. [config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
|
||||
3. [config-default-template.md](D:/dev/cmr-mini/doc/config-default-template.md)
|
||||
4. [event/classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
|
||||
5. [event/score-o.json](D:/dev/cmr-mini/event/score-o.json)
|
||||
6. [backend-config-management-v2.md](D:/dev/cmr-mini/doc/backend-config-management-v2.md)
|
||||
3. [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
|
||||
4. [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
|
||||
5. [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
|
||||
6. [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
7. [event/classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
|
||||
8. [event/score-o.json](D:/dev/cmr-mini/event/score-o.json)
|
||||
9. [backend-config-management-v2.md](D:/dev/cmr-mini/doc/backend-config-management-v2.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -149,9 +206,12 @@
|
||||
后续每次新增配置能力时,建议至少同步更新这几处:
|
||||
|
||||
1. [config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
|
||||
2. [config-default-template.md](D:/dev/cmr-mini/doc/config-default-template.md)
|
||||
3. 对应玩法的 `event/*.json` 样例
|
||||
4. 如果涉及顶层结构变化,再更新 [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
|
||||
2. [config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
|
||||
3. [config-template-minimal-classic-sequential.md](D:/dev/cmr-mini/doc/config-template-minimal-classic-sequential.md)
|
||||
4. [config-template-minimal-score-o.md](D:/dev/cmr-mini/doc/config-template-minimal-score-o.md)
|
||||
5. [config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
6. 对应玩法的 `event/*.json` 样例
|
||||
7. 如果涉及顶层结构变化,再更新 [config-design-proposal.md](D:/dev/cmr-mini/doc/config-design-proposal.md)
|
||||
|
||||
这样可以保证:
|
||||
|
||||
|
||||
@@ -313,6 +313,61 @@
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:点击内容的展示形态
|
||||
|
||||
#### `pointStyle`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:单个控制点的样式覆盖,仅影响当前控制点
|
||||
- 支持值:
|
||||
- `classic-ring`
|
||||
- `solid-dot`
|
||||
- `double-ring`
|
||||
- `badge`
|
||||
- `pulse-core`
|
||||
|
||||
#### `pointColorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:单个控制点的颜色覆盖,例如 `#27ae60`
|
||||
- 备注:通常和 `pointStyle` 一起使用,未配置时回退到玩法样式 profile
|
||||
|
||||
#### `pointSizeScale`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:单个控制点的尺寸倍率覆盖
|
||||
- 建议范围:`0.6 ~ 1.4`
|
||||
- 建议默认值:`1`
|
||||
- 备注:大于 `1` 会放大点位,小于 `1` 会缩小点位
|
||||
|
||||
#### `pointAccentRingScale`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:单个控制点强调环/外环的尺寸倍率
|
||||
- 建议范围:`1.0 ~ 1.6`
|
||||
- 建议默认值:由样式 profile 决定
|
||||
- 备注:适合当前点、高分点、终点这类需要更强层次感的点位
|
||||
|
||||
#### `pointGlowStrength`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:单个控制点的光晕强度
|
||||
- 建议范围:`0 ~ 1`
|
||||
- 建议默认值:`0`
|
||||
- 备注:`0` 为无光晕,越接近 `1` 光晕越明显
|
||||
|
||||
#### `pointLabelScale`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:单个控制点编号文字的尺寸倍率
|
||||
- 建议范围:`0.7 ~ 1.3`
|
||||
- 建议默认值:`1`
|
||||
- 备注:适合高价值点、终点、特殊活动点的编号强调
|
||||
|
||||
#### `pointLabelColorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:单个控制点编号文字颜色覆盖,例如 `#ffffff`
|
||||
- 备注:未配置时回退到样式系统默认标签颜色逻辑
|
||||
- 当前支持:
|
||||
- `sheet`
|
||||
- `dialog`
|
||||
@@ -626,7 +681,369 @@
|
||||
|
||||
---
|
||||
|
||||
## 19. 当前默认逻辑说明
|
||||
## 19. `game.presentation`
|
||||
|
||||
### `game.presentation.sequential.controls.default`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛普通未完成控制点的默认样式
|
||||
- 支持字段:
|
||||
- `style`:`classic-ring | solid-dot | double-ring | badge | pulse-core`
|
||||
- `colorHex`:十六进制颜色,例如 `#cc006b`
|
||||
- `sizeScale`:点位尺寸倍率
|
||||
- `accentRingScale`:强调环尺寸倍率
|
||||
- `glowStrength`:点位光晕强度
|
||||
- `labelScale`:编号文字尺寸倍率
|
||||
- `labelColorHex`:编号文字颜色
|
||||
|
||||
### `game.presentation.sequential.controls.current`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛当前目标点/可打点状态样式
|
||||
|
||||
### `game.presentation.sequential.controls.completed`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛已完成点样式
|
||||
|
||||
### `game.presentation.sequential.controls.skipped`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛已跳过点样式
|
||||
|
||||
### `game.presentation.sequential.controls.start`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛起点样式
|
||||
|
||||
### `game.presentation.sequential.controls.finish`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛终点样式
|
||||
|
||||
### `game.presentation.sequential.legs.default`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛默认路线腿样式
|
||||
- 支持字段:
|
||||
- `style`:`classic-leg | dashed-leg | glow-leg | progress-leg`
|
||||
- `colorHex`:十六进制颜色
|
||||
- `widthScale`:路线腿宽度倍率
|
||||
- `glowStrength`:路线腿光晕强度
|
||||
|
||||
### `game.presentation.sequential.legs.completed`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:顺序赛已完成路线腿样式
|
||||
|
||||
### `playfield.legOverrides`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:对指定路线腿做局部样式覆盖
|
||||
- 键名建议:
|
||||
- `leg-1`
|
||||
- `leg-2`
|
||||
- `leg-3`
|
||||
|
||||
- 字段:
|
||||
- `style`:`classic-leg | dashed-leg | glow-leg | progress-leg`
|
||||
- `colorHex`:十六进制颜色
|
||||
- `widthScale`:路线腿宽度倍率
|
||||
- `glowStrength`:路线腿光晕强度
|
||||
|
||||
- 示例:
|
||||
|
||||
```json
|
||||
"legOverrides": {
|
||||
"leg-2": {
|
||||
"style": "glow-leg",
|
||||
"colorHex": "#27ae60"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `game.presentation.scoreO.controls.default`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:积分赛默认点位样式
|
||||
|
||||
### `game.presentation.scoreO.controls.focused`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:积分赛当前聚焦/选中点样式
|
||||
|
||||
### `game.presentation.scoreO.controls.collected`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:积分赛已收集点样式
|
||||
|
||||
### `game.presentation.scoreO.controls.start`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:积分赛起点样式
|
||||
|
||||
### `game.presentation.scoreO.controls.finish`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:积分赛终点样式
|
||||
|
||||
### `game.presentation.scoreO.controls.scoreBands`
|
||||
|
||||
- 类型:`array`
|
||||
- 说明:积分赛按分值档位映射点位颜色和样式
|
||||
- 数组项字段:
|
||||
- `min`:分值下界,含
|
||||
- `max`:分值上界,含
|
||||
- `style`:`classic-ring | solid-dot | double-ring | badge | pulse-core`
|
||||
- `colorHex`:十六进制颜色
|
||||
- `sizeScale`:该积分档位的点位尺寸倍率
|
||||
- `accentRingScale`:该积分档位的强调环倍率
|
||||
- `glowStrength`:该积分档位的光晕强度
|
||||
- `labelScale`:该积分档位的编号文字尺寸倍率
|
||||
- `labelColorHex`:该积分档位的编号文字颜色
|
||||
|
||||
- 示例:
|
||||
|
||||
```json
|
||||
"presentation": {
|
||||
"scoreO": {
|
||||
"controls": {
|
||||
"scoreBands": [
|
||||
{ "min": 0, "max": 19, "style": "classic-ring", "colorHex": "#56ccf2" },
|
||||
{ "min": 20, "max": 49, "style": "double-ring", "colorHex": "#f2c94c" },
|
||||
{ "min": 50, "max": 999999, "style": "badge", "colorHex": "#eb5757" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 20. `game.presentation.track`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:用户轨迹显示策略与样式配置
|
||||
|
||||
### `game.presentation.track.mode`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:轨迹显示模式
|
||||
- 当前支持:
|
||||
- `none`:不显示轨迹
|
||||
- `tail`:彗尾拖尾
|
||||
- `full`:全轨迹
|
||||
- 建议默认值:
|
||||
- 顺序赛:`full`
|
||||
- 积分赛:`tail`
|
||||
|
||||
### `game.presentation.track.style`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:轨迹风格 profile
|
||||
- 当前支持:
|
||||
- `classic`
|
||||
- `neon`
|
||||
- 当前默认值:`neon`
|
||||
|
||||
### `game.presentation.track.tailLength`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:拖尾基础长度档位
|
||||
- 当前支持:
|
||||
- `short`
|
||||
- `medium`
|
||||
- `long`
|
||||
- 备注:
|
||||
- 实际显示长度会继续按移动速度动态变化
|
||||
- 跑得越快,尾巴越长
|
||||
- 跑得越慢,尾巴越短
|
||||
|
||||
### `game.presentation.track.colorPreset`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:轨迹亮色调色盘
|
||||
- 当前支持:
|
||||
- `mint`
|
||||
- `cyan`
|
||||
- `sky`
|
||||
- `blue`
|
||||
- `violet`
|
||||
- `pink`
|
||||
- `orange`
|
||||
- `yellow`
|
||||
- 备注:
|
||||
- 运行时会在此基础上根据速度和心率张力自动提亮头部颜色与光晕
|
||||
|
||||
### `game.presentation.track.tailMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:拖尾基础长度(米)
|
||||
- 备注:
|
||||
- 若未显式配置,则按 `tailLength` 自动映射
|
||||
|
||||
### `game.presentation.track.tailMaxSeconds`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:拖尾最大时间窗口(秒)
|
||||
|
||||
### `game.presentation.track.fadeOutWhenStill`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:静止后是否逐步收尾消失
|
||||
|
||||
### `game.presentation.track.stillSpeedKmh`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:低于该速度时进入静止收尾逻辑
|
||||
|
||||
### `game.presentation.track.fadeOutDurationMs`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:静止后拖尾完全淡出的时长(毫秒)
|
||||
|
||||
### `game.presentation.track.colorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:轨迹主色
|
||||
- 备注:
|
||||
- 未配置时按 `colorPreset` 自动映射
|
||||
|
||||
### `game.presentation.track.headColorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:轨迹头部高亮颜色
|
||||
- 备注:
|
||||
- 未配置时按 `colorPreset` 自动映射
|
||||
|
||||
### `game.presentation.track.widthPx`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:轨迹基础宽度
|
||||
|
||||
### `game.presentation.track.headWidthPx`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:轨迹头部高亮宽度
|
||||
|
||||
### `game.presentation.track.glowStrength`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:轨迹光晕强度
|
||||
- 备注:
|
||||
- `standard / lite` 会自动做 glow 强度降级
|
||||
|
||||
---
|
||||
|
||||
## 21. `game.presentation.gpsMarker`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:GPS 定位点显示、尺寸、颜色、朝向指示和品牌化扩展配置
|
||||
|
||||
### `game.presentation.gpsMarker.visible`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否显示 GPS 定位点
|
||||
- 当前默认值:`true`
|
||||
|
||||
### `game.presentation.gpsMarker.style`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点基础样式
|
||||
- 当前支持:
|
||||
- `dot`
|
||||
- `beacon`
|
||||
- `disc`
|
||||
- `badge`
|
||||
- 当前默认值:`beacon`
|
||||
|
||||
### `game.presentation.gpsMarker.size`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点整体大小档位
|
||||
- 当前支持:
|
||||
- `small`
|
||||
- `medium`
|
||||
- `large`
|
||||
- 当前默认值:`medium`
|
||||
|
||||
### `game.presentation.gpsMarker.colorPreset`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点亮色调色盘
|
||||
- 当前支持:
|
||||
- `mint`
|
||||
- `cyan`
|
||||
- `sky`
|
||||
- `blue`
|
||||
- `violet`
|
||||
- `pink`
|
||||
- `orange`
|
||||
- `yellow`
|
||||
- 当前默认值:`cyan`
|
||||
|
||||
### `game.presentation.gpsMarker.colorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点主色
|
||||
- 备注:
|
||||
- 未配置时按 `colorPreset` 自动映射
|
||||
|
||||
### `game.presentation.gpsMarker.ringColorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点外圈颜色
|
||||
- 备注:
|
||||
- 未配置时按 `colorPreset` 自动映射
|
||||
|
||||
### `game.presentation.gpsMarker.indicatorColorHex`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:朝向小三角颜色
|
||||
- 备注:
|
||||
- 未配置时按 `colorPreset` 自动映射
|
||||
|
||||
### `game.presentation.gpsMarker.showHeadingIndicator`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否显示跟随朝向旋转的小三角
|
||||
- 当前默认值:`true`
|
||||
- 备注:
|
||||
- 运行时会结合朝向可信度自动降低透明度
|
||||
|
||||
### `game.presentation.gpsMarker.animationProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:GPS 点动画 profile
|
||||
- 当前支持:
|
||||
- `minimal`
|
||||
- `dynamic-runner`
|
||||
- `warning-reactive`
|
||||
- 当前默认值:`dynamic-runner`
|
||||
- 备注:
|
||||
- 第一阶段主要影响静止、移动、高速和高压状态下的动势强弱
|
||||
- 未配置时使用系统默认动画逻辑
|
||||
|
||||
### `game.presentation.gpsMarker.logoUrl`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:品牌 logo 资源地址
|
||||
- 当前状态:已支持中心贴片
|
||||
- 备注:
|
||||
- logo 作为中心贴片嵌入 GPS 点,不直接替代定位点
|
||||
- 建议使用透明背景正方形资源
|
||||
|
||||
### `game.presentation.gpsMarker.logoMode`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:logo 嵌入方式
|
||||
- 当前支持:
|
||||
- `center-badge`
|
||||
- 当前状态:已支持
|
||||
|
||||
---
|
||||
|
||||
## 22. 当前默认逻辑说明
|
||||
|
||||
当前客户端对配置的处理原则是:
|
||||
|
||||
@@ -642,7 +1059,7 @@
|
||||
|
||||
---
|
||||
|
||||
## 20. 维护约定
|
||||
## 23. 维护约定
|
||||
|
||||
后续每次新增配置项时,应同步更新:
|
||||
|
||||
|
||||
650
doc/config-template-full-current.md
Normal file
650
doc/config-template-full-current.md
Normal file
@@ -0,0 +1,650 @@
|
||||
# 游戏配置全量模板(当前开发实现版)
|
||||
|
||||
本文档提供一份 **截至当前开发状态,客户端已实现或已正式消费的较完整配置模板**。
|
||||
|
||||
目标:
|
||||
|
||||
- 给后端、后台、联调一份“当前最全可用模板”
|
||||
- 帮助梳理哪些字段已经生效
|
||||
- 后续新增字段时,以这份模板持续补充
|
||||
|
||||
说明:
|
||||
|
||||
- 本模板优先以**当前客户端代码真实实现**为准
|
||||
- 不是未来终态,只代表“当前这一版已经能消费的字段”
|
||||
- 以顺序赛为主模板,同时说明积分赛差异点
|
||||
|
||||
---
|
||||
|
||||
## 1. 当前最全模板
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"version": "2026.03.30",
|
||||
"app": {
|
||||
"id": "sample-full-001",
|
||||
"title": "完整配置示例",
|
||||
"locale": "zh-CN"
|
||||
},
|
||||
"map": {
|
||||
"tiles": "../map/lxcb-001/tiles/",
|
||||
"mapmeta": "../map/lxcb-001/tiles/meta.json",
|
||||
"declination": 6.91,
|
||||
"initialView": {
|
||||
"zoom": 17
|
||||
}
|
||||
},
|
||||
"playfield": {
|
||||
"kind": "course",
|
||||
"source": {
|
||||
"type": "kml",
|
||||
"url": "../kml/lxcb-001/10/c01.kml"
|
||||
},
|
||||
"CPRadius": 6,
|
||||
"metadata": {
|
||||
"title": "完整路线示例",
|
||||
"code": "full-001"
|
||||
},
|
||||
"controlOverrides": {
|
||||
"start-1": {
|
||||
"template": "focus",
|
||||
"title": "比赛开始",
|
||||
"body": "从这里触发,先熟悉地图方向。",
|
||||
"clickTitle": "起点说明",
|
||||
"clickBody": "点击起点可再次查看起跑说明。",
|
||||
"autoPopup": true,
|
||||
"once": true,
|
||||
"priority": 1,
|
||||
"contentExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/start-1",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "dialog"
|
||||
},
|
||||
"clickExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/start-1-click",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "dialog"
|
||||
}
|
||||
},
|
||||
"control-1": {
|
||||
"template": "story",
|
||||
"score": 10,
|
||||
"title": "第一检查点",
|
||||
"body": "完成该点后继续推进。",
|
||||
"clickTitle": "第一检查点",
|
||||
"clickBody": "点击查看该点的补充说明。",
|
||||
"autoPopup": true,
|
||||
"once": false,
|
||||
"priority": 1,
|
||||
"contentExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/control-1",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "dialog"
|
||||
},
|
||||
"clickExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/control-1-click",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "dialog"
|
||||
}
|
||||
},
|
||||
"control-2": {
|
||||
"template": "minimal",
|
||||
"title": "第二检查点",
|
||||
"body": "这个点配置成手动查看内容。",
|
||||
"clickTitle": "第二检查点",
|
||||
"clickBody": "点击查看手动内容。",
|
||||
"autoPopup": false,
|
||||
"once": true,
|
||||
"priority": 1
|
||||
},
|
||||
"finish-1": {
|
||||
"template": "focus",
|
||||
"title": "比赛结束",
|
||||
"body": "恭喜完成本次路线。",
|
||||
"clickTitle": "终点说明",
|
||||
"clickBody": "点击终点可再次查看结束说明。",
|
||||
"autoPopup": true,
|
||||
"once": true,
|
||||
"priority": 2,
|
||||
"clickExperience": {
|
||||
"type": "h5",
|
||||
"url": "https://example.com/content/finish-1-click",
|
||||
"bridge": "content-v1",
|
||||
"presentation": "dialog"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"mode": "classic-sequential",
|
||||
"rulesVersion": "1",
|
||||
"session": {
|
||||
"startManually": true,
|
||||
"requiresStartPunch": true,
|
||||
"requiresFinishPunch": true,
|
||||
"autoFinishOnLastControl": false,
|
||||
"maxDurationSec": 5400
|
||||
},
|
||||
"punch": {
|
||||
"policy": "enter-confirm",
|
||||
"radiusMeters": 5,
|
||||
"requiresFocusSelection": false
|
||||
},
|
||||
"sequence": {
|
||||
"skip": {
|
||||
"enabled": true,
|
||||
"radiusMeters": 30,
|
||||
"requiresConfirm": true
|
||||
}
|
||||
},
|
||||
"scoring": {
|
||||
"type": "score",
|
||||
"defaultControlScore": 10
|
||||
},
|
||||
"guidance": {
|
||||
"showLegs": true,
|
||||
"legAnimation": true,
|
||||
"allowFocusSelection": false
|
||||
},
|
||||
"visibility": {
|
||||
"revealFullPlayfieldAfterStartPunch": true
|
||||
},
|
||||
"finish": {
|
||||
"finishControlAlwaysSelectable": false
|
||||
},
|
||||
"telemetry": {
|
||||
"heartRate": {
|
||||
"age": 30,
|
||||
"restingHeartRateBpm": 62,
|
||||
"userWeightKg": 65
|
||||
}
|
||||
},
|
||||
"feedback": {
|
||||
"audioProfile": "default",
|
||||
"hapticsProfile": "default",
|
||||
"uiEffectsProfile": "default"
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"audioProfile": "default",
|
||||
"contentProfile": "default",
|
||||
"themeProfile": "default-race"
|
||||
},
|
||||
"debug": {
|
||||
"allowModeSwitch": false,
|
||||
"allowMockInput": false,
|
||||
"allowSimulator": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 顶层字段说明
|
||||
|
||||
### `schemaVersion`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置结构版本
|
||||
- 当前建议值:`"1"`
|
||||
|
||||
### `version`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置内容版本号
|
||||
|
||||
### `app`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:是
|
||||
- 说明:活动级基础信息
|
||||
|
||||
### `map`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:是
|
||||
- 说明:地图底座信息
|
||||
|
||||
### `playfield`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:是
|
||||
- 说明:点位空间、内容覆盖、点位元信息
|
||||
|
||||
### `game`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:是
|
||||
- 说明:玩法规则与对局流程
|
||||
|
||||
### `resources`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:否
|
||||
- 说明:资源 profile 引用
|
||||
|
||||
### `debug`
|
||||
|
||||
- 类型:`object`
|
||||
- 必填:否
|
||||
- 说明:调试开关
|
||||
|
||||
---
|
||||
|
||||
## 3. `app` 字段说明
|
||||
|
||||
### `app.id`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:活动配置 ID
|
||||
|
||||
### `app.title`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:活动标题 / 比赛名称
|
||||
|
||||
### `app.locale`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:语言环境
|
||||
- 当前常用值:`zh-CN`
|
||||
|
||||
---
|
||||
|
||||
## 4. `map` 字段说明
|
||||
|
||||
### `map.tiles`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:瓦片根路径
|
||||
|
||||
### `map.mapmeta`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图 meta 文件路径
|
||||
|
||||
### `map.declination`
|
||||
|
||||
- 类型:`number`
|
||||
- 必填:否
|
||||
- 说明:磁偏角
|
||||
- 影响:真北 / 磁北换算
|
||||
|
||||
### `map.initialView.zoom`
|
||||
|
||||
- 类型:`number`
|
||||
- 必填:否
|
||||
- 说明:初始缩放级别
|
||||
- 建议默认值:`17`
|
||||
|
||||
---
|
||||
|
||||
## 5. `playfield` 字段说明
|
||||
|
||||
### `playfield.kind`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:空间对象类型
|
||||
- 当前常用值:
|
||||
- `course`
|
||||
- `control-set`
|
||||
|
||||
### `playfield.source.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:空间来源类型
|
||||
- 当前推荐值:`kml`
|
||||
|
||||
### `playfield.source.url`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:KML 路径
|
||||
|
||||
### `playfield.CPRadius`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:检查点绘制半径
|
||||
- 建议默认值:`6`
|
||||
|
||||
### `playfield.metadata.title`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:路线标题
|
||||
|
||||
### `playfield.metadata.code`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:路线编码
|
||||
|
||||
---
|
||||
|
||||
## 6. `playfield.controlOverrides` 字段说明
|
||||
|
||||
### key 命名规则
|
||||
|
||||
- 起点:`start-1`
|
||||
- 普通点:`control-1`、`control-2`、`control-3`
|
||||
- 终点:`finish-1`
|
||||
|
||||
### 当前支持字段
|
||||
|
||||
#### `template`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:原生内容卡模板
|
||||
- 当前支持:
|
||||
- `minimal`
|
||||
- `story`
|
||||
- `focus`
|
||||
|
||||
#### `score`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:积分赛点位分值
|
||||
|
||||
#### `title`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:打点完成后自动弹出的标题
|
||||
|
||||
#### `body`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:打点完成后自动弹出的正文
|
||||
|
||||
#### `clickTitle`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:点击点位时弹出的标题
|
||||
- 默认逻辑:未配置时回退到 `title`
|
||||
|
||||
#### `clickBody`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:点击点位时弹出的正文
|
||||
- 默认逻辑:未配置时回退到 `body`
|
||||
|
||||
#### `autoPopup`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:打点完成后是否自动弹出
|
||||
- 默认逻辑:`true`
|
||||
- 特殊逻辑:`game.punch.policy = "enter"` 时不自动弹原生内容
|
||||
|
||||
#### `once`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:本局只展示一次
|
||||
- 默认逻辑:`false`
|
||||
|
||||
#### `priority`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:内容优先级,越大越高
|
||||
- 默认逻辑:
|
||||
- 普通点:`1`
|
||||
- 终点:`2`
|
||||
|
||||
#### `contentExperience`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:打点完成后的 H5 详情/互动扩展配置
|
||||
- 注意:当前不是直接顶替原生弹窗,而是通过原生卡片 CTA 进入
|
||||
|
||||
#### `contentExperience.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:内容扩展承载类型
|
||||
- 当前支持:
|
||||
- `native`
|
||||
- `h5`
|
||||
|
||||
#### `contentExperience.url`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:H5 详情页地址
|
||||
|
||||
#### `contentExperience.bridge`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:Bridge 协议版本
|
||||
- 当前推荐值:`content-v1`
|
||||
|
||||
#### `contentExperience.presentation`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:H5 内容页展示形态
|
||||
- 当前支持值:
|
||||
- `dialog`
|
||||
- `fullscreen`
|
||||
|
||||
#### `clickExperience`
|
||||
|
||||
- 类型:`object`
|
||||
- 说明:点击点位时的 H5 详情/互动扩展配置
|
||||
- 规则同 `contentExperience`
|
||||
|
||||
---
|
||||
|
||||
## 7. `game` 字段说明
|
||||
|
||||
### `game.mode`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:玩法模式
|
||||
- 当前常用值:
|
||||
- `classic-sequential`
|
||||
- `score-o`
|
||||
|
||||
### `game.rulesVersion`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:规则版本号
|
||||
|
||||
### `game.session.startManually`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否手动开始
|
||||
|
||||
### `game.session.requiresStartPunch`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否必须打起点
|
||||
|
||||
### `game.session.requiresFinishPunch`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否必须打终点
|
||||
|
||||
### `game.session.autoFinishOnLastControl`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:最后一个目标完成后是否自动结束
|
||||
|
||||
### `game.session.maxDurationSec`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:最大对局时长,单位秒
|
||||
|
||||
### `game.punch.policy`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:打点策略
|
||||
- 当前常用值:
|
||||
- `enter-confirm`
|
||||
- `enter`
|
||||
|
||||
### `game.punch.radiusMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:打点半径,单位米
|
||||
|
||||
### `game.punch.requiresFocusSelection`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否需要先聚焦/选中目标再打点
|
||||
|
||||
### `game.sequence.skip.enabled`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:顺序赛是否允许跳点
|
||||
|
||||
### `game.sequence.skip.radiusMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:跳点可用半径
|
||||
|
||||
### `game.sequence.skip.requiresConfirm`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:跳点是否需要二次确认
|
||||
|
||||
### `game.scoring.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:积分模式类型
|
||||
- 当前常用值:`score`
|
||||
|
||||
### `game.scoring.defaultControlScore`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:默认控制点分值
|
||||
|
||||
### `game.guidance.showLegs`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否显示路线腿段
|
||||
|
||||
### `game.guidance.legAnimation`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否开启路线腿段动画
|
||||
|
||||
### `game.guidance.allowFocusSelection`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否允许点击点位选中目标
|
||||
|
||||
### `game.visibility.revealFullPlayfieldAfterStartPunch`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:打完起点后是否显示完整场地
|
||||
|
||||
### `game.finish.finishControlAlwaysSelectable`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:终点是否始终可选
|
||||
|
||||
### `game.telemetry.heartRate.age`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:用户年龄
|
||||
|
||||
### `game.telemetry.heartRate.restingHeartRateBpm`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:静息心率
|
||||
|
||||
### `game.telemetry.heartRate.userWeightKg`
|
||||
|
||||
- 类型:`number`
|
||||
- 说明:体重,单位公斤
|
||||
|
||||
### `game.feedback.audioProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:音效 profile
|
||||
|
||||
### `game.feedback.hapticsProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:震动 profile
|
||||
|
||||
### `game.feedback.uiEffectsProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:UI 动效 profile
|
||||
|
||||
---
|
||||
|
||||
## 8. `resources` 字段说明
|
||||
|
||||
### `resources.audioProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:资源音效配置档
|
||||
|
||||
### `resources.contentProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:内容资源配置档
|
||||
|
||||
### `resources.themeProfile`
|
||||
|
||||
- 类型:`string`
|
||||
- 说明:主题配置档
|
||||
|
||||
---
|
||||
|
||||
## 9. `debug` 字段说明
|
||||
|
||||
### `debug.allowModeSwitch`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否允许玩法切换调试
|
||||
|
||||
### `debug.allowMockInput`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否允许模拟输入
|
||||
|
||||
### `debug.allowSimulator`
|
||||
|
||||
- 类型:`boolean`
|
||||
- 说明:是否允许模拟器调试
|
||||
|
||||
---
|
||||
|
||||
## 10. 积分赛差异点
|
||||
|
||||
如果使用积分赛,通常要修改这几项:
|
||||
|
||||
```json
|
||||
{
|
||||
"playfield": {
|
||||
"kind": "control-set"
|
||||
},
|
||||
"game": {
|
||||
"mode": "score-o",
|
||||
"guidance": {
|
||||
"showLegs": false,
|
||||
"legAnimation": false,
|
||||
"allowFocusSelection": true
|
||||
},
|
||||
"finish": {
|
||||
"finishControlAlwaysSelectable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
并在 `playfield.controlOverrides` 中为普通点补:
|
||||
|
||||
- `score`
|
||||
|
||||
---
|
||||
|
||||
## 11. 推荐配套阅读
|
||||
|
||||
- [D:\dev\cmr-mini\doc\config-template-minimal-game.md](D:/dev/cmr-mini/doc/config-template-minimal-game.md)
|
||||
- [D:\dev\cmr-mini\doc\config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
|
||||
- [D:\dev\cmr-mini\doc\config-docs-index.md](D:/dev/cmr-mini/doc/config-docs-index.md)
|
||||
164
doc/config-template-minimal-classic-sequential.md
Normal file
164
doc/config-template-minimal-classic-sequential.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 顺序赛最小配置模板
|
||||
|
||||
本文档提供一份 **顺序赛(`classic-sequential`)最小可跑配置模板**。
|
||||
|
||||
目标:
|
||||
|
||||
- 只保留顺序赛跑通所需的最少字段
|
||||
- 适合快速起活动、联调、排查配置链
|
||||
- 每个字段都带简要说明
|
||||
|
||||
---
|
||||
|
||||
## 1. 最小模板
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"version": "2026.03.30",
|
||||
"app": {
|
||||
"id": "sample-classic-minimal-001",
|
||||
"title": "顺序赛最小示例"
|
||||
},
|
||||
"map": {
|
||||
"tiles": "../map/lxcb-001/tiles/",
|
||||
"mapmeta": "../map/lxcb-001/tiles/meta.json"
|
||||
},
|
||||
"playfield": {
|
||||
"kind": "course",
|
||||
"source": {
|
||||
"type": "kml",
|
||||
"url": "../kml/lxcb-001/10/c01.kml"
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"mode": "classic-sequential",
|
||||
"punch": {
|
||||
"policy": "enter-confirm",
|
||||
"radiusMeters": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 字段说明
|
||||
|
||||
### `schemaVersion`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置结构版本
|
||||
- 当前建议值:`"1"`
|
||||
|
||||
### `version`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置版本号
|
||||
|
||||
### `app.id`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动配置实例 ID
|
||||
|
||||
### `app.title`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动标题 / 比赛名称
|
||||
|
||||
### `map.tiles`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图瓦片根路径
|
||||
|
||||
### `map.mapmeta`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图 meta 文件路径
|
||||
|
||||
### `playfield.kind`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间对象类型
|
||||
- 顺序赛固定使用:`course`
|
||||
|
||||
### `playfield.source.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间底稿来源类型
|
||||
- 当前推荐值:`kml`
|
||||
|
||||
### `playfield.source.url`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:KML 文件路径
|
||||
|
||||
### `game.mode`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:玩法模式
|
||||
- 顺序赛固定值:`classic-sequential`
|
||||
|
||||
### `game.punch.policy`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:打点策略
|
||||
- 当前常用值:
|
||||
- `enter-confirm`:进入范围后用户再点击确认打点
|
||||
- `enter`:进入范围自动打点
|
||||
|
||||
### `game.punch.radiusMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 必填:是
|
||||
- 说明:打点判定半径,单位米
|
||||
- 建议默认值:`5`
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前默认逻辑
|
||||
|
||||
如果你不写下面这些字段,顺序赛会按当前客户端默认逻辑运行:
|
||||
|
||||
- `map.declination`
|
||||
- 默认按 `0` 处理
|
||||
- `map.initialView.zoom`
|
||||
- 默认由客户端初始视口逻辑接管
|
||||
- `playfield.CPRadius`
|
||||
- 默认按客户端内置值处理
|
||||
- `game.session.*`
|
||||
- 默认手动开始、要求起点打卡、终点打卡
|
||||
- `game.sequence.skip.*`
|
||||
- 默认不启用跳点
|
||||
- `game.guidance.*`
|
||||
- 默认使用当前引导逻辑
|
||||
- `resources.*`
|
||||
- 默认 profile
|
||||
- `debug.*`
|
||||
- 默认关闭
|
||||
|
||||
---
|
||||
|
||||
## 4. 适用场景
|
||||
|
||||
这份模板适合:
|
||||
|
||||
- 快速验证顺序赛主流程
|
||||
- 联调地图和 KML
|
||||
- 后台先跑通最小顺序赛配置
|
||||
|
||||
如果要看更完整版本,请继续参考:
|
||||
|
||||
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
- [D:\dev\cmr-mini\event\classic-sequential.json](D:/dev/cmr-mini/event/classic-sequential.json)
|
||||
201
doc/config-template-minimal-game.md
Normal file
201
doc/config-template-minimal-game.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# 游戏最小可跑配置模板
|
||||
|
||||
本文档提供一份 **去掉大部分选配项之后,当前客户端可以直接跑起来的最小配置模板**。
|
||||
|
||||
目标:
|
||||
|
||||
- 给联调、后台、快速起新活动一个最小起步模板
|
||||
- 保证只填最必要字段时,也能正常进入地图、开始比赛、完成流程
|
||||
- 每个字段都带简要说明,方便直接照着改
|
||||
|
||||
说明:
|
||||
|
||||
- 本模板优先保证“能跑”
|
||||
- 默认以**顺序赛**作为最小示例
|
||||
- 如果要做积分赛,只需要替换少量字段
|
||||
|
||||
---
|
||||
|
||||
## 1. 最小模板
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"version": "2026.03.30",
|
||||
"app": {
|
||||
"id": "sample-minimal-001",
|
||||
"title": "最小顺序赛示例"
|
||||
},
|
||||
"map": {
|
||||
"tiles": "../map/lxcb-001/tiles/",
|
||||
"mapmeta": "../map/lxcb-001/tiles/meta.json"
|
||||
},
|
||||
"playfield": {
|
||||
"kind": "course",
|
||||
"source": {
|
||||
"type": "kml",
|
||||
"url": "../kml/lxcb-001/10/c01.kml"
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"mode": "classic-sequential",
|
||||
"punch": {
|
||||
"policy": "enter-confirm",
|
||||
"radiusMeters": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 字段说明
|
||||
|
||||
### `schemaVersion`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置结构版本
|
||||
- 当前建议值:`"1"`
|
||||
|
||||
### `version`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置版本号
|
||||
- 建议写法:日期或发布号,例如 `2026.03.30`
|
||||
|
||||
### `app.id`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动配置实例 ID
|
||||
- 用途:区分不同活动或不同配置版本
|
||||
|
||||
### `app.title`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动标题 / 比赛名称
|
||||
|
||||
### `map.tiles`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图瓦片根路径
|
||||
|
||||
### `map.mapmeta`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图 meta 文件路径
|
||||
|
||||
### `playfield.kind`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间对象类型
|
||||
- 最小顺序赛推荐值:`course`
|
||||
- 最小积分赛推荐值:`control-set`
|
||||
|
||||
### `playfield.source.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间底稿来源类型
|
||||
- 当前推荐值:`kml`
|
||||
|
||||
### `playfield.source.url`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:KML 文件路径
|
||||
|
||||
### `game.mode`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:玩法模式
|
||||
- 当前常用值:
|
||||
- `classic-sequential`
|
||||
- `score-o`
|
||||
|
||||
### `game.punch.policy`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:打点触发方式
|
||||
- 当前常用值:
|
||||
- `enter-confirm`
|
||||
- `enter`
|
||||
|
||||
### `game.punch.radiusMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 必填:是
|
||||
- 说明:打点判定半径,单位米
|
||||
- 建议默认值:`5`
|
||||
|
||||
---
|
||||
|
||||
## 3. 最小积分赛改法
|
||||
|
||||
如果你要把这份最小模板改成积分赛,只需要改这几项:
|
||||
|
||||
```json
|
||||
{
|
||||
"playfield": {
|
||||
"kind": "control-set",
|
||||
"source": {
|
||||
"type": "kml",
|
||||
"url": "../kml/lxcb-001/10/c01.kml"
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"mode": "score-o",
|
||||
"punch": {
|
||||
"policy": "enter-confirm",
|
||||
"radiusMeters": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前最小模板默认逻辑
|
||||
|
||||
即使你没有填写下面这些字段,当前客户端也会按默认逻辑运行:
|
||||
|
||||
- `map.declination`
|
||||
- 默认按 `0` 处理
|
||||
- `map.initialView.zoom`
|
||||
- 默认由客户端初始视口逻辑接管
|
||||
- `playfield.CPRadius`
|
||||
- 默认按客户端内置值处理
|
||||
- `game.session.*`
|
||||
- 使用玩法默认逻辑
|
||||
- `game.guidance.*`
|
||||
- 使用当前默认引导逻辑
|
||||
- `game.visibility.*`
|
||||
- 使用当前默认可见性逻辑
|
||||
- `resources.*`
|
||||
- 使用默认资源 profile
|
||||
- `debug.*`
|
||||
- 默认关闭
|
||||
|
||||
---
|
||||
|
||||
## 5. 适用场景
|
||||
|
||||
这份模板适合:
|
||||
|
||||
- 新活动快速起盘
|
||||
- 联调验证地图和 KML 是否正常
|
||||
- 后台先跑通配置装配链
|
||||
- 调试客户端主流程是否可进入
|
||||
|
||||
如果要做正式项目,请继续参考:
|
||||
|
||||
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
- [D:\dev\cmr-mini\doc\config-option-dictionary.md](D:/dev/cmr-mini/doc/config-option-dictionary.md)
|
||||
199
doc/config-template-minimal-score-o.md
Normal file
199
doc/config-template-minimal-score-o.md
Normal file
@@ -0,0 +1,199 @@
|
||||
# 积分赛最小配置模板
|
||||
|
||||
本文档提供一份 **积分赛(`score-o`)最小可跑配置模板**。
|
||||
|
||||
目标:
|
||||
|
||||
- 只保留积分赛跑通所需的最少字段
|
||||
- 适合快速起活动、联调、排查配置链
|
||||
- 每个字段都带简要说明
|
||||
|
||||
---
|
||||
|
||||
## 1. 最小模板
|
||||
|
||||
```json
|
||||
{
|
||||
"schemaVersion": "1",
|
||||
"version": "2026.03.30",
|
||||
"app": {
|
||||
"id": "sample-score-o-minimal-001",
|
||||
"title": "积分赛最小示例"
|
||||
},
|
||||
"map": {
|
||||
"tiles": "../map/lxcb-001/tiles/",
|
||||
"mapmeta": "../map/lxcb-001/tiles/meta.json"
|
||||
},
|
||||
"playfield": {
|
||||
"kind": "control-set",
|
||||
"source": {
|
||||
"type": "kml",
|
||||
"url": "../kml/lxcb-001/10/c01.kml"
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"mode": "score-o",
|
||||
"punch": {
|
||||
"policy": "enter-confirm",
|
||||
"radiusMeters": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 字段说明
|
||||
|
||||
### `schemaVersion`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置结构版本
|
||||
- 当前建议值:`"1"`
|
||||
|
||||
### `version`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:配置版本号
|
||||
|
||||
### `app.id`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动配置实例 ID
|
||||
|
||||
### `app.title`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:活动标题 / 比赛名称
|
||||
|
||||
### `map.tiles`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图瓦片根路径
|
||||
|
||||
### `map.mapmeta`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:地图 meta 文件路径
|
||||
|
||||
### `playfield.kind`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间对象类型
|
||||
- 积分赛固定使用:`control-set`
|
||||
|
||||
### `playfield.source.type`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:空间底稿来源类型
|
||||
- 当前推荐值:`kml`
|
||||
|
||||
### `playfield.source.url`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:KML 文件路径
|
||||
|
||||
### `game.mode`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:玩法模式
|
||||
- 积分赛固定值:`score-o`
|
||||
|
||||
### `game.punch.policy`
|
||||
|
||||
- 类型:`string`
|
||||
- 必填:是
|
||||
- 说明:打点策略
|
||||
- 当前常用值:
|
||||
- `enter-confirm`
|
||||
- `enter`
|
||||
|
||||
### `game.punch.radiusMeters`
|
||||
|
||||
- 类型:`number`
|
||||
- 必填:是
|
||||
- 说明:打点判定半径,单位米
|
||||
- 建议默认值:`5`
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前默认逻辑
|
||||
|
||||
如果你不写下面这些字段,积分赛会按当前客户端默认逻辑运行:
|
||||
|
||||
- `map.declination`
|
||||
- 默认按 `0` 处理
|
||||
- `map.initialView.zoom`
|
||||
- 默认由客户端初始视口逻辑接管
|
||||
- `playfield.CPRadius`
|
||||
- 默认按客户端内置值处理
|
||||
- `playfield.controlOverrides.*.score`
|
||||
- 没配时走 `game.scoring.defaultControlScore` 或玩法默认值
|
||||
- `game.session.*`
|
||||
- 默认手动开始
|
||||
- `game.guidance.allowFocusSelection`
|
||||
- 默认按积分赛逻辑允许选点
|
||||
- `game.finish.finishControlAlwaysSelectable`
|
||||
- 默认按积分赛逻辑处理终点可选
|
||||
- `resources.*`
|
||||
- 默认 profile
|
||||
- `debug.*`
|
||||
- 默认关闭
|
||||
|
||||
---
|
||||
|
||||
## 4. 推荐补充字段
|
||||
|
||||
如果你要让积分赛更接近正式活动,通常很快会补这几项:
|
||||
|
||||
```json
|
||||
{
|
||||
"playfield": {
|
||||
"controlOverrides": {
|
||||
"control-1": {
|
||||
"score": 10
|
||||
},
|
||||
"control-2": {
|
||||
"score": 20
|
||||
}
|
||||
}
|
||||
},
|
||||
"game": {
|
||||
"scoring": {
|
||||
"type": "score",
|
||||
"defaultControlScore": 10
|
||||
},
|
||||
"guidance": {
|
||||
"allowFocusSelection": true
|
||||
},
|
||||
"finish": {
|
||||
"finishControlAlwaysSelectable": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 适用场景
|
||||
|
||||
这份模板适合:
|
||||
|
||||
- 快速验证积分赛主流程
|
||||
- 联调自由选点、积分累加、终点结束
|
||||
- 后台先跑通最小积分赛配置
|
||||
|
||||
如果要看更完整版本,请继续参考:
|
||||
|
||||
- [D:\dev\cmr-mini\doc\config-template-full-current.md](D:/dev/cmr-mini/doc/config-template-full-current.md)
|
||||
- [D:\dev\cmr-mini\event\score-o.json](D:/dev/cmr-mini/event/score-o.json)
|
||||
210
doc/gps-marker-animation-system-proposal.md
Normal file
210
doc/gps-marker-animation-system-proposal.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# GPS 点动画系统方案
|
||||
|
||||
## 目标
|
||||
|
||||
把 GPS 点从“静态定位点”升级成**状态驱动的动态标记系统**:
|
||||
|
||||
- 停止时是一种动画
|
||||
- 移动时是一种动画
|
||||
- 高速时是一种动画
|
||||
- 高压/危险状态时还能叠加额外张力
|
||||
|
||||
原则:
|
||||
|
||||
- 优先程序化动画,不先上重资源
|
||||
- 不破坏当前位置识别性
|
||||
- 必须兼容 `standard / lite`
|
||||
- 品牌 logo 只是贴片,不替代定位点本体和朝向三角
|
||||
|
||||
## 状态分层
|
||||
|
||||
### 1. 运动状态
|
||||
|
||||
- `idle`
|
||||
- 基本静止
|
||||
- 轻呼吸
|
||||
- 不拖尾
|
||||
- `moving`
|
||||
- 正常行走/跑动
|
||||
- 有轻微动势和尾迹
|
||||
- `fast-moving`
|
||||
- 明显高速
|
||||
- 更强脉冲
|
||||
- 更长尾迹
|
||||
- 朝向更锐利
|
||||
|
||||
### 2. 危险/高压状态
|
||||
|
||||
- `warning`
|
||||
- 由心率/张力状态触发
|
||||
- 不替代运动判断,而是在视觉上给 GPS 点额外警示感
|
||||
- 更暖的色彩张力
|
||||
- 更强的外环脉冲
|
||||
|
||||
## 第一阶段实现范围
|
||||
|
||||
### 默认动画 profile
|
||||
|
||||
- `dynamic-runner`
|
||||
|
||||
后续预留:
|
||||
|
||||
- `minimal`
|
||||
- `warning-reactive`
|
||||
|
||||
### 第一阶段具体表现
|
||||
|
||||
#### `idle`
|
||||
|
||||
- 慢节奏呼吸
|
||||
- 基本无拖尾
|
||||
- 方向三角稍收敛
|
||||
|
||||
#### `moving`
|
||||
|
||||
- 普通脉冲
|
||||
- 后侧轻尾迹
|
||||
- 方向三角略放大
|
||||
|
||||
#### `fast-moving`
|
||||
|
||||
- 更快脉冲
|
||||
- 更长尾迹
|
||||
- 本体略放大
|
||||
- 方向三角更强
|
||||
|
||||
#### `warning`
|
||||
|
||||
- 保留运动态基础
|
||||
- 外环增加暖色警示张力
|
||||
- 脉冲节奏更急
|
||||
|
||||
## 第一阶段配置字段
|
||||
|
||||
入口:
|
||||
|
||||
```json
|
||||
"game": {
|
||||
"presentation": {
|
||||
"gpsMarker": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
新增字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"animationProfile": "dynamic-runner"
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `minimal`
|
||||
- 更轻、更克制
|
||||
- 适合低配或保守活动风格
|
||||
- `dynamic-runner`
|
||||
- 默认值
|
||||
- 强调移动感
|
||||
- `warning-reactive`
|
||||
- 更强调高压/危险张力
|
||||
|
||||
## 运行时内部字段
|
||||
|
||||
这些字段不建议先暴露给活动配置,而是由运行时自动计算:
|
||||
|
||||
- `motionState`
|
||||
- `motionIntensity`
|
||||
- `wakeStrength`
|
||||
- `warningGlowStrength`
|
||||
- `indicatorScale`
|
||||
- `logoScale`
|
||||
|
||||
这样可以保证:
|
||||
|
||||
- 配置简单
|
||||
- 逻辑稳定
|
||||
- 真机调完后再决定哪些值得开放
|
||||
|
||||
## 运行时判定建议
|
||||
|
||||
### 运动状态
|
||||
|
||||
- `< 1.0 km/h`:`idle`
|
||||
- `1.0 ~ 6.8 km/h`:`moving`
|
||||
- `>= 6.8 km/h`:`fast-moving`
|
||||
|
||||
### 高压状态
|
||||
|
||||
参考现有 telemetry tone:
|
||||
|
||||
- `yellow`
|
||||
- `orange`
|
||||
- `red`
|
||||
|
||||
其中:
|
||||
|
||||
- `orange / red`
|
||||
优先进入 `warning`
|
||||
- `yellow`
|
||||
作为较轻的张力增强
|
||||
|
||||
## 渲染拆分
|
||||
|
||||
### WebGL 主体
|
||||
|
||||
负责:
|
||||
|
||||
- 本体
|
||||
- 外环
|
||||
- 脉冲
|
||||
- 尾迹
|
||||
- 朝向三角
|
||||
|
||||
### 2D 叠加层
|
||||
|
||||
负责:
|
||||
|
||||
- logo 中心贴片
|
||||
|
||||
logo 不参与主几何动画,只跟随缩放强度和尺寸变化。
|
||||
|
||||
## 性能策略
|
||||
|
||||
### `standard`
|
||||
|
||||
- 完整脉冲
|
||||
- 完整尾迹
|
||||
- 警示外环
|
||||
|
||||
### `lite`
|
||||
|
||||
- 减弱尾迹
|
||||
- 降低 glow
|
||||
- 降低 warning 外环强度
|
||||
- 保留最基本的移动/静止差异
|
||||
|
||||
## 后续第二阶段
|
||||
|
||||
- logo 贴片本身的轻动画
|
||||
- 事件动作
|
||||
- 打点成功跳动
|
||||
- 锁定开启反馈
|
||||
- 高压进入反馈
|
||||
- mascot/角色化 GPS 点
|
||||
|
||||
## 结论
|
||||
|
||||
GPS 点动画不应该做成单一固定动画,而应该做成:
|
||||
|
||||
**状态驱动的动态标记系统**
|
||||
|
||||
第一阶段先把:
|
||||
|
||||
- `idle`
|
||||
- `moving`
|
||||
- `fast-moving`
|
||||
- `warning`
|
||||
|
||||
这 4 种状态的程序化动画跑通,再决定后续是否继续开放更细粒度配置。
|
||||
113
doc/gps-marker-style-system-proposal.md
Normal file
113
doc/gps-marker-style-system-proposal.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# GPS 点样式系统方案
|
||||
|
||||
## 目标
|
||||
|
||||
把当前“粗糙蓝点”升级成正式的 GPS 点样式系统,满足:
|
||||
|
||||
- 默认样式更精致
|
||||
- 显示/隐藏可控
|
||||
- 大小可调
|
||||
- 颜色可调
|
||||
- 带跟随朝向旋转的小三角
|
||||
- 后续可承接品牌 logo 定制
|
||||
|
||||
## 分层
|
||||
|
||||
### 1. 显示策略
|
||||
|
||||
- `visible`
|
||||
- `size`
|
||||
- `colorPreset`
|
||||
|
||||
### 2. 基础样式
|
||||
|
||||
第一阶段支持:
|
||||
|
||||
- `dot`
|
||||
- `beacon`
|
||||
- `disc`
|
||||
- `badge`
|
||||
|
||||
默认:
|
||||
|
||||
- `beacon`
|
||||
|
||||
### 3. 朝向指示
|
||||
|
||||
GPS 点上方增加一个小三角:
|
||||
|
||||
- 跟随朝向旋转
|
||||
- 朝向可信度高时更明显
|
||||
- 朝向可信度低时自动降低透明度
|
||||
|
||||
### 4. 品牌化扩展
|
||||
|
||||
后续通过:
|
||||
|
||||
- `logoUrl`
|
||||
- `logoMode`
|
||||
|
||||
把商家 logo 作为中心贴片嵌入 GPS 点,不直接替代定位点本体。
|
||||
|
||||
## 第一阶段默认值
|
||||
|
||||
```json
|
||||
{
|
||||
"visible": true,
|
||||
"style": "beacon",
|
||||
"size": "medium",
|
||||
"colorPreset": "cyan",
|
||||
"showHeadingIndicator": true,
|
||||
"logoUrl": "",
|
||||
"logoMode": "center-badge"
|
||||
}
|
||||
```
|
||||
|
||||
## 用户设置建议
|
||||
|
||||
系统设置先开放:
|
||||
|
||||
- GPS 点显示:`显示 / 隐藏`
|
||||
- GPS 点大小:`小 / 中 / 大`
|
||||
- GPS 点颜色:8 种亮色
|
||||
|
||||
品牌 logo 先不进用户设置,只保留给活动配置。
|
||||
|
||||
## 配置入口
|
||||
|
||||
建议统一放在:
|
||||
|
||||
```json
|
||||
"game": {
|
||||
"presentation": {
|
||||
"gpsMarker": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 长期演进
|
||||
|
||||
### 第二阶段
|
||||
|
||||
- logo 中心贴片
|
||||
- 不同玩法默认 GPS 点 profile
|
||||
- 更强的脉冲/光晕动画
|
||||
|
||||
### 第三阶段
|
||||
|
||||
- GPS 点与心率/危险状态联动
|
||||
- 客户品牌化主题包
|
||||
- 特殊活动皮肤
|
||||
|
||||
## 结论
|
||||
|
||||
GPS 点应被视为独立样式系统,而不是固定蓝点。
|
||||
|
||||
第一阶段先把:
|
||||
|
||||
- 显示
|
||||
- 大小
|
||||
- 颜色
|
||||
- 朝向三角
|
||||
|
||||
做稳定,再逐步承接商业品牌化定制。
|
||||
125
doc/mock-simulator-debug-log-proposal.md
Normal file
125
doc/mock-simulator-debug-log-proposal.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# 模拟器调试日志方案
|
||||
|
||||
## 目标
|
||||
|
||||
复用现有 GPS 模拟器 websocket,在不污染地图调试面板的前提下,把高频、临时、开发期日志输出到外部模拟器。
|
||||
|
||||
第一阶段只做最小闭环:
|
||||
|
||||
- 复用 `tools/mock-gps-sim` 现有 websocket
|
||||
- 增加 `debug-log` 消息类型
|
||||
- 小程序侧增加最小 logger
|
||||
- 第一批只发送 `gps-logo` 范围日志
|
||||
|
||||
## 设计原则
|
||||
|
||||
- 调试面板看“当前状态”
|
||||
- 模拟器日志看“变化过程”
|
||||
- 日志链只在开发/调试期间启用
|
||||
- 不进入正式玩法逻辑
|
||||
- 不把高频临时日志继续塞进页面 WXML
|
||||
|
||||
## 协议
|
||||
|
||||
消息类型:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "debug-log",
|
||||
"timestamp": 1712345678901,
|
||||
"scope": "gps-logo",
|
||||
"level": "info",
|
||||
"message": "wx.getImageInfo success",
|
||||
"payload": {
|
||||
"src": "https://example.com/logo.png",
|
||||
"path": "wxfile://tmp_xxx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
字段说明:
|
||||
|
||||
- `type`
|
||||
固定为 `debug-log`
|
||||
- `timestamp`
|
||||
毫秒时间戳
|
||||
- `scope`
|
||||
日志分类,例如 `gps-logo`、`h5`、`compass`
|
||||
- `level`
|
||||
`info / warn / error`
|
||||
- `message`
|
||||
简短可读说明
|
||||
- `payload`
|
||||
可选附加对象,用于排查细节
|
||||
|
||||
## 第一阶段 scope
|
||||
|
||||
第一批只接:
|
||||
|
||||
- `gps-logo`
|
||||
|
||||
典型日志点:
|
||||
|
||||
- logo 未配置
|
||||
- 当前风格不是 `badge`
|
||||
- 开始加载 logo
|
||||
- `wx.getImageInfo` 成功
|
||||
- `wx.getImageInfo` 失败
|
||||
- 图片 `onload`
|
||||
- 图片 `onerror`
|
||||
|
||||
## 小程序侧实现
|
||||
|
||||
新增:
|
||||
|
||||
- `miniprogram/engine/debug/mockSimulatorDebugLogger.ts`
|
||||
|
||||
职责:
|
||||
|
||||
- 复用 mock GPS simulator websocket 地址
|
||||
- 负责连接、断开、简单队列、发送 `debug-log`
|
||||
- 只在调试 UI 开启时启用
|
||||
|
||||
接入点:
|
||||
|
||||
- `MapEngine`
|
||||
- 调试 UI 开启时启用 logger
|
||||
- 调试 UI 关闭时关闭 logger
|
||||
- mock bridge 地址变化时同步 logger 地址
|
||||
- `CourseLabelRenderer`
|
||||
- 发送 `gps-logo` 相关日志
|
||||
|
||||
## 模拟器侧实现
|
||||
|
||||
复用:
|
||||
|
||||
- `tools/mock-gps-sim/server.js`
|
||||
- `tools/mock-gps-sim/public/index.html`
|
||||
- `tools/mock-gps-sim/public/simulator.js`
|
||||
|
||||
最小能力:
|
||||
|
||||
- websocket 接收 `debug-log`
|
||||
- UI 新增“调试日志”区域
|
||||
- 仅显示 `debug-log`
|
||||
- 保留最近若干条,避免无限增长
|
||||
|
||||
## 后续扩展
|
||||
|
||||
第二阶段可以再补:
|
||||
|
||||
- `compass`
|
||||
- `h5`
|
||||
- `content-card`
|
||||
- `heart-rate`
|
||||
|
||||
第三阶段再补:
|
||||
|
||||
- scope 过滤
|
||||
- level 过滤
|
||||
- 暂停滚动
|
||||
- 导出日志
|
||||
|
||||
## 当前结论
|
||||
|
||||
先把 `gps-logo` 调试链打通,再回头用模拟器日志查 logo 为什么不显示,比继续把临时字段堆在调试面板里更稳。
|
||||
85
doc/track-visualization-proposal.md
Normal file
85
doc/track-visualization-proposal.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# 轨迹可视化方案
|
||||
|
||||
本文档定义用户轨迹的显示模式、默认策略与配置结构。
|
||||
|
||||
目标:
|
||||
|
||||
- 支持 `none / full / tail` 三种轨迹模式
|
||||
- `tail` 模式有更强的实时感和游戏感
|
||||
- 兼顾低端机性能
|
||||
|
||||
## 模式定义
|
||||
|
||||
### `none`
|
||||
|
||||
- 不显示轨迹
|
||||
- 只显示当前 GPS 点
|
||||
|
||||
### `full`
|
||||
|
||||
- 显示从开始到当前的完整轨迹
|
||||
|
||||
### `tail`
|
||||
|
||||
- 只显示最近一小段拖尾轨迹
|
||||
- 头部更亮、更粗
|
||||
- 尾部逐步变淡、变细
|
||||
- 用户停止移动后,轨迹会逐步缩短到消失
|
||||
|
||||
## 推荐默认值
|
||||
|
||||
### 顺序赛
|
||||
|
||||
- `mode = full`
|
||||
- `style = classic`
|
||||
|
||||
### 积分赛
|
||||
|
||||
- `mode = tail`
|
||||
- `style = neon`
|
||||
|
||||
## 推荐配置
|
||||
|
||||
```json
|
||||
"game": {
|
||||
"presentation": {
|
||||
"track": {
|
||||
"mode": "tail",
|
||||
"style": "neon",
|
||||
"tailMeters": 60,
|
||||
"tailMaxSeconds": 30,
|
||||
"fadeOutWhenStill": true,
|
||||
"stillSpeedKmh": 0.6,
|
||||
"fadeOutDurationMs": 3000,
|
||||
"colorHex": "#176d5d",
|
||||
"headColorHex": "#54f3d8",
|
||||
"widthPx": 5,
|
||||
"headWidthPx": 10,
|
||||
"glowStrength": 0.42
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 当前实现约定
|
||||
|
||||
当前第一版实现支持:
|
||||
|
||||
- `mode`
|
||||
- `style`
|
||||
- `tailMeters`
|
||||
- `tailMaxSeconds`
|
||||
- `fadeOutWhenStill`
|
||||
- `stillSpeedKmh`
|
||||
- `fadeOutDurationMs`
|
||||
- `colorHex`
|
||||
- `headColorHex`
|
||||
- `widthPx`
|
||||
- `headWidthPx`
|
||||
- `glowStrength`
|
||||
|
||||
## 后续扩展
|
||||
|
||||
- 轨迹颜色按心率区间变化
|
||||
- 轨迹颜色按速度变化
|
||||
- `standard / lite` 下自动降级 glow
|
||||
Reference in New Issue
Block a user