开发者

lua - table maintenance (particle system related)

The update() function below gets called on every frame of a game. If the Drop particle has y value greater than 160 I want to remove it from the table. The problem is that I get "attempt to compare number with nil" errors, on the line notated below:

local particles = {};

function update()
    local num = math.random(1,10);
    if(num < 4) then
        local drop = Drop.new()
        table.insert ( particles, drop );
    end

    for i,val in ipairs(particles) do
        if(val.y > 160) then --ERROR attempt to compare number with nil
            val:removeSelf(); --removeSelf() is Corona function that removes the display object fro开发者_JAVA百科m the screen
            val = nil;
        end
    end
end

What am I doing wrong? Obviously val is nil, but I don't understand why the table iteration would find val in the first place since I set it to nil when it's y value gets larger than 160.


Thanks for the answers, they were all helpful. Here is what ended up working for me. The table.remove call is necessary to keep the loop running properly.

for i = #particles, 1, -1 do
    if particles[i].y > 160 then
        local child = table.remove(particles, i)
        if child ~= nil then
            display.remove(child)
            child = nil
        end
    end
end


You're looking in the wrong place, the problem isn't that val is nil, it's val.y that's nil. See this example:

> x=nil
> if x.y > 10 then print("test") end
stdin:1: attempt to index global 'x' (a nil value)
stack traceback:
    stdin:1: in main chunk
    [C]: ?
> x={y=nil}
> if x.y > 10 then print("test") end
stdin:1: attempt to compare number with nil
stack traceback:
    stdin:1: in main chunk
    [C]: ?

Also, when you set val to nil, that may not be doing anything (I believe val is a copy):

> t={"a", "b", "c", "d"}
> for i,val in ipairs(t) do print(i, val) end
1   a
2   b
3   c
4   d
> for i,val in ipairs(t) do if i==3 then print("delete", val); val=nil end end
delete  c
> for i,val in ipairs(t) do print(i, val) end
1   a
2   b
3   c
4   d

Edit: to delete an element from a table, you want table.remove:

> t[3]=nil
> for i,val in ipairs(t) do print(i, val) end
1   a
2   b
> t[3]="c"
> for i,val in ipairs(t) do print(i, val) end
1   a
2   b
3   c
4   d
> for i,val in ipairs(t) do if i==3 then print("delete", val); table.remove(t, i) end end
delete  c
> for i,val in ipairs(t) do print(i, val) end
1   a
2   b
3   d


JeffK's solution should work, but I think the reason it will work is not because of the fact that he's traversing the list backwards, but because he is setting particles[i] = nil instead of val = nil. If you run val = nil you're only setting the local copy of val to nil, not the entry in the table.

Try this:

for i,val in ipairs(particles) do
    if(val.y > 160) then
        particles[i]:removeSelf()
        particles[i] = nil;
    end
end


I don't think you are allowed to modify the contents of a table while ipairs is iterating through it. I vaguely remember reading that my hardcopy of the Lua 5.1 Reference Manual, but I can't seem to locate it now. When you set val to nil, it removes an element from the particles table.

You might try processing the table in reverse, since your function is doing a full sweep of the particles table, conditionally removing some items:

for x = #particles, 1, -1 do
    if particles[x].y > 160 then
        particles[x]:removeSelf()
        particles[x] = nil
    end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜