You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Pymunk Categories和Masks配置自定义碰撞规则

Pymunk ShapeFilter categories/mask 配置方法

核心逻辑

不用对位运算有畏难情绪,Chipmunk2D(Pymunk底层)的碰撞过滤规则非常直白,两个形状发生碰撞必须同时满足两个条件:

  1. 形状A的categories值 与 形状B的mask值 做按位与(&)运算结果不为0
  2. 形状B的categories值 与 形状A的mask值 做按位与(&)运算结果不为0

你可以把这套规则理解成双向白名单:

  • categories是形状自身的身份标签,为32位整数,每一位对应一个独立类别,日常开发只要给每类对象分配一个唯一的、仅单个二进制位为1的值即可(也就是2的整数次幂),最多支持32个独立类别,完全覆盖常规项目需求
  • mask是形状的碰撞许可名单,哪一类对应的二进制位设为1,就代表该形状认可对应类别的碰撞资格
  • 要给一个形状开放多个类别的碰撞权限,直接用按位或(|)把对应类别的值拼接起来即可

针对你当前场景的落地配置

第一步:先给场景内所有需要独立判定碰撞的对象分配唯一类别值,注意线段和末端圆形是两个独立形状,需要单独分配类别:

# 每个值的二进制仅一位为1,互不冲突
CAT_WALL = 1 << 0    # 墙体
CAT_ANCHOR = 1 << 1  # 墙体上的锚点
CAT_SEGMENT = 1 << 2 # 连接锚点的线段
CAT_CIRCLE = 1 << 3  # 线段末端的圆形
CAT_CART = 1 << 4    # 小车

第二步:对照你提出的碰撞规则,逐个给形状配置ShapeFilter即可,group参数保持默认0即可,不需要额外设置:

from pymunk import ShapeFilter

# 墙体:允许和小车、线段、末端圆形碰撞
wall_filter = ShapeFilter(
    categories=CAT_WALL,
    mask=CAT_CART | CAT_SEGMENT | CAT_CIRCLE
)

# 锚点:不与任何对象碰撞
anchor_filter = ShapeFilter(
    categories=CAT_ANCHOR,
    mask=0
)

# 线段:允许和墙体、小车碰撞
segment_filter = ShapeFilter(
    categories=CAT_SEGMENT,
    mask=CAT_WALL | CAT_CART
)

# 线段末端圆形:仅允许和墙体碰撞
end_circle_filter = ShapeFilter(
    categories=CAT_CIRCLE,
    mask=CAT_WALL
)

# 小车:仅允许和墙体、线段碰撞
cart_filter = ShapeFilter(
    categories=CAT_CART,
    mask=CAT_WALL | CAT_SEGMENT
)

规则校验

你可以直接套核心逻辑验证所有组合,不会出现规则外的碰撞:

  • 小车与末端圆形:小车mask仅包含墙体、线段,和圆形的categories做与运算结果为0,不碰撞
  • 线段与末端圆形:线段mask仅包含墙体、小车,和圆形的categories做与运算结果为0,不碰撞
  • 锚点与所有对象:锚点mask为0,和任何对象的categories做与运算结果都为0,无碰撞
  • 墙体与小车/线段/末端圆形、小车与线段:双向与运算结果均不为0,正常触发碰撞

常见注意事项

  • 普通场景下每个形状的categories仅设置自己对应的单个类别位即可,不要随意给categories叠加多个值,容易出现规则冲突
  • group参数优先级高于categories/mask规则,非必要不要设置非0的group值,避免规则被覆盖
  • 后续新增碰撞类别时,直接按1 << n的顺序往后递增值即可,不要复用已有类别的数值

内容的提问来源于stack exchange,提问作者Shark Coding

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 15:57:15