Skip to content

拆解六面骰子

VVE 自带的 vve_examples:dice_6 是理解刚体完整路径的好样本:它足够小,又同时涉及随机姿态、偏心冲量、八顶点碰撞、着陆规整、item display 和专用模拟器。

模块数据

默认 _class

mcfunction
function vve_examples:dice_6/_zero
execute positioned 0 0 0 rotated 0 0 as 0-0-0-0-0 run function vve:object/_anchor_to
scoreboard players set a int 2500
scoreboard players set mass int 17
scoreboard players set inertia int 500
function vve_examples:dice_6/_model
data modify storage vve_examples:class dice_6_plate set from storage vve_examples:io result

物理半边长是 0.25 格,显示缩放在 _update_display 中由 a × 0.0003 写入 transformation。这个系数是当前骰子资源模型与物理尺寸之间的映射,不是通用 VVE 常量。

_roll:从上下文创建运动

_roll 要求“世界实体执行者 + 执行位置 + 执行朝向”。它完成:

  1. dice_6_plate 创建 item display 实例;
  2. _get 读入新实例;
  3. _rand_quat 生成随机姿态;
  4. 从执行位置与朝向构造偏心冲量;
  5. vve:block/_apply_impulse 同时改变平动与转动;
  6. _store 写回;
  7. 注册销毁/点数输出回调。

使用专门 marker 作为投掷者,可避免内部 tp 影响玩家:

mcfunction
summon marker 0 106 -2 {Tags:["dice_thrower"]}
execute as @e[tag=dice_thrower,limit=1] at @s rotated 0 -25 anchored eyes positioned ^ ^ ^0.5 run function vve_examples:dice_6/_roll
kill @e[tag=dice_thrower]

main_c:一帧骰子物理

源码阶段依次是:

mcfunction
function vve_examples:dice_6/_get
execute as 0-0-0-0-0 run function vve:object/_iter_motion
execute as 0-0-0-0-0 run function vve:block/_iter_cpoints_c
scoreboard players operation vy int -= vve_gravity int
execute if score shift_response int matches 1 run function vve:object/_apply_shift
execute if score impulse_response int matches 1 run function vve:object/_apply_impulse_f
execute if score couple_response int matches 1 as 0-0-0-0-0 run function vve:object/_apply_couple
function vve:object/_apply_friction
# 支撑足够且法向速度足够小后进行姿态规整
function vve:object/_sync_motion
function vve_examples:dice_6/_store

_iter_cpoints_c 遍历 (±a,±a,±a),将偏心冲量拆成平动冲量和力偶矩。落地阶段通常会同时看到 shift、impulse、friction 与 grab-layer 信号。

专用模拟器

vve_examples:dice_simulator/main_loop 每个子步执行四类骰子的 main_c:d4、d6、d8、d12。它自己的 _consts 先恢复 VVE 默认值,再设置较高抓地/实心摩擦与反弹逆映射值。

如果项目只使用 d6,可以复制模拟器模板并只调度 d6,避免无意义遍历。不要直接修改 VVE 包内示例;在自己的命名空间生成模拟器模块。

点数如何得出

骰子姿态由局部坐标轴/四元数表示。点数读取函数根据哪一个本地面法向最朝上判定结果。这个过程依赖落地姿态已经稳定;若在高速旋转中调用,得到的只是当时“最朝上的面”,不是最终点数。

为什么落地会抖

常见原因不止一个:

  • 同一骰子被两条 tick 路径重复执行;
  • 支撑判定在阈值两侧来回切换;
  • 稳定标志确定后仍施加一次较大的 penetration shift;
  • 摩擦、冲量与 _regular 顺序不一致;
  • 物理已稳定,但 display interpolation 在旧/新变换之间重复重启。

本站实验包采用“稳定判定先于最终位移/冲量应用”的兼容覆盖,并在连续低速接触后冻结演示骰子。这是演示层策略,不改动 VVE 原数据包,也不应被误写成 VVE 3.0.1 通用静体 API。

骰子回归应该断言什么

不要断言每次随机投掷最终点数相同。应固定初始状态并检查性质:

  • 若干 tick 后 y 保持在地面接触范围;
  • vx/vy/vzangular_* 进入低速阈值;
  • 对象没有越过坐标安全边界;
  • 稳定后再推进若干 tick,状态变化仍在容差内;
  • display entity 存在且 transformation 有限;
  • 相同 seed/初态的 JVM 与 Web snapshot 一致。

首页 GIF 与在线实验正是这条路径的可视化结果。

VVE 由小豆 8593 开发;本站是面向学习与查阅的增强文档。