desktop: 双方血条(角上平行四边形)、归零即击败、去掉受击抖动、裁判端可改队名
界面改动都在浏览器预览里逐条核对过(DOM 尺寸 + 视觉),截图留在 desktop/screenshots/ (该目录不进仓库)。 1. 客户端显示对手的血量 快照里两端都给两支队伍(顺序固定为队伍号 0/1),界面按 `team` 取那一格,不再靠 数组下标。顺带修掉一个真 bug:用户端"对手那一格"以前会走 `armor_id`——那是我自己 绑定的主板,于是右上角显示的是自己的血,比不显示更糟。现在只有"自己那一块"才用 `armor_id`;同理 `assigned_armor` 里的裁判端槽位指定对用户端不再生效。 2. 血条改到画面两个上角,平行四边形,一条分 5 格 左上角自己、右上角对手(裁判端两格各贴自己的角,读法一致)。整条 skewX(-15deg), 右条再 scaleX(-1) 镜像,两条斜边朝外对称、**都从靠中心的一侧开始灭**。一格 20 点血。 条挂在绝对定位的一层上并 pointer-events:none(那一层盖着画面,而画面要能滚轮缩放、 拖动),倍率与复位徽标因此从上沿挪到下沿。未接入显示"装甲板未接入"而不是 0。 注意:不要在 JS 里再反转一次数组——那会和 CSS 的 scaleX(-1) 互相抵消,表现是右条 从外侧开始灭(代码里写了注释钉住这件事)。 3. 受击画面不抖动 删掉整幅图(含瞄准器)的位移与 shakeOffset。`HitFeedbackConfig::shake` 字段保留但 **不再生效**:配置文件是 deny_unknown_fields 的,删字段会让所有写过 shake = true 的 配置解析失败,而配置解析失败等于程序起不来。默认值改 false,设置面板去掉开关, 并有单测钉住"旧配置读得进来、默认不抖"。 4. 血量归零算击败,不显示"损毁" 血条上不再出现"已击毁/损毁",归零的结论放到图传中央:胜利 / 击败 / 平局。结论在 Rust 侧算(snapshot::resolve_outcomes,4 条单测),规则有意不对称——**输只看自己** (自己归零就是输,哪怕对手主板掉线),**赢要看两边**(对手归零且自己还有血), 两边同时归零是平局。它一直显示到血量被重置,不做几秒淡出,否则截图与回放里就再也 没有"这局结束了"的痕迹。 5. 裁判端可以改队伍名 两格画面各自下面一个输入框:回车/失焦生效、Esc 取消、超 12 字截断、留空回落到 「队伍一 / 队伍二」。命令是 `set_team_name(team, name)`,**一次只改一边**——传整个 两条的数组就成了"读两条、改一条、写两条",而读来的那两条来自最多 200ms 前的快照, 紧接着改另一边会把上一次的改动覆盖回去。规范化统一在 `config::sanitize_team_name` (合并空白、按字符截断、留空回落),并同样过密码闸门(裁判端本来就没有密码)。 名字只有一个来源(快照的 `teamNames` / DTO 的 `name`):装甲板表、槽位标签、设置 面板与"等待图传"的占位文字都跟着改,不再有第二处自己拼"队伍一/队伍二"。 测试:core 80(69→80)、src-tauri 30、protocol 15;`pnpm build`(tsc + vite)通过。
This commit is contained in:
@@ -6,13 +6,13 @@ UDP 图传。
|
||||
固件是跑在 ESP-IDF 上的 Rust,用官方 esp32-camera 组件采集;桌面端是 **Tauri v2 +
|
||||
React**,用户端与裁判端两套页面(见 [`desktop/README.md`](desktop/README.md))。同一套
|
||||
系统里还有一队一块的**装甲板**(ESP32-C3,一主三从),负责四路击打检测、灯带与整车血量,
|
||||
并把血量广播给裁判终端。
|
||||
并把血量广播给局域网里的两端。
|
||||
|
||||
```text
|
||||
protocol/ 线路格式 + 帧重组 三端共用,无 ESP-IDF 依赖,14 个单元测试
|
||||
. 图传固件 -> ESP32-S3 交叉编译,Xtensa
|
||||
armor/ 装甲板固件 -> ESP32-C3 独立 workspace,RISC-V;规则层 22 个单元测试
|
||||
desktop/ 桌面端 Tauri v2 + React;用户端(血条 + 瞄准器)/ 裁判端
|
||||
desktop/ 桌面端 Tauri v2 + React;用户端(双方血条 + 瞄准器)/ 裁判端(可改队名)
|
||||
core/ 不含界面与 Tauri 的网络层、配置、密码(可单测)
|
||||
src-tauri/ Tauri 后端:推流、命令、录制
|
||||
src/ React 前端:两套页面 + HUD
|
||||
@@ -43,7 +43,9 @@ desktop/ 桌面端 Tauri v2 + React;用户端(血条 + 瞄
|
||||
上报里必须带 `team` 字段,而且灯色现场不该靠按键切错。见 `armor/README.md`。
|
||||
|
||||
裁判终端同时收两块图传板,也收两块装甲板主板在 5601 上广播的血量。队伍客户端也收
|
||||
全部板子的视频,然后在**界面层**过滤到绑定的那一块。
|
||||
全部板子的视频,然后在**界面层**过滤到绑定的那一块;**血量相反,两边都显示**——用户端的
|
||||
画面左上角是自己、右上角是对手。血量本来就是明文广播的(裁判端与用户端收的是同一份),而
|
||||
"自己的血与对手的血一起看"是这项运动里最基本的对照,藏起来只会让操作手看不见对手的血。
|
||||
|
||||
## 实测性能
|
||||
|
||||
@@ -384,8 +386,9 @@ python3 scripts/armor_probe.py 15 # 不开界面,单看板子在广播什么
|
||||
|
||||
桌面端侧:`desktop/core/src/armor.rs` 的 `ArmorHealthStore` 监听 5601,按 `(team, index)`
|
||||
存最后一次读数,四条都在 1.5 s 内收到才显示——**没有数据时显示占位符而不是 0**,
|
||||
0 看起来像真值,现场看到会以为对方已经没血了。界面上直接显示血量数字(整车一条血,
|
||||
归零显示 `0 · 已击毁` 并转红);数字变化也会打进客户端日志。
|
||||
0 看起来像真值,现场看到会以为对方已经没血了。界面上的血量画在画面角上(一条分 5 格的
|
||||
平行四边形,20 点血一格),归零不写"已击毁/损毁",而是由图传中央的「胜利 / 击败」横幅表达
|
||||
(见 [`desktop/README.md`](desktop/README.md));数字变化也会打进客户端日志。
|
||||
|
||||
同一块板子还会被单独记下来(帧头里的 MAC 派生 id),所以两端都能列出"场上有哪几块装甲板"
|
||||
并选一块绑定——命中反馈也是从这个 id 上归位的。**这不需要改固件**:主板一直在用
|
||||
|
||||
Reference in New Issue
Block a user