游戏开发【免费下载链接】planck.js2D JavaScript Physics Engine项目地址https://gitcode.com/gh_mirrors/pl/planck.js点击查看免费下载planck.js 是一个以 TypeScript/JavaScript 实现的 2D 物理引擎MIT 协议源自 Box2D 的跨平台 HTML5 游戏开发移植。本文以仓库根目录的 CHANGES.md 变更记录为主线逐版还原 0.1 → 0.2 → 1.0.0 → 1.1.0 的演进脉络并结合 src、vite.config.mts 等源码证据解读每一次重构背后的设计动机与 API 迁移方式帮助读者理解当前引擎的模块结构、事件系统与命名规范并掌握从旧版 API 升级到新版的关键对照。版本演进总览当前仓库 package.json 版本为 1.5.0而 CHANGES.md 记录了从早期移植到现代化重构的四个关键阶段版本核心变化性质0.1目录重排、类合并、标志位改布尔字段、事件系统引入大范围架构重构0.2TypeScript 定义加入、向量组合运算 API 重命名、关节构造器清理API 命名规范化1.0.0全量 TypeScript 迁移、性能优化语言与运行时升级1.1.0Vite 构建迁移工程化升级从变更记录看planck.js 的演进方向非常清晰先是内部架构去 Box2D 化0.1再是公开 API 规范化0.2随后是类型系统与构建工具链的现代化1.0.0 / 1.1.0。0.1架构重构——从忠实移植到JavaScript 原生0.1 是信息量最大的一次版本几乎重写了整个引擎的组织方式。以下按主题分组解读。目录结构与文件组织source code directory layout changed, classes moved around!从当前仓库的目录布局可以反推这次调整的结果物理与碰撞基础类型集中在 src/commonVec2、Vec3、Mat22、Mat33、Rot、Transform、Sweep、Jacobian等碰撞算法集中在 src/collisionAABB、BroadPhase、DynamicTree、Distance、Manifold、Shape、TimeOfImpact形状实现在 src/collision/shapeCircleShape、EdgeShape、PolygonShape、ChainShape、BoxShape及各Collide*配对碰撞函数动力学与求解器集中在 src/dynamicsBody、Fixture、Contact、Joint、World、Solver关节实现位于 src/dynamics/joint。b2Class renamed to Class早期版本中所有类都继承自一个b2Class基类0.1 起统一改名为Class。当前源码中已完全搜不到b2Class或GrowableStack的痕迹说明这两项已彻底移除。Dumping is removed, Drawing is moved to testbed序列化/反序列化能力被拆分场景dump功能被移除绘图相关能力移入 testbed即planck-with-testbed构建产物见 vite.config.mts 的buildTestbed分支。这也解释了package.json中./with-testbed导出子路径的存在——核心引擎与可视化测试台被明确解耦。GrowableStack replaced with native array, Timer is changedBox2D 风格的自增长栈数据结构被原生数组取代计时器改为基于Date.now()的轻量实现见 src/util/Timer.tsnow()直接返回Date.now()diff(time)计算差值。数学与几何 API 拆分Math is changed and splitVec2.Min/Max renamed to Vec2.Upper/Lower and several other methods added数学工具被拆分到多个文件Vec2、Vec3、Mat22、Mat33、Rot、Transform、Sweep等见 src/common同时Vec2.Min/Max更名为Vec2.Upper/Lower并补充了若干新方法。当前 Vec2.ts 中可以看到大量以matrix.*前缀出现的内部向量运算辅助以及setVec2、add、setCombine、addCombine、subCombine、setMul、addMul、subMul等方法见 Vec2.ts。TestOverlap moved from Collision to DistancetestOverlap从 Collision 模块移入 Distance 模块当前位于 src/collision/Distance.ts它通过设置input.useRadii true调用Distance算法计算两形状最近距离并以output.distance 10.0 * EPSILON判定是否重叠。同时 Distance.ts 保留了 legacy 导出Distance.testOverlap、Distance.Input、Distance.Output、Distance.Proxy、Distance.Cache方便旧代码平滑迁移Distance.ts。Distance method, DistanceInput/Output and SimplexCache merged into a stateful Distance class原独立的Distance函数、DistanceInput、DistanceOutput、SimplexCache被合并进一个有状态的 Distance 模块。当前 Distance.ts 中DistanceInput、DistanceOutput、SimplexCache仍作为独立类存在分别见 Distance.ts、Distance.ts、Distance.ts但Distance本体变成了可复用的函数式接口配合模块级复用对象simplex、output、cache等减少 GC 压力内部统计stats.gjkCalls、stats.gjkIters也可用于基准测试Distance.ts。Shape.computeDistanceProxy is added形状基类Shape新增抽象方法computeDistanceProxysrc/collision/Shape.ts各形状CircleShape、EdgeShape、PolygonShape、ChainShape分别实现为 GJK 距离算法提供支持点查询代理。Distance内部通过shape.computeDistanceProxy(this, index)装载代理Distance.ts。接触与碰撞架构合并Contact and Collide classes merged, Contact registration/creation is changedContactSolver/VelocityConstraint/PositionConstraint merged with ContactContactManager/ContactListener merged into World (and Contact)这三条变更合起来看原先分散的碰撞、求解、管理职责被压缩。当前 src/dynamics/Contact.ts 一个文件内同时包含VelocityConstraintPoint、速度约束求解initVelocityConstraint、solveVelocityConstraint与位置约束求解solvePositionConstraint、solvePositionConstraintTOI即旧版ContactSolver/VelocityConstraint/PositionConstraint的逻辑已被合并进 Contact 类。而ContactManager/ContactListener的职责则并入 src/dynamics/World.ts 与 Contact。Manifold files is added, WorldManifold.Initialize moved to Manifold.getWorldManifold新增独立的 src/collision/Manifold.ts原WorldManifold.Initialize变为Manifold.getWorldManifold。该方法接收世界变换与形状半径将局部流形换算为世界坐标下的法线、接触点与分离距离见 Manifold.ts并处理e_circles、e_faceA、e_faceB三种流形类型。Manifold.ts 还静态导出clipSegmentToLine、ClipVertex、getPointStates、PointStateManifold.ts。ContactFilter.ShouldCollide moved to Fixture?碰撞过滤判定下沉到 Fixture 层与 Fixture 的过滤数据group、categoryBits、maskBits耦合更紧密。碰撞配对阶段仍由 BroadPhase 的updatePairs驱动src/collision/BroadPhase.ts测试见 src/test/Collision.test.ts。求解流程重组Island/World.Solve/SolveTOI moved to new SolverPosition/Velocity correction objects assigned to owner bodies孤岛Island管理与世界级求解含 TOI 连续碰撞求解被移入新的 src/dynamics/Solver.ts其中定义TimeStep、ContactImpulse等求解输入输出类型位置/速度矫正对象则归属到各自的 Body 上消除了大量临时对象传递。二进制标志位 → 布尔字段binary flags changes to boolean fields (awakeFlag, autoSleepFlag, bulletFlag, fixedRotationFlag, activeFlag, enabledFlag, islandFlag, touchingFlag, filterFlag, bulletHitFlag, toiFlag, clearForces, newFixture, locked)这是最影响内部实现的一处改动原本用单个整数按位存储的十几个状态标志全部改为独立的布尔字段。好处是代码可读性与调试友好度大幅提升代价是需要逐一核对语义迁移。以 src/dynamics/Body.ts 为例当前可见m_bulletFlag、m_autoSleepFlag、m_awakeFlag、m_activeFlag、m_fixedRotationFlag等字段并通过isBullet/setBulletBody.ts、isSleepingAllowed/setSleepingAllowedBody.ts、isAwake/setAwakeBody.ts、isActive/setActiveBody.ts、isFixedRotation/setFixedRotationBody.ts成对暴露。字符串类型系统Body.Is[Type]/Set[Type] addedShape, Body and Joint string types (circle, dynamic, mouse-joint, etc.)引擎从数值枚举走向字符串类型标识这是一次面向开发者的重大 API 变更形状类型ShapeType circle | edge | polygon | chainsrc/collision/Shape.tsgetType()返回对应字符串刚体类型BodyType static | kinematic | dynamicsrc/dynamics/Body.ts并同时保留Body.STATIC/KINEMATIC/DYNAMIC静态常量与setStatic/setDynamic/setKinematic/setType/getType系列方法Body.ts关节类型DistanceJoint、FrictionJoint、GearJoint、MotorJoint、MouseJoint、PrismaticJoint、PulleyJoint、RevoluteJoint、RopeJoint、WeldJoint、WheelJoint各自定义static TYPE如distance-jointDistanceJoint.ts、mouse-jointMouseJoint.ts、wheel-jointWheelJoint.ts等Joint.getType()返回该字符串Joint.ts。字符串类型的价值在于序列化、调试输出、以及testbed的 UI 展示关节样式匹配、形状渲染分支都可以直接以可读字符串为键无需维护枚举 ↔ 字符串的映射表。测试中可直接断言b1.getFixtureList().getType() circlesrc/test/Basic.test.ts。世界监听器 → 事件系统World listeners changed to events: PostSolve, PreSolve, EndContact, BeginContact, SayGoodby to post-solve, pre-solve, end-contact, begin-contact, remove-body, remove-joint, remove-fixture这是 0.1 中最具代表性的公开 API 变更从接口式监听器转向事件发布/订阅。当前World以on(name, listener)/off(name, listener)/publish(name, ...)三件套实现事件机制src/dynamics/World.ts支持的事件包括事件名回调参数触发时机begin-contact(contact)两个 fixture 开始接触World.tsend-contact(contact)两个 fixture 停止接触World.tspre-solve(contact, oldManifold)接触更新后、进入求解器前可修改流形或禁用接触World.tspost-solve(contact, impulse)求解完成后用于读取冲量World.tsremove-body/remove-joint/remove-fixture(body)/(joint)/(fixture)对应实体被显式或隐式移除时World.ts此外还扩展了add-body、add-joint、add-fixture三个新增事件World.ts。事件发布点在 Contact 与 World 内部如beginContact/endContact/preSolve/postSolve均通过this.publish(...)触发World.ts。官方文档注明这些回调中不能创建/销毁世界实体World.ts且同一时间步内同一接触可能收到多次回调。回调类 → 函数Callbacks classes changed to functions: DynamicTree.query DynamicTree.rayCast BroadPhase.updatePairs BroadPhase.rayCast BroadPhase.query World.queryAAB World.rayCastBox2D 中以回调对象 虚方法实现查询的方式被替换为纯函数回调DynamicTree.query(aabb, callback)与DynamicTree.rayCast(input, callback)src/collision/DynamicTree.tsBroadPhase.query、BroadPhase.rayCast、BroadPhase.updatePairs(addPairCallback)src/collision/BroadPhase.tsWorld.queryAABB(aabb, callback)src/dynamics/World.ts与World.rayCast(point1, point2, callback)World.ts回调返回false可提前终止 AABB 查询rayCast 回调返回数值可控制射线maxFraction的收缩。0.2API 命名规范化与 TypeScript 定义向量组合运算重命名wSet/wAdd/wSub(a, v, b, w) replaced with combine/setCombine/addCombine/subCombine(a, v, b, w)wSet/wAdd/wSub(a, v) replaced with mul/setMul/addMul/subMul(a, v)Vec2的加权赋值方法从带w前缀的模糊命名改为语义明确的组合运算命名。旧方法在 Vec2.ts 中仍保留但标记deprecated并内部委托给新方法wSet(a, v, b, w)→setCombine(a, v, b, w)语义为this a*v b*wwSet(a, v)→setMul(a, v)语义为this a*vVec2.tswAdd→addCombine/addMul语义为this a*v ( b*w)Vec2.tswSub→subCombine/subMul语义为this - a*v ( b*w)Vec2.ts。注意setCombine的注释特别说明this可能即是w// this may be w因此实现先计算局部变量再赋值避免别名冲突——这是向量库常见的坑。此外Vec2.combine(a, v, b, w)静态方法也基于setCombine实现Vec2.ts。关节构造器清理Joints constructors cleanupTypeScript definitions added各关节构造器从需要显式传入大量参数改为统一的definition 对象 可选 bodyA/bodyB风格例如 Joint.ts 支持两种构造形式new Joint(def)或new Joint(def, bodyA, bodyB)其中bodyA可从def.bodyA解出。这一约定配合0.2引入的 TypeScript 定义文件让关节创建更类型安全、更易读。1.0.0全量 TypeScript 迁移与性能优化Typescript migrationPerformance improvements1.0.0 将引擎主体含测试从 JavaScript 全面迁移到 TypeScript。当前仓库结构可见完整证据源码全部为.ts文件src 下的*.ts、测试使用 Vitest*.test.ts位于 src/test与 src/serializer/test、类型测试使用tsdtest-d/planck.test-d.ts。性能优化方面从代码结构可以推断几个方向对象复用/池化模块级复用DistanceOutput、SimplexCache、Simplex等对象[Distance.ts](https://link.gitcode.com/i/397dcbd86cb532fc38a5bf147b3c63f4#L740Vec2、Mat22等临时对象通过内部matrix.*工具复用src/util/Pool.ts 提供对象池构建期常量折叠ASSERT、_ASSERT、CONSTRUCTOR_FACTORY在构建时通过 Vitedefine替换为false/truevite.config.mts运行时断言在生产构建中被移除统计埋点stats.gjkCalls、stats.gjkIters等计数器Distance.ts服务于 benchmark 基准测试npm run benchmark会结合 Git 提交信息对比性能见 package.json。1.1.0Vite 构建迁移Vite build migration构建工具链统一迁移到 Vite由 vite.config.mts 完成以下工作双产物构建核心引擎planck入口 src/main.ts与可视化测试台planck-with-testbed入口 testbed/main.ts分别打包vite.config.mts同时输出 ES.mjs与 UMD.js两种格式vite.config.mts类型声明打包通过vite-plugin-dts-bundle-generator生成planck.d.tsvite.config.mts供package.json的exports字段分发package.jsonLicense 注入rollup-plugin-license在每个构建产物头部注入 MIT License 横幅vite.config.mts压缩产物npm run build额外用 terser 生成planck.min.js与planck-with-testbed.min.jspackage.json分别提供给 jsDelivr/unpkg CDN 使用package.json。从 1.1.0 起npm run dev/npm run testbed启动 Vite 开发服务器并加载 testbed 交互式测试台npm run test运行 Vitest 测试npm run docs:dev基于 Vitepress 预览 docs 文档站package.json。从 0.x 迁移到当前版本的快速对照综合 0.1 与 0.2 的破坏性变更整理出面向升级者的核心对照表旧写法0.x新写法当前依据Vec2.wSet(a, v, b, w)vec.setCombine(a, v, b, w)Vec2.tsVec2.wAdd(a, v)vec.addMul(a, v)Vec2.tsVec2.wSub(a, v, b, w)vec.subCombine(a, v, b, w)Vec2.tsVec2.Min/MaxVec2.Upper/LowerCHANGES.md 0.1 条目数值类型枚举字符串类型circle、dynamic、mouse-joint等Shape.ts、Body.ts、MouseJoint.tsWorldManifold.Initialize(...)manifold.getWorldManifold(wm, xfA, radiusA, xfB, radiusB)Manifold.ts二进制标志位布尔字段 isXxx/setXxxBody.ts监听器接口BeginContact、SayGoodbye等事件world.on(begin-contact, ...)、world.on(remove-body, ...)World.ts回调对象函数回调world.queryAABB(aabb, cb)、world.rayCast(p1, p2, cb)World.ts、World.ts关节多参数构造定义对象构造new RevoluteJoint({...}, bodyA, bodyB)Joint.ts延伸阅读CHANGELOG.md更细粒度的逐版本变更说明docs/core-concepts.md 与 docs/world/simulation.md理解 World 事件与求解流程的使用语境src/dynamics/World.ts 与 src/common/Vec2.ts事件系统与向量 API 的第一手实现example 目录下的 60 个示例如Breakable.ts、Pinball.ts、RayCast.ts新 API 的实际调用范式vite.config.mts 与 package.json构建与发布产物全貌。赞分享游戏开发【免费下载链接】planck.js2D JavaScript Physics Engine项目地址https://gitcode.com/gh_mirrors/pl/planck.js点击查看免费下载相关推荐Qlib 版本演进全解析从 0.1.0 到 0.8.0 的架构变迁与技术脉络Qlib 版本演进全解析从 0.1.0 到 0.8.0 的架构变迁与技术脉络 Qlib 是一款面向 AI 量化研究的开源平台其核心代码自 0.1.0 起步金融科技人工智能机器学习数据分析强化学习VCMI 引擎版本演进全解析从 1.8.0 开发版到 0.x 时代的完整技术变更脉络VCMI 引擎版本演进全解析从 1.8.0 开发版到 0.x 时代的完整技术变更脉络 本文以仓库根目录的 ChangeLog.md https://link.游戏开发flow-for-vscode 版本演进全景解析从 LSP 迁移、安全加固到 TypeScript 重写的完整技术脉络flow for vscode 版本演进全景解析从 LSP 迁移、安全加固到 TypeScript 重写的完整技术脉络 Flow 是 JavaScript 的开发工具静态分析代码质量上一篇手机号找回QQ号码Python工具如何帮你3分钟搞定账号关联验证下一篇超越传统OCRPaddleOCR-VL-1.6-4bit如何处理倾斜文档、表格和多语言内容创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考