几乎每个使用 Corona 基于
对于那些需要更专业的碰撞处理的开发者,Corona 还提供了 碰撞前 监听器。这是为在碰撞发生前对其进行特定、专门的处理而保留的,它经常与 PhysicsContact 一起使用,如 多元素碰撞 教程中所述。
还有第三种选择 — 不太为人所知,但在某些情况下同样重要 — 碰撞后 监听器。顾名思义,此监听器用于在碰撞发生后收集各种碰撞细节。此事件还提供了一些其他事件类型无法提供的物理信息,使其在某些情况下特别有用!
本教程不会详细介绍如何设置碰撞监听器,因为这些内容在 碰撞检测 指南中都有概述。基本上,
-- Set up physics engine local physics = require( "physics" ) physics.start() -- Create a basic physics object local box = display.newRect( 60, 20, 50, 50 ) physics.addBody( box ) -- Set up the post-collision listener function local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) end -- Associate the listener function with the object box.postCollision = postCollisionEvent box:addEventListener( "postCollision" )
请注意,
box:removeEventListener( "postCollision" ) box.postCollision = nil
在碰撞“已经发生”之后收集碰撞细节似乎毫无意义,因为碰撞已经发生,物理引擎基本上已经移动到下一个时间步。然而,正是在
让我们探讨一些
event.force
,例如:
local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) print( "FORCE:", event.force ) end
这在物理模拟中有什么应用?想想经典的热门游戏愤怒的小鸟™,其中每只愤怒的小鸟对世界上的不同固体材料都有不同的影响 — 例如,蓝色的小鸟撞击“玻璃”块时特别用力。如果我们要实现类似的游戏功能,可以很容易地编写一个条件检查来检测蓝色小鸟是否与玻璃块碰撞,但这将我们限制在一个真/假关系中 — 我们仍然不知道碰撞中传递的力究竟有多大。然而,使用
碰撞力在“过滤”方面同样有用。想象一个玩家向装甲敌人发射箭的游戏,例如 多元素碰撞 教程中的装甲骷髅。理论上,骷髅的盔甲有一定的阈值,它会完全阻挡射弹,导致它们反弹并掉落到地面。如上所述,正常的碰撞事件可以显示射弹击中了骷髅,但它无法提供有关碰撞力的详细信息。因此,
local function postCollisionEvent( self, event ) print( "POST-COLLISION EVENT" ) print( "FRICTION:", event.friction ) end
这在物理模拟中有什么应用?一个例子是检测汽车或其他物体与金属表面碰撞时的摩擦力,然后使用该值通过 粒子发射器 或其他方式显示可变数量的“火花”。例如,如果摩擦力非常高,我们可以产生更明显的火花数量,而如果摩擦力很低 — 例如物体只是轻微地擦过表面 — 我们可以只产生一小股火花(或者甚至使用上面讨论的过滤阈值来完全省略效果)。
希望本教程概述了 碰撞后 事件的一些有效应用。虽然检测这些事件永远不会像检测普通碰撞那样普遍,但它们是独特的事件,对于某些游戏逻辑甚至游戏的视觉真实感至关重要。