Corona 包含一个强大的
有几种方法可以在不使用物理引擎的情况下检测碰撞,包括
如果矩形有任何旋转应用于它,第一种方法可能会很复杂,并且分离轴定理相当
在考虑
在某些游戏中,即使不是艺术上的圆形的对象,其碰撞边界通常也可以用圆形表示,例如包围整个图像的圆形,或者跨越对象“中心”周围略小区域的圆形。在快速的游戏过程中,玩家可能不会注意到精确的
一些非常简单的计算可以确定任意大小的两个圆是否重叠。
local function hasCollidedCircle( obj1, obj2 ) if ( obj1 == nil ) then -- Make sure the first object exists return false end if ( obj2 == nil ) then -- Make sure the other object exists return false end local dx = obj1.x - obj2.x local dy = obj1.y - obj2.y local distance = math.sqrt( dx*dx + dy*dy ) local objectSize = (obj2.contentWidth/2) + (obj1.contentWidth/2) if ( distance < objectSize ) then return true end return false end
对于此函数,我们只需传入两个显示对象 obj1
和 obj2
。使用 contentWidth
属性确定它们的宽度,我们检查两个圆是否比它们中心之间的距离更近,如果是,我们就知道它们正在接触。
使用 CoronacontentBounds
属性,更容易检测重叠的矩形。
local function hasCollidedRect( obj1, obj2 ) if ( obj1 == nil ) then -- Make sure the first object exists return false end if ( obj2 == nil ) then -- Make sure the other object exists return false end local left = obj1.contentBounds.xMin <= obj2.contentBounds.xMin and obj1.contentBounds.xMax >= obj2.contentBounds.xMin local right = obj1.contentBounds.xMin >= obj2.contentBounds.xMin and obj1.contentBounds.xMin <= obj2.contentBounds.xMax local up = obj1.contentBounds.yMin <= obj2.contentBounds.yMin and obj1.contentBounds.yMax >= obj2.contentBounds.yMin local down = obj1.contentBounds.yMin >= obj2.contentBounds.yMin and obj1.contentBounds.yMin <= obj2.contentBounds.yMax return ( left or right ) and ( up or down ) end
此函数非常适用于瓷砖和卡片等方形或矩形对象。它使用一组 if
语句检查来查看一个矩形的任何角是否在另一个矩形的边界内。
对于周围有一些透明度的图像,请注意,这**将**包括透明区域,因为该函数使用这些图像的内容边界。如有必要,您可以调整比较中的数学运算,例如,对各种“min”和“max”属性添加或减去一个像素值,以考虑透明度的宽度。
现在您已经有了几种不同的方法来确定两个项目是否发生碰撞,您如何使用它们?与
也许最明显的方法是使用 "enterFrame"
运行时侦听器,如下所示:
作为一个
作为一种侦听器方法,您可以根据需要将其打开或关闭,例如,仅当玩家
考虑这个示例函数,它假设您有一个 myPlayer
对象,并且多个硬币对象存储在一个名为 coinCache
的表中。假设玩家也可以使用coinCache
表,并检查玩家是否与任何硬币接触。
local function gameLoop( event ) for i = 1,#coinCache do -- Check for collision between player and this coin instance if ( coinCache[i] and hasCollidedCircle( myPlayer, coinCache[i] ) ) then -- Remove the coin from the screen display.remove( coinCache[i] ) -- Remove reference from table coinCache[i] = nil -- Handle other collision aspects like increasing score, etc. end end return true end Runtime:addEventListener( "enterFrame", gameLoop )
我们的
教程到此结束。如您所见,当您构建一个需要基本碰撞检测的应用程序时,这是一种方便的方法,而且物理引擎的功能强大,超出了您任务的需求。