本指南讨论如何在 Corona 应用中设置 Box2D 物理引擎。物理引擎通常用于模拟物体在各种物理力(如重力)作用下的移动、碰撞和相互作用的应用。
即使您以前从未使用过物理引擎,Corona 也能让您轻松地在应用中添加物理效果。虽然底层引擎是围绕流行的 Box2D 构建的,但我们采用了一种不同的设计方法,消除了传统上所需的大量编码。
要使用 Corona 物理引擎,只需从熟悉的 Corona 显示对象 开始。Corona 将物理体属性视为其图形对象的扩展:任何标准显示对象,包括图像、矢量对象或动画精灵,都可以“赋予物理特性”,它们将自动与模拟中的其他对象交互。
请注意,Corona 会在其熟悉的屏幕单位和物理模拟的内部公制单位之间自动转换。所有位置值都以像素表示,并在内部以默认比例 30 像素/米转换为米。为了进一步保持一致性,所有角度值都以度数而不是弧度表示,并且位置 (0,0)
仍然位于内容区域的左上角。
要开始使用物理引擎,您必须引入库。以下代码行使物理引擎在 physics
命名空间下可用
local physics = require( "physics" )
以下函数用于启动、暂停和停止物理模拟
physics.start() — 实例化或恢复(如果已暂停)模拟。在调用本指南中的任何其他物理函数之前,您**必须**启动物理模拟。
physics.pause() — 暂停物理模拟。
physics.stop() — 这被视为“销毁”物理世界的请求。如果您只想暂停物理引擎,请使用 physics.pause()。
physics.start() -- Do this before any other physics call(s) physics.pause() physics.stop()
在使用 Corona 显示组 和 Box2D 时,务必记住 Box2D 要求所有物理对象共享一个**全局坐标系**。分组和未分组的显示对象都可以正常工作,因为它们将共享该组的内部坐标。但是,如果将物理对象添加到不同的显示组,并且这些组彼此独立地移动、缩放或旋转,则会出现意外结果。作为一般规则,**不要**更改包含物理对象的显示组的位置、比例或旋转。请参阅 物理引擎注意事项/限制
默认情况下,未参与碰撞的物理体会“休眠”几秒钟。这会降低性能开销,但在某些情况下,您可能不希望出现这种行为。在使用加速度计影响物理重力变化的应用中尤其如此——在这种情况下,休眠体不会响应重力方向的变化。
您可以使用 body.isSleepingAllowed = false
命令(参考)覆盖任何给定体上的此行为,或者使用 physics.start()
中的可选布尔参数全局覆盖世界中**所有**体的此行为
physics.start( true ) -- Prevent all bodies from sleeping physics.start( false ) -- Default behavior; bodies may sleep after a few seconds
物理引擎具有几个全局模拟选项。这些选项可用于对物理模拟进行微调,使其超出默认行为。
physics.setGravity() 设置全局重力矢量的 **x** 和 **y** 分量,单位为 m/s²。默认值为 ( 0, 9.8 )
,用于模拟标准地球重力,指向 **y** 轴的下方。
physics.setGravity( 0, 6 )
physics.setScale() 设置用于在屏幕 Corona 坐标和模拟物理坐标之间进行转换的内部像素/米比率。这应该只在实例化任何物理对象之前完成一次。
更改此值不会产生视觉上的后果——它只会影响物理模型的精度。Box2D 引擎经过调整,可模拟大小在 0.1 米到 10 米之间的中等大小物体,因此当游戏中的物体映射到大致落在此范围内的物理属性时,它效果最佳。
默认缩放值为 30
,这意味着最佳 0.1 米到 10 米范围对应于大小在 3 到 300 像素之间的可见对象。对于较大的对象,您可能希望将此值增加到 60
或更大。
physics.setScale( 60 )
如果要模拟的对象看起来太慢或反应太慢,您可能也希望增加此值。在这种情况下,它们可能太大太重,不适合您的目的——尝试提高缩放值和/或降低它们的密度。
physics.setDrawMode() 为物理引擎设置三种可能的“渲染模式”之一。虽然此功能可在设备上运行,但在调试意外的物理引擎行为时,它在 Corona 模拟器中最有用。
physics.setDrawMode( "hybrid" ) -- Overlays collision outlines on normal display objects physics.setDrawMode( "normal" ) -- The default Corona renderer, with no collision outlines physics.setDrawMode( "debug" ) -- Shows collision engine outlines only
物理数据使用彩色矢量图形显示,反映不同的对象类型和属性。有关详细信息,请参阅 物理体 指南。
physics.setPositionIterations() 设置引擎位置计算的精度。
physics.setPositionIterations( 6 )
默认值为 3
,这意味着引擎将为每个对象在每帧迭代八个位置近似值。增加此数字将减少瞬时误差(如对象重叠),但会增加计算开销。默认值应该适用于大多数一般情况。
physics.setVelocityIterations() 设置引擎速度计算的精度。
physics.setVelocityIterations( 16 )
默认值为 8
,这意味着引擎将为每个对象在每帧迭代三个速度近似值。增加此数字将减少瞬时误差(如对象重叠),但会增加计算开销。默认值应该适用于大多数一般情况。
physics.setContinuous() 控制是否启用连续物理。默认情况下,Box2D 执行连续碰撞检测,以防止对象“穿透”。如果关闭此功能,则快速移动的物体可能会穿过薄壁。
在某些复杂情况下,物体通过枢轴关节连接(例如,布娃娃),可能会发生不稳定性。一种解决方法是使用 physics.setVelocityIterations() 增加速度迭代次数。但是,这可能会导致计算成本高昂并降低帧速率。另一种解决方案是**禁用**连续物理
physics.setContinuous( false )
关闭它应该可以防止不稳定性,而无需增加迭代次数。但是,您需要使静态体额外厚,以防止穿透效应。
physics.setAverageCollisionPositions() 启用对物理体之间碰撞中所有接触点的平均化。由于 Box2D 通常会在单个帧迭代期间报告多个碰撞点,因此此设置对于将这些点报告为一个平均点非常有用。
physics.setAverageCollisionPositions( true )
physics.setReportCollisionsInContentCoordinates() 将内容原点设置为collision、preCollision 和postCollision 物理事件中的参考点。
physics.setReportCollisionsInContentCoordinates( true )
physics.setDebugErrorsEnabled() 允许 Box2D 捕获额外的物理错误。默认值为 `true`(启用)。
physics.setTimeStep() 指定基于帧(近似)的物理模拟或基于时间的模拟。
physics.setTimeStep( 0 ) -- Time-based physics simulation
physics.setMKS() 为特定键设置物理模拟的 MKS(米、千克和秒)值。这仅用于高级用途——普通开发人员和项目不需要此功能。