Corona SDK中的“nil value”问题

我正在利用corona sdk制作射击游戏... 我的问题是当对象离开屏幕时(该对象是数组的一部分),我尝试删除它,但是我得到一个错误,显示“正在尝试将空值与变量进行比较”,这是指数组中每个对象的简单移动函数。这里是相关的代码部分:

function addAlien()
    listeners('add')
end

function listeners(action)
    if(action == 'add') then
    Runtime:addEventListener('enterFrame',update)
    enemyTimer = timer.performWithDelay(800,addEnemy,0)
    else
    Runtime:removeEventListener('enterFrame',update)
    timer.cancel(enemyTimer)
    end
end

function addEnemy(e)
    enemy = display.newImage('drone.png')
    enemy.x = 500
    enemy.y = math.floor(math.random()*300)
    enemy:scale(-0.1,0.1)
    enemy.speed = math.random(2,6)
    enemies.insert(enemies,enemy)
    enemy.enterFrame = moveEnemy
    Runtime:addEventListener('enterFrame',enemy)
end

function moveEnemy(self,event)
    self.x = self.x-self.speed
end

function update(e)
    if(enemies.numChildren ~= 0)then
        for i = 1,enemies.numChildren do
            if(enemies[i] ~= nil)then
                if(enemies[i].x<100)then
                    display.remove(enemies[i])
                    table.remove(enemies, i)
                end
            end
        end
    end
end

我已经注释了会导致错误的部分。 非常感谢您的帮助。

点赞
用户1870706
用户1870706

你可能想尝试将删除代码放入自己的函数中,然后使用定时器将其删除,以便可以返回当前删除对象的函数并避免删除自身。

另一个选项是将其暂时设为不可见,并定期遍历表格并删除移动处理程序之外的任何内容。

2013-08-12 02:24:44
用户1078537
用户1078537

你手头的代码有问题:

function listeners(action)
    if(action == 'add') then
        Runtime:addEventListener('enterFrame',update)
        enemyTimer = timer.performWithDelay(800,addEnemy,0)
    else
        Runtime:removeEventListener('enterFrame',update)
        timer.cancel(enemyTimer)
    end
end

你只需要在一开始就执行一次 Runtime:addEventListener('enterFrame', update)。如果你在每次添加敌人时都重复执行它,程序就会出现问题。问题在于你的代码在物体已被移除后仍然会一遍遍地运行。

2014-04-08 19:21:52
用户7941332
用户7941332

hmmm. did you use the scene template? if so, you should only put the :removeself() and = nil values in the scene destroy section at the bottom. you also dont need the second removeself() that is not attached to an object as that is probably the nil issue.

嗯,你使用了场景模板吗?如果是这样的话,你应该只将 :removeself()= nil 值放在底部的场景销毁部分。你也不需要第二个 removeself(),因为它不附属于任何对象,这可能是 nil 问题的原因。

to summarize.

总结:

  1. 将所有的 remove self()= nil 放在场景模板的销毁部分,并使用 object.isVisible = false
  2. nil 错误最可能来自于没有对象的 removeself() 语句。因此,请将其更改为 moveenemy:removeself()
2017-07-25 02:07:33
用户8355478
用户8355478
local scrWidth = display.actualContentWidth
local scrHeight = display.actualContentHeight

local enemy = {} --这将保存你的外星人

function addEnemy()
    enemy[#enemy + 1] = display.newImage("drone.png")
    enemy[#enemy].x = 500
    enemy[#enemy].y = math.floor(math.random()*300)
    enemy[#enemy]:scale(-0.1,0.1)
    enemy[#enemy].speed = math.random(2,6)
end

local function update()
    addEnemy()

   --这将从右向左移动外星人
   for i=1,#enemy,1 do
    enemy[i].x = enemy[i].x - enemy[i].speed
   end

   --以下代码将在屏幕左侧外部销毁每个外星人
   local function destroyWhenOutside()
    for i=1,#enemy,1 do
      if enemy[i].x < 0 - enemy[i].width then
        enemy[i]:removeSelf()
        enemy[i] = nil
      elseif enemy[i].y < 0 - enemy[i].height then
        enemy[i]:removeSelf()
        enemy[i] = nil
      end
    end
   end
   destroyWhenOutside()
end

--这将每1/1000秒循环一次更新
local timerUpdate = timer.performWithDelay(1,update,-1)
2017-07-25 17:01:45