動畫時序照 Codex 校正,並修掉 look 列被畫小造成的縮水

摘要:
待機動畫放慢成 Codex 的速度、非 idle 狀態播 3 次後沉澱,並自動補正 spritesheet 裡整列 look 格子被畫小的缺陷。

根本原因:
1. idle 直接用合約上的幀時長無限循環,一輪只有 1.1 秒,看起來一直在動。Codex 的 codex-pet-assets 裡有一個放慢倍率 6,idle 實際是一輪 6.6 秒,其他狀態則是播 3 次後接上慢速 idle 並從那裡循環。
2. 內附的小念 spritesheet 第 10 列(看向 180 度到 337.5 度)整列被畫成 idle 的 78%,寬高同時縮小。游標移到人物身上或左邊時會切到那一列,人物就突然矮一截。第 9 列尾端只有高度變矮、寬度不變,那是低頭姿勢,不能一起改。
3. 追視參考點取在頭部高度(0.3),與 Codex 的方框中心不同,使得更多游標位置被判成「在下方」,更容易踩到第 10 列。

影響:
待機時一直晃;游標一靠近或移到左側,人物就明顯縮水又彈回來。

修法:
- 動畫改成序列模型(frames = [{row, col, ms}] + loopStart),對應 Codex 的 f(state):
  IDLE_SLOWDOWN = 6、STATE_REPEATS = 3、播完 3 次後循環慢速 idle。
- 每個 hook 事件都重播一次動畫(pulse),對應 Codex 每次狀態更新都會重跑動畫效果;
  否則狀態播完 3 次後就再也看不出 Claude Code 在忙。
- 載入寵物時量測 16 個 look 格子,以整列中位數判斷是否整列被縮小(門檻 0.9),
  是的話以腳底為支點放大回 idle 身高;單格差異不動,避免把低頭姿勢拉直。
- 追視參考點改為人物方框中心、死區改為 1 px,與 Codex 相同。
- 拖曳用的 running-left / running-right 維持持續循環,不套用沉澱規則。

刻意不同於 Codex 的地方:
Codex 的追視會覆蓋所有狀態,本程式只在 idle 時追視。否則工作中的動畫會被靜態擺姿蓋掉,
寵物就失去反映 Claude Code 狀態的作用。

驗證:
- 抽出序列邏輯單獨執行:idle 一輪 6600 ms(幀長 1680/660/660/840/840/1920);
  running / waiting / review 皆為 24 幀、第 18 幀起循環列 0;拖曳維持循環;一次性動作播完即止。
- 以 PIL 重現量測與繪製:小念第 9 列中位數比 0.995 不補正,第 10 列 0.783 補正倍率 1.2774,
  補正後畫面身高 128.7-132.1 px(idle 為 130.4),且無任何一格超出畫布;
  xiao-nian-realistic 兩列都是 0.99,判定不需補正而未受影響。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar 內的 renderer.js 與 main.js,確認六項改動都在出貨的檔案裡。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 14:41:42 +08:00
co-authored by Claude Fable 5
parent e591475d4c
commit c96dcccb80
3 changed files with 170 additions and 35 deletions
+1 -1
View File
@@ -277,7 +277,7 @@ function startCursorPolling() {
lastCursor = p;
const b = win.getBounds();
const cx = b.x + b.width / 2;
const cy = b.y + BUBBLE_H + PET_H * config.scale * 0.3; // 大約頭部的高度
const cy = b.y + BUBBLE_H + (PET_H * config.scale) / 2; // 人物方框的中心,與 Codex 相同
send("pet:cursor", { dx: p.x - cx, dy: p.y - cy });
}, 50);
}