LiquidFun 粒子碰撞

本教程概述了如何处理 LiquidFun 粒子和 Box2D 刚体的碰撞。处理这些碰撞对于使用 LiquidFun 物理实现更全面和响应更快的场景至关重要。

如果您尚未阅读过 LiquidFun 基础 教程,请仔细阅读它以便了解 LiquidFun 系统的基础知识。

基本设置

在本教程中,我们至少需要创建一个 ParticleSystem 和其他一个可以与粒子碰撞的对象

local physics = require( "physics" )
physics.start()

-- Create a platform
local platform = display.newRect( display.contentCenterX, 350, 160, 40 )
physics.addBody( platform, "static" )
platform.rotation = 10

-- Create the particle system
local testParticleSystem = physics.newParticleSystem(
{
    filename = "particle.png",
    radius = 2,
    imageRadius = 4
})

local function onTimer()

    testParticleSystem:createParticle(
    {
        x = display.screenOriginX - 10,
        y = 100,
        velocityX = 80,
        velocityY = -200,
        color = { 1, 0.2, 0.4, 1 },
        lifetime = 32.0,
        flags = { "water", "colorMixing", "fixtureContactListener" }
    })
end

timer.performWithDelay( 20, onTimer, 40 )

让我们更详细地检查这段代码

  1. 紧跟物理引擎的包含和启动,我们为粒子创建一个静态平台,供其碰撞,并将其旋转 10 度,以便我们观察液体从其流出

  2. 接下来,我们使用相对基础的属性创建粒子系统。

  3. 在设置好粒子系统之后,我们创建一个函数 (onTimer())。在此函数中,我们包含对 object:createParticle() 方法的调用,该方法会生成一个粒子。此调用的属性类似于 LiquidFun 基础 教程中的属性,除了包含一个非常重要的标志:"fixtureContactListener"。如果您省略此标志,您将不会收到粒子碰撞响应!

  4. 最后,我们排队一个定时器,以 20 毫秒的增量生成 40 个粒子。

为了再次强调上述重点,您必须在创建粒子时在 flags 表中包含 "fixtureContactListener"。如果未包含该标志,您将不会收到粒子碰撞响应。

粒子系统碰撞处理

现在,让我们添加一个函数来侦听粒子系统上的碰撞事件。这类似于 此处 描述的传统物理对象之间的本地碰撞处理方法,在这种情况下,我们只需要设置函数,设置粒子系统的 particleCollision 属性来引用该函数,然后向系统添加 "particleCollision" 类型的事件侦听器。

local function particleSystemCollision( self, event )

    if ( event.phase == "began" ) then
        print( "PARTICLE SYSTEM:", event.particleSystem )
    end
end
 
testParticleSystem.particleCollision = particleSystemCollision
testParticleSystem:addEventListener( "particleCollision" )

这提供了一个非常基本的碰撞框架,但在大多数情况下,您需要更多信息才能正确应对粒子碰撞。幸运的是,Corona 提供了大量信息,作为 particleSystemCollision 侦听器函数的 event 表的 属性。这些包括

重要信息

在使用 LiquidFun 时的一个关键考虑因素是只能针对粒子系统作为整体对象执行由于粒子碰撞而应用的动作。换言之,当单个粒子与另一个对象碰撞时,你可以读取以上任何属性,但你无法设置该特定粒子上的属性,例如设置其 b 值(蓝色值)以改变它的颜色。基本上,你需要将粒子系统视为一个专用单元,而不是尝试在per-particlebasis 上设置属性。

对象碰撞处理

或者,你可以在其他对象上检测碰撞,而不是直接在粒子系统中检测碰撞。如果你正在设计一个带有多个粒子系统且希望在一个主对象(例如玩家角色)上检测碰撞的游戏,这样做可能更合乎逻辑。

在我们的现有示例中,我们可以通过将碰撞监听器添加到platform对象(而不是粒子系统)来实现这一点。检查差异

local function objectCollision( self, event )

    if ( event.phase == "began" ) then
        print( "OBJECT:", event.object )
    end
end

platform.particleCollision = objectCollision
platform:addEventListener( "particleCollision" )

方便的是,此模型还提供了上面列出的相同的event属性,因此你可以收集有关参与碰撞的特定粒子的信息,包括生成粒子的粒子系统。

全局碰撞处理

处理粒子碰撞的另一种方式是使用全局Runtime监听器。这将检测粒子和其它物理物体之间的全局级别的碰撞。

local function onGlobalCollision( event )

    if ( event.phase == "began" ) then
        print( "OBJECT:", event.object )
        print( "PARTICLE SYSTEM:", event.particleSystem )
    end
end

Runtime:addEventListener( "particleCollision", onGlobalCollision )

结论

希望本教程说明了检测 LiquidFun 粒子和其它物理对象之间的碰撞是多么简单。此功能应有助于将你LiquidFun-based游戏提升到一个新的互动层次!