- AI 插件
- dsh-plugin
- 交互助手
- 桌面应用
【免费下载链接】dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI 视频自造专属宠物
dsh-pet 是一款住在 DeepSeek Harness 里的透明动画桌面宠物:除了待机呼吸、随机动作、右键点播之外,它最"上头"的玩法是把宠物拖起来用力甩出去——它会沿抛物线飞、撞屏边缘反弹、落地摩擦停稳,多显示器下甚至能跨屏弹跳。本文带你用通俗的方式看懂 dsh-pet 拖拽抛掷物理引擎背后的设计:弹簧跟手、初速估算、重力反弹与多屏穿行的实现思路,以及怎么在配置里调出最顺手的"弹感"。
🎯 弹簧跟手:为什么拖起来不抖、不飘、不"甩尾"
大多数桌宠拖拽是"鼠标到哪、宠物到哪",高频鼠标事件会让画面抖动。dsh-pet 的做法是给宠物挂一根虚拟弹簧:指针位置是弹簧的"目标",宠物位置是弹簧末端,每一帧朝目标加速追赶。
- 弹簧刚度
K = 200、阻尼C = 30,阻尼比 ζ ≈ 1.06 —— 属于过阻尼:跟得很紧但绝不冲过头(不 overshoot),所以拖快了宠物是"贴着"追上来,而不是荡出去再弹回来 - 松手前,弹簧的"速度"就是宠物此时的速度,为下一阶段的抛掷无缝续上
相关常量定义在 physics.ts,浏览器端驱动循环见 pet.ts。
💡 过阻尼是"手感"的核心:既保留了一点弹性跟随的柔软感,又不会出现"甩一下,宠物原地画圈"的失控。
🚀 松手瞬间:初速估算如何"读懂"你的甩动
"温柔放下"和"大力甩出"的差别全在松手那 150 毫秒的鼠标轨迹里。dsh-pet 会持续记录指针轨迹(只保留最近 200ms 的窗口),松手时按下述策略估算初速:
- 方向:取窗口内首末两点的位移方向,天然抗抖动
- 大小:端点平均速度 × 50% + 窗口内分段峰值速度 × 50% 加权——快甩时位移集中在窗口一小段,只看端点会低估
- 加速度加成:如果末段还在加速(越甩越快),最多再放大 60%
- 软上限:速度按
3600×(1-e^(-v/3600))软钳位——再大的力气也飞不出去,且力度始终单调可区分 - 死区判定:估算速度 < 500px/s 或松手前停顿了 150ms 以上 = "温柔放下",原地停住,不抛
核心函数estimateReleaseVelocity见 physics.ts,参数含义一目了然:
| 常量 | 值 | 作用 |
|---|---|---|
DEAD_ZONE_SPEED | 500 px/s | 低于此速度 = 放下,不抛 |
MAX_THROW_SPEED | 3600 px/s | 甩出速度软上限 |
RELEASE_WINDOW_MS | 150 ms | 初速估算窗口 |
RELEASE_STALE_MS | 150 ms | 停顿超过它 = 温柔放下 |
🏀 重力、反弹与落地:单屏内的完整抛体循环
一旦初速越过死区,宠物就进入逐帧积分:每帧加重力、位移,再检查四个边。默认手感由 config.jsonc 的physics段驱动:
- 重力
gravity = 1400px/s²:数值越大落得越快;0= 无重力,宠物甩出后匀速直线飘,永不回落 - 恢复系数
restitution = 0.78:每次碰墙/碰地保留约 78% 的速度,所以反弹一帧比一帧弱,几秒内自然衰减 - 地面摩擦
groundFriction = 2.5/s:落地后水平速度按秒衰减,宠物贴地"滑"一小段才停稳,而不是原地急刹 - 顶部反弹
ceilingBounce = true:关掉后宠物可以飞出屏幕顶部,再靠重力落回来
积分与边界反弹在 throwStep。落地还有一层"灵魂"——Q 弹挤压(squash & stretch):落地冲击速度越大,身体压得越扁(轻落最多压到 0.8 倍高,重砸压到 0.55 倍),再用带 4% 过冲的回弹曲线弹回原形,见 landingSquash / squashScale。
🖥️ 多屏弹来弹去:能"穿"屏幕,又不飞进黑洞
多显示器下有个经典难题:如果把整个桌面按"外接矩形"当边界,宠物会飞进不属于任何显示器的空洞(实测一例右倒 T 型双屏,外接矩形 23.7% 的面积是空洞)——用户直接看不到宠物去哪了。
dsh-pet 的解法在 displays.ts 和 throwStepRegion 里,思路分三层:
- 边界逐屏取:宠物用"身体中心所在屏"的 AABB 当边界,而不是整个桌面
- 越界先探测:撞到某条边时,先往缝外第一像素探一下——那边有屏就原样放行(跨屏飞行),没屏才反弹。于是"屏缝当墙"只发生在真空洞处
- 无状态判定:放行时不记录"当前在几号屏",每帧都由身体中心重新定位——避免了骑缝宠物在两屏边界间逐帧对跳的抖动
细节上还有个坑:任务栏会挖掉屏缝处的一条工作区条带,所以邻屏探测用的是完整面板(含任务栏区),而反弹/休息线仍按工作区——脚不踩任务栏,但身体能跨过去。多屏几何工具(点在屏上?最近是哪块屏?)都收敛在 displays.ts。
🖥️ 桌面模式(透明置顶小窗)与浏览器形态共用同一份纯函数物理,跨屏弹跳手感严格一致;不想要跨屏?把 config.jsonc 的
confineToScreen设为true,屏缝即变墙,宠物只在本屏内弹。
🐾 进阶玩法:多宠物互撞与"点击积分"
多开宠物 + 抛掷引擎还能组合出更多物理玩法:
- 多宠物碰撞(
petCollision: true,默认关):飞行中的宠物撞到别的宠物,按动量守恒 + 恢复系数 0.995(近乎完全弹性)弹开,质量 ∝ 大小的平方——大宠物把小宠物撞飞得明显更猛,被撞方从落点以新初速继续抛。核心公式在 collidePet - 点击积分:飞行中的宠物被快速点中(速度 ≥ 400px/s),点击处爆粒子 + 弹积分卡——越快、宠物越小,分数越高(小目标更难命中,奖励更高)
⚙️ 手把手调参:把你的桌宠调得更"弹"
所有物理手感集中在physics段(全局默认,所有宠物共用),README 配置表 有完整说明:
| 参数 | 默认 | 调大的效果 | 调小 / 关闭 |
|---|---|---|---|
gravity | 1400 | 落得更快、砸得更狠 | 0= 无重力漂浮 |
restitution | 0.78 | 弹得更久(1= 完全弹性,永不衰减) | 接近0= 撞上即停 |
groundFriction | 2.5 | 落地很快停稳 | 0= 冰面,一直滑 |
throwPower | 1.0 | 跟手更贴、甩得更猛 | < 1 = 松弛、更易温柔放下 |
ceilingBounce | true | — | 关掉 = 可飞出屏幕顶部 |
petCollision | false | — | 开 = 宠物互撞弹开 |
两个入口任选:DSH 设置页「桌宠配置 → 物理」区图形化编辑(保存即时生效),或直接改$DSH_HOME/dsh-pet/main-config.jsonc后刷新。想魔改更细的弹簧刚度、软上限等内部常量,看 physics.ts 头部注释——每个常量都写清了取值依据。
📌 小结:一套纯函数,两种外壳,一种手感
dsh-pet 抛掷引擎的可读性来自一条纪律:物理是纯计算,不含任何 DOM / 定时器。同一份 physics.ts 被浏览器(React)和桌面(Electron 纯 DOM)两个渲染壳共用,移动几何在 motion.ts 里同样纯函数化——所以无论宠物住在网页里还是透明小窗中,甩出去的手感逐位一致。理解了"弹簧跟手 → 轨迹估速 → 逐屏积分 → 落地 Q 弹"这四段,你就掌握了整套拖拽抛掷物理引擎的骨架;剩下的,就是把restitution调到 0.95,看它在屏幕间弹满三遍 🏀
- AI 插件
- dsh-plugin
- 交互助手
- 桌面应用
【免费下载链接】dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI 视频自造专属宠物
相关推荐
2024年必知的广播技术趋势:Awesome Broadcasting核心功能解析
2024年必知的广播技术趋势:Awesome Broadcasting核心功能解析 广播技术正在经历数字化转型的关键时期, Awesome Broadcasti
彻底解决弹幕刷屏!Jellyfin弹幕插件重复过滤机制深度解析
彻底解决弹幕刷屏!Jellyfin弹幕插件重复过滤机制深度解析 你是否还在为视频播放时弹幕重叠、刷屏导致观看体验下降而烦恼?作为开源媒体中心Jellyfin的核
终极指南:如何使用DanmakuFlameMaster实现高效的Android弹幕交互功能
终极指南:如何使用DanmakuFlameMaster实现高效的Android弹幕交互功能 DanmakuFlameMaster是一款强大的Android开源弹
移动开发音视频
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考