本指南讨论如何在 Corona 中配置各种可用的 Box2D 物理关节。
关节可用于将多个刚体组装成复杂的物理对象。例如,关节可用于连接布娃娃图形的肢体,将车辆的轮子连接到车身,创建移动的电梯平台等等。
大多数关节用于连接两个刚性物理体,因此您必须首先创建这些物体,然后将它们作为参数提交给 physics.newJoint() 构造函数,以及其他根据关节类型而变化的属性(请参阅下面的详细信息)。
physics.newJoint( jointType, ... )
如果不再需要关节,您可以通过调用 object:removeSelf() 或 display.remove() 来销毁它。
joint:removeSelf()
display.remove( joint )
如果其中一个连接体被销毁,则关联的关节将被自动销毁。但是,请记住要正确移除并 将已销毁关节的任何引用设置为 `nil`。
枢轴关节,在 Box2D 术语中称为**旋转**关节,将两个物体连接在一个重叠点,就像两块木板由一个旋转的钉子连接在一起。初始参数是要连接的物体 `A` 和 `B`,然后是锚点的 **x** 和 **y** 坐标,以内容空间坐标声明。
local pivotJoint = physics.newJoint( "pivot", bodyA, bodyB, anchor_x, anchor_y )
如果您正在使用枢轴关节构建复杂的组件(如布娃娃),并且遇到不稳定性问题,请考虑将 physics.setContinuous() 设置为 `true`。
可选地,可以通过关节马达驱动(旋转)通过枢轴关节与对象 `A` 连接的对象 `B`。这种旋转可以是顺时针或
pivotJoint.isMotorEnabled — 必须将其设置为 `true` 才能在枢轴关节上启用任何马达动作。
pivotJoint.motorSpeed — 此数字值指定预期的旋转马达速度。
pivotJoint.maxMotorTorque — 此数字值指定关节马达允许的最大扭矩。
pivotJoint.motorTorque — 只读数字值,指示当前马达扭矩。
可以选择限制枢轴关节的旋转范围。例如,如果构造一个布娃娃图形,则头/颈关节的顺时针或
pivotJoint.isLimitEnabled — 将此设置为 `true` 可约束枢轴关节的旋转限制。
pivotJoint:setRotationLimits() — 接受两个值(以度为单位)的函数,定义旋转的负限制和正限制。例如,如果您想相对于向上轴(`0`)稍微严格地限制旋转,则这些值可以分别为 `-10` 和 `10`。请注意,这些值仍然与物体 `A` 的旋转相关,这意味着如果物体 `A` 在声明关节后旋转,则这些旋转限制将与该物体的旋转保持同步。
pivotJoint.isLimitEnabled = true pivotJoint:setRotationLimits( -20, 20 )
local negLimit, posLimit = pivotJoint:getRotationLimits() print( negLimit, posLimit )
pivotJoint.jointAngle — 只读数字值,指示枢轴关节的当前角度(以度为单位)。
pivotJoint.jointSpeed — 只读数字值,指示枢轴关节的当前旋转速度。
pivotJoint.referenceAngle — 只读数字值,指示创建时物体之间的关节角度。
距离关节将两个物体连接在固定距离处。初始参数是要连接的物体 `A` 和 `B`,然后是每个物体的 **x** 和 **y** 锚点坐标,以内容空间坐标声明。
local distanceJoint = physics.newJoint( "distance", bodyA, bodyB, anchorA_x, anchorA_y, anchorB_x, anchorB_y )
可选地,可以将距离关节设置为软连接,例如
distanceJoint.dampingRatio — 此数字值的范围可以从 `0`(无阻尼)到 `1`(临界阻尼)。使用临界阻尼,所有振荡都应消失。
distanceJoint.frequency — 此数字指定
distanceJoint.length — 此数字指定锚点之间的距离,该距离不应为零或非常短。如果您在应用距离关节之前定位物体,则此长度将自动设置为锚点之间的距离,因此通常不需要设置此参数。
活塞关节,在 Box2D 术语中称为**棱柱**关节,沿着单个受限运动轴连接两个物体,例如发动机活塞或仅限于沿垂直轴运动的电梯平台。初始参数是要连接的物体 `A` 和 `B`,然后是每个物体上锚点的 **x** 和 **y** 坐标,再然后是定义允许线性运动的轴的值。
local pistonJoint = physics.newJoint( "piston", bodyA, bodyB, anchor_x, anchor_y, axisX, axisY )
如前所述,活塞关节的线性运动轴受限,由 `axisX` 和 `axisY` 定义。此轴可以被视为一个方向向量,指示当由正 pistonJoint.motorSpeed 值驱动时对象将移动的方向。
下表提供了 `axisX`、`axisY` 和**正**马达速度之间关系的示例。但是,`axisX` 和 `axisY` 值都可以是介于 `-1.0` 和 `1.0` 之间的十进制值 — 您不限于这八个方向。
axisX | axisY | |
---|---|---|
0 |
-1 |
上 / 0° |
1 |
-1 |
右上 / 45° |
1 |
0 |
右 / 90° |
1 |
1 |
右下 / 135° |
0 |
1 |
下 / 180° |
-1 |
1 |
左下 / 225° |
-1 |
0 |
左 / 270° |
-1 |
-1 |
左上 / 315° |
要限制沿线性轴任一方向的运动距离,请使用 pistonJoint:setLimits() 函数,如下所示。
运动速度不受轴值控制,而是由 pistonJoint.motorSpeed 属性控制,如下一节所述。
负马达速度将使对象沿其定义的轴向量的相反方向移动。
可选地,可以使用关节马达驱动活塞关节。与 枢轴 关节的旋转马达不同,此运动将是线性的,并沿定义的轴受限。例如,可以使用活塞关节马达来沿其轴上下移动电梯平台。
pistonJoint.isMotorEnabled — 必须将其设置为 `true` 才能在活塞关节上启用任何马达动作。
pistonJoint.motorSpeed — 此数字值指定预期的线性马达速度。正马达速度将使对象沿其定义的轴向量方向移动,而负马达速度将使对象沿相反方向移动。
pistonJoint.maxMotorForce — 此数字值指定关节马达允许的最大力。
pistonJoint.motorForce — 只读数字值,指示当前马达力。
可以选择限制活塞关节的线性运动范围。限制采用下限和上限的形式,它们定义沿 `axisX` 和 `axisY` 定义的轴的运动范围(距离)。
pistonJoint.isLimitEnabled — 将此设置为 `true` 可限制活塞关节的运动范围。
pistonJoint:setLimits() — 此函数接受两个值,定义负运动范围和正运动范围。第二个值应始终大于或等于第一个值,因为它们定义沿轴的运动范围(距离)。
pistonJoint.isLimitEnabled = true pistonJoint:setLimits( -40, 120 )
local negLimit, posLimit = pistonJoint:getLimits() print( negLimit, posLimit )
pistonJoint:getLocalAxisA() — 此函数返回沿定义的轴的锚点在内容空间中的当前坐标。
pistonJoint.jointTranslation — 只读数字值,指示活塞关节的当前平移,即沿轴发生的运动距离。
pistonJoint.jointSpeed — 只读数字值,指示活塞关节的当前线性运动速度。
pistonJoint.referenceAngle — 只读数字值,指示创建时物体之间的关节角度。
摩擦关节用于模拟A
和 B
,然后是锚点的 x 和 y 坐标。
local frictionJoint = physics.newJoint( "friction", bodyA, bodyB, anchor_x, anchor_y )
创建摩擦关节时,可以通过最大力和扭矩值来应用模拟摩擦
frictionJoint.maxForce — 此 数字 指定可以应用于连接体的最大方向摩擦力。值越高,模拟的摩擦力越大。
frictionJoint.maxTorque — 此 数字 指定可以应用于连接体的最大旋转摩擦力。值越高,模拟的摩擦力越大。
焊接关节将两个物体牢固地连接在内容空间坐标中指定的锚点处。
local weldJoint = physics.newJoint( "weld", bodyA, bodyB, anchor_x, anchor_y )
由于数学近似,即使设置了 dampingRatio
和 frequency
来防止这种行为,该关节在模拟过程中也可能显得略微柔软。如果您想组装多个形状而没有任何弯曲的风险,请考虑创建一个
weldJoint.dampingRatio — 此 数字 值的范围可以从 0
(无阻尼)到 1
(临界阻尼)。使用临界阻尼,所有振荡都应消失。
weldJoint.frequency — 此 数字 值指定
请注意,图中两个物体不必重叠,并且关节锚点不必位于其中一个物体内部。实际上,这两个物体可以完全分开,焊接关节仍然会将它们连接在一起,就像它们之间存在一个刚性的、不可见的链接一样。
轮关节,在 Box2D 术语中称为**线**关节,类似于活塞关节,不同之处在于连接的物体可以像安装在汽车减震器上的车轮一样自由旋转。它的大部分属性都继承自标准活塞关节,但您可以指定A
和 B
,然后是任一物体上锚点的 x 和 y 坐标,然后是定义允许线性运动轴的值。
local wheelJoint = physics.newJoint( "wheel", bodyA, bodyB, anchor_x, anchor_y, axisX, axisY )
与活塞关节一样,轮关节的线性运动轴受到限制,由 axisX
和 axisY
定义。但是,与活塞关节不同,轮关节不受电机驱动,因此您不能发送车轮B
)0,1
或 0,-1
会将运动限制在垂直轴上,但不会将其限制在沿该轴向上**或**向下。类似地,1,0
或 -1,0
的值会将线性运动限制在水平轴上的左**或**右。
本质上,车轮——或者更确切地说是代表车轮的物体——容易受到任何可能作用在其上的力,例如重力。该物体将尝试保持在定义的轴上,但其他力可能会以不可预测的方式将车轮拉/推离该轴。
或者,可以使轮关节变软,例如
wheelJoint.springDampingRatio — 此 数字 值的范围可以从 0
(无阻尼)到 1
(临界阻尼)。使用临界阻尼,所有振荡都应消失。
wheelJoint.springFrequency — 此 数字 值指定0
。
wheelJoint:getLocalAxisA() — 此函数返回沿定义轴的锚点在内容空间中的当前坐标。
wheelJoint.jointTranslation — 只读 数字 值,指示轮关节的当前平移,即沿轴发生的移动距离。
wheelJoint.jointSpeed — 只读 数字 值,指示轮关节当前的线性移动速度。
滑轮关节用一根长度保持不变的假想绳索连接两个物体。如果一个物体被某种力拉动或推动,另一个物体将根据模拟的绳索进行补偿。初始参数是要连接的物体 A
和 B
,然后是两个坐标对,它们表示绳索两侧悬挂的固定锚点。接下来的四个参数是 x 和 y 锚点坐标ratio
值,可以调整该值来模拟滑轮组设置。
local pulleyJoint = physics.newJoint( "pulley", bodyA, bodyB, statA_x, statA_y, statB_x, statB_y, bodyA_x, bodyA_y, bodyB_x, bodyB_y, 1.0 )
滑轮关节的构造函数中将 ratio
属性作为最后一个参数。可以调整此比率以模拟滑轮组装置。在这种情况下,滑轮绳的一侧移动速度比另一侧快。默认比率为 1.0
,它模拟一个简单的滑轮。
pulleyJoint:getGroundAnchorA() — 此函数返回关节的第一个地面锚点在内容坐标中的 x 和 y 坐标。
pulleyJoint:getGroundAnchorB() — 此函数返回关节的第二个地面锚点在内容坐标中的 x 和 y 坐标。
pulleyJoint.length1 — 只读 数字 值,在实例化时,指示第一个关节锚点与其固定滑轮锚点之间的距离(以像素为单位)。
pulleyJoint.length2 — 只读 数字 值,在实例化时,指示第二个关节锚点与其固定滑轮锚点之间的距离(以像素为单位)。
触摸关节,在 Box2D 中称为**鼠标**关节,将单个物体连接到A
,后跟内容空间中的 x 和 y 锚点坐标。
local touchJoint = physics.newJoint( "touch", body, anchor_x, anchor_y )
对于触摸关节,锚点可以被认为是“连接”物体的点。例如,要通过其中心点连接物体,请将 body.x
和 body.y
指定为最后两个参数。或者,要通过触摸物体上的点来拖动物体,请使用触摸事件返回的 event.x
和 event.y
值。此锚点通常配置为物体边界内的点,但如果需要,它也可以位于边界之外。
请注意,通过触摸关节连接的物体仍在模拟中,因此它将与世界上的其他物体充分交互。此外,当通过
触摸关节的目标跟随行为是通过将 x 和 y 坐标传递给 touchJoint:setTarget() 函数来设置的
targetX
和 targetY
表示的点。这可以是任何特定的内容点、用户触摸的位置、要跟随的其他物体的坐标、沿路径的连续点等。touchJoint:setTarget( targetX, targetY )
touchJoint.dampingRatio — 此 数字 值的范围可以从 0
(无阻尼)到 1
(临界阻尼)。使用临界阻尼,所有振荡都应消失。
touchJoint.frequency — 此 数字 值指定
touchJoint.maxForce — 此 数字 值指定触摸关节的最大允许力。默认情况下,此属性是物体质量的 1000 倍,可以实现相当快速的目标跟随。
绳索关节通过理论上的A
和 B
,后跟可选的局部偏移点,可用于设置
local ropeJoint = physics.newJoint( "rope", bodyA, bodyB, offsetA_x, offsetA_y, offsetB_x, offsetB_y )
配置绳索关节时,偏移值是可选的,默认值为 0
,除非另有设置。与其他关节不同,这些 x 和 y 值不应在内容空间中指定。相反,它们应被视为与任一物体相关的局部偏移值。例如,如果您指定( ..., 0, 0, 0, 0 )
( ..., -20, -20, 10, 10 )
A
的绳索端将偏离其中心点左侧和上方 20 个像素,而连接到物体 B
的绳索端将偏离其中心点右侧和下方 10 个像素。
可以通过 ropeJoint.maxLength 属性设置绳索的最大长度。与可用于使两个物体保持固定距离的距离关节不同,理论上的绳索可以像实际绳索一样弯曲/弯曲,但最大距离将始终限制为此值。
"inactive"
、"lower"
、"upper"
或 "equal"
。要模拟涉及齿轮的复杂机械装置,请考虑使用齿轮关节。此关节可以将两个物体(或按顺序排列的多个物体)以
local gearJoint = physics.newJoint( "gear", bodyA, bodyB, joint1, joint2, ratio )
齿轮关节最重要的区别在于它直接作用于另外两个关节。必须先创建这两个关节,然后才能实例化齿轮关节,并且它们必须是枢轴关节或活塞关节。声明后,其中一个枢轴/活塞关节可以由其电机供电,并影响连接到父齿轮关节的另一个枢轴/活塞关节。相同的原理适用于更复杂链配置中的连续关节,假设它们通过其他齿轮关节正确地链接在一起。
始终在销毁关联的枢轴/活塞关节或其物体**之前**销毁齿轮关节。否则,由于孤立的齿轮关节指针,Box2D 可能会崩溃。
齿轮关节的另一个重要方面是 ratio
属性。这表示
1.0
,因为齿轮 B 直接驱动齿轮 C。但是,您必须计算连接齿轮 C 和垂直杆 (D
) 的齿轮关节的比率,并且由于齿轮 C 的周长大于齿轮 B,因此该比率不会是 1.0
。gearJoint.joint1 — 只读 用户数据 引用,指向与齿轮关节关联的第一个 枢轴 或 活塞 关节。
gearJoint.joint2 — 只读 用户数据 引用,指向与齿轮关节关联的第二个 枢轴 或 活塞 关节。