我在main.lua中有以下代码 我想要做的就是生成矩形,将它们添加到物理中以便它们可以从屏幕上掉下来,一旦它们的y大于屏幕高度(意味着它们不再可见)就从内存中删除矩形,并删除那些矩形。被用户触动。
这是我的代码
local physics = require( "physics")
physics.start( )
--table to hold dynamically created rectangles
local rects={}
--used as index for table
local numRect=0
--event handler for rectangle touch
local function rectTouch(event)
event.target:removeSelf( )
event.target = nil
end
--function for spawning rectangles
local function spawnRect()
numRect = numRect + 1
rects[numRect] = display.newRect( display.contentWidth/2, 200, 200, 200)
rects[numRect]:setFillColor( 1,1,1 )
physics.addBody( rects[numRect], "dynamic",{density=1, friction=0,2, bounce=0 })
rects[numRect]:addEventListener( "touch", rectTouch )
end
--function for removing rectangles which are no more visible
local function removeInactiveRects()
for i = 1, #rects do
if rects[i] ~= nil then
if rects[i].y > display.contentHeight + 100 then
rects[i]:removeSelf( )
rects[i] = nil
end
end
end
end
timer.performWithDelay( 1000, spawnRect, -1 )
timer.performWithDelay( 2000, removeInactiveRects,-1 )
我得到一个错误removeInactiveRects函数,说明尝试将数字与nil进行比较,我想负责这个的语句是rects[i] ~= nil
,但我不知道为什么。另外,它是从内存中删除对象的正确方法吗?
答案 0 :(得分:2)
问题在于触摸rectTouch
功能,您不仅需要删除矩形,还需要删除rects[]
表中的参考。您可以使用id值创建矩形,这样您就可以在事件函数中识别它们并删除它们。
--event handler for rectangle touch
local function rectTouch(event)
local i = event.target.id
event.target:removeSelf( )
event.target = nil
rects[i] = nil
end
--function for spawning rectangles
local function spawnRect()
numRect = numRect + 1
rects[numRect] = display.newRect( display.contentWidth/2, 200, 200, 200)
rects[numRect]:setFillColor( 1,1,1 )
rects[numRect].id = numRect
physics.addBody( rects[numRect], "dynamic",{density=1, friction=0,2, bounce=0 })
rects[numRect]:addEventListener( "touch", rectTouch )
end
我也是Corona的新人,所以我不确定,但也许你可以创造一些"地面物体"在底部+ 500并检测碰撞以移除矩形。 看collision detection guide
答案 1 :(得分:2)
问题是语句event.target = nil
也没有将相应的rects[i]
设置为nil,它只将目标从显示对象转换回常规表。因此,在此声明之后,rects[i]
对应于触摸目标的i
包含常规表对象,而不是nil,并且此表对象没有y字段。只要您在显示对象上removeSelf
,请确保从其他对象(例如rects
等表)中删除引用。
此外,关于物体低于某个高度后的移除,有几种方法可以做到这一点:
PhysicsContact:isEnabled()
并在碰撞处理程序中禁用碰撞并安排删除对象。 enterFrame
,检查任何具有y>的对象。 YMAX。可以立即删除这些对象。 但#4技术每2秒循环遍历所有“活”框,而基于物理的技术(#1和#2)仅对应删除的那些框使用计算周期。 OTOH,碰撞检测本身有些苛刻,但在2D中可能没那么多。 enterFrame
方法(#3)可能有点矫枉过正,因为它在每一帧(30次/秒)被调用,而你只是想删除该对象以使物理学从不再发展的物体中解放出来是可见的,但是如果对象超过阈值,或者一秒钟之后,这种清理是否正确无关紧要。
这一点在Corona的碰撞文档中都有解释。
答案 2 :(得分:0)
只需使用:
if rects[i] and rects[i].y > display.contentHeight + 100 then
之所以发生这种情况是因为删除了一些rects,因此表中的索引为空。如果它是空的,那么显然它不能有.y
参数。
您也可以通过插入对象来避免它:
local localRect = display.newRect( display.contentWidth/2, 200, 200, 200)
rects:insert(localRect)
而不是使用
if rects[i] ~= nil then
使用
if rects[i] then
表示“如果在[i]中有任何对象(不是”nil“而非”false“值)