lua - 表维护(粒子系统相关)

发布于 2024-11-10 11:25:47 字数 690 浏览 0 评论 0原文

下面的 update() 函数在游戏的每一帧都会被调用。如果 Drop 粒子的 y 值大于 160,我想将其从表中删除。问题是我收到“尝试将数字与零进行比较”错误,如下所示:

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 from the screen
            val = nil;
        end
    end
end

我做错了什么?显然 val 是 nil,但我不明白为什么表迭代首先会找到 val,因为当 y 值大于 160 时我将它设置为 nil。

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 from 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

枯叶蝶 2024-11-17 11:25:47

感谢您的回答,他们都很有帮助。这就是最终对我有用的东西。 table.remove 调用对于保持循环正常运行是必要的。

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

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
兔小萌 2024-11-17 11:25:47

您找错地方了,问题不在于 valnil,而是 val.ynil< /代码>。请参阅此示例:

> 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]: ?

另外,当您将 val 设置为 nil 时,可能不会执行任何操作(我相信 val 是一个副本):

> 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

编辑:要从表中删除元素,您需要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

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
舂唻埖巳落 2024-11-17 11:25:47

JeffK 的解决方案应该有效,但我认为它有效的原因不是因为他向后遍历列表,而是因为他设置的是 articles[i] = nil 而不是 val =零。如果运行val = nil,您只是将 val 的本地副本设置为 nil,而不是表中的条目。

试试这个:

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

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
趁微风不噪 2024-11-17 11:25:47

我认为当 ipairs 迭代表时,您不能修改表的内容。我依稀记得读过我的Lua 5.1参考手册的硬拷贝,但我现在似乎找不到它。当您将 val 设置为 nil 时,它会从粒子中删除一个元素 em> 表。

您可以尝试反向处理该表,因为您的函数正在对粒子表进行全面扫描,有条件地删除一些项目:

for x = #particles, 1, -1 do
    if particles[x].y > 160 then
        particles[x]:removeSelf()
        particles[x] = 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文