MoonBit 生态首个 2D 游戏物理引擎

MoonCollider

面向 MoonBit 的 2D 游戏物理与碰撞检测库。SAT 窄相、GJK+EPA 通用凸形碰撞、四种宽相加速结构、顺序冲量求解器、关节约束、CCD 连续碰撞检测——纯逻辑无渲染,跑遍 wasm-gc / js / native。

快速开始 查看源码
moon check 56/56 tests moon info moon fmt fuzz + 确定性快照
实时物理沙盒 · 由 MoonCollider 引擎驱动
拖拽物体抛掷 · 点击空白添加球/箱 · 切换模式 · 开关重力
4867
LOC 源代码
9+1
碰撞对(SAT + GJK)
4
宽相加速结构
56
测试全通过

为什么选择 MoonCollider?

从向量数学到刚体世界,一站式覆盖 2D 物理游戏的全部碰撞与模拟需求

📐

向量和形状

Vec2 全套运算;AABB / Circle / 凸多边形,支持凸包、正多边形、矩形构造器,Shape 枚举统一分发。

💥

SAT 窄相碰撞

全部 9 种形状对,分离轴定理求穿透法线和深度,2 点接触流形,含圆心在多边形内的退化处理。

🌀

GJK + EPA

通用凸形碰撞:GJK 迭代求单纯形,EPA 展开求最近穿透深度,任意 support 函数均可接入。

🔦

射线检测

Ray vs AABB / Circle / Polygon,返回参数化 t、命中点和表面法线,支持内外两面命中。

🗺️

四种宽相

GridHash 均匀网格、QuadTree 松散四叉树、SweepAndPrune 排序扫描、AABBTree 动态树(含增删改)。

⚙️

刚体求解器

顺序冲量法、Baumgarte 位置修正、库仑摩擦、2 点接触,velocity iterations 可调。

🔗

关节约束

Distance 距离关节、Revolute 旋转铰链、Weld 焊接关节,软 Baumgarte 偏置稳定收敛。

🎯

CCD 连续碰撞

扫描体求交,防止高速物体穿透薄墙,circle/AABB sweep 两种实现,可开关对比。

🛡️

对抗性 fuzz + 确定性

6 组 fuzzing(随机形状暴雨 / 退化几何 / NaN / 能量发散 / 穿模)+ 跨平台浮点快照,xorshift32 可复现。

核心架构

五层分层设计,每层可独立使用,也可从形状一路走到完整物理世界

World 求解层 — world.mbt
World::step 顺序冲量求解:力积分 → 宽相 → 窄相 → 接触约束 → 摩擦 → Baumgarte 位置修正
关节层 — joints.mbt
Distance / Revolute / Weld 三种约束,软 Baumgarte 偏置,与接触约束同帧求解
宽相层 — broadphase.mbt / broadphase_sap.mbt
GridHash / QuadTree / SweepAndPrune / AABBTree,候选对生成,O(n) 到 O(n log n)
窄相层 — narrowphase.mbt / gjk.mbt / raycast.mbt / ccd.mbt
SAT 9 对 + GJK/EPA 通用凸形 + 射线 + CCD 扫描,输出 Manifold(法线 / 深度 / 接触点)
基础层 — vec2.mbt / shape.mbt / body.mbt
Vec2 数学、AABB/Circle/Polygon 几何、RigidBody 刚体定义(质量 / 转动惯量 / 恢复系数 / 摩擦 / 阻尼)

快速开始

三行命令安装,十行代码跑起一个物理世界

bash安装
# 在你的 MoonBit 项目里
moon add uiwcvb/mooncollider
moonbit弹跳球:动态圆 + 静态地板
fn main {
  let world = @mooncollider.World::new()
  // 动态圆球
  let _ = world.add_body(
    @mooncollider.BodyDef::dynamic(
      @mooncollider.Vec2::new(0.0, 10.0),
      @mooncollider.Shape::from_circle(
        @mooncollider.Circle::new(@mooncollider.Vec2::zero(), 0.5)),
      1.0, 0.8))
  // 静态地板
  let _ = world.add_body(
    @mooncollider.BodyDef::static_(
      @mooncollider.Vec2::new(0.0, 0.0),
      @mooncollider.Shape::from_aabb(
        @mooncollider.AABB::from_min_max(
          @mooncollider.Vec2::new(-10.0, -1.0),
          @mooncollider.Vec2::new(10.0, 0.0)))))
  // 步进仿真
  for i = 0; i < 200; i = i + 1 {
    world.step(0.016)
  }
}
moonbit单独碰撞检测(不用 World)
let a = @mooncollider.Shape::from_aabb(
  @mooncollider.AABB::from_min_max(
    @mooncollider.Vec2::new(0.0, 0.0),
    @mooncollider.Vec2::new(2.0, 2.0)))
let b = @mooncollider.Shape::from_circle(
  @mooncollider.Circle::new(@mooncollider.Vec2::new(3.0, 1.0), 1.5))
let m = @mooncollider.collide(a, b)
if m.colliding() {
  // m.normal 从 a 指向 b,m.depth 是穿透深度
}

示例程序

7 个 demo 覆盖从基础碰撞到性能基准

moon run cmd/main
弹跳球:重力下动态圆球撞击地板反弹
moon run cmd/stacking
箱子堆叠:多刚体稳定堆叠,摩擦力生效
moon run cmd/raycast
射线场景:多条射线打向形状群,求交命中
moon run cmd/pendulum
距离关节钟摆:DistanceJoint 约束演示
moon run cmd/ccd_stress
CCD 穿模对比:100 u/s 小球撞薄墙,开关 CCD 对比
moon run cmd/perf
性能基准:narrowphase / broadphase / world step
moon run examples/pairs
批量碰撞查询:无 World 纯碰撞检测

性能基准

@bench 测量,100 轮取中位数(wasm-gc,本地环境)

场景规模中位耗时吞吐
Narrowphase 圆对碰撞1000 对~9 µs/op~110k ops/s
Broadphase GridHash500 体~200 µs/op~5k ops/s
World::step100 体~120 µs/op~8k steps/s

项目状态

竞赛验收硬性 + 软性要求全部通过

维度数据说明
源代码规模4867 LOC含库 + 测试 + 7 个 demo + 示例
窄相碰撞9 对 + GJK/EPASAT 多边形 + GJK 通用凸形
宽相加速4 种GridHash / QuadTree / SAP / AABBTree
刚体求解顺序冲量Baumgarte + 摩擦 + 2 点接触
关节约束3 种Distance / Revolute / Weld
CCD2 种 sweepCircle / AABB 连续碰撞
测试体系56 个测试blackbox + whitebox + fuzz + 确定性快照
moon check✓ 0 error编译检查通过
moon test✓ 56/56全部测试通过
moon info✓ clean diff接口文件与代码同步
moon fmt✓ clean diff格式化规范
编译目标wasm-gc可扩展 js / native
开源协议Apache-2.0商业友好