2

以下のupdate()関数は、ゲームのすべてのフレームで呼び出されます。Dropパーティクルのy値が160より大きい場合は、テーブルから削除します。問題は、以下の行に「数値とnilを比較しよう」というエラーが発生することです。

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ですが、yの値が160より大きくなるとnilに設定したため、テーブルの反復で最初にvalが見つかる理由がわかりません。

4

4 に答える 4

3

答えてくれてありがとう、それらはすべて役に立ちました。これが私のために働いた結果です。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
于 2011-06-01T16:59:42.293 に答える
2

あなたは間違った場所を見ています、問題はそれではありません、それvalはです。この例を参照してください。nilval.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
于 2011-06-01T00:13:01.537 に答える
0

ipairsがテーブルを反復処理している間は、テーブルの内容を変更することは許可されていないと思います。Lua 5.1リファレンスマニュアルのハードコピーを読んだことをぼんやりと覚えていますが、今は見つけられないようです。valnilに設定すると、パーティクルテーブルから要素が削除されます。

関数はパーティクルテーブルを完全にスイープし、条件付きでいくつかのアイテムを削除しているため、テーブルを逆に処理してみてください。

for x = #particles, 1, -1 do
    if particles[x].y > 160 then
        particles[x]:removeSelf()
        particles[x] = nil
    end
end
于 2011-05-31T23:25:28.743 に答える
0

JeffKのソリューションは機能するはずですが、機能する理由は、彼がリストを逆方向にトラバースしているためではparticles[i] = nilなく、の代わりに設定しているためだと思いますval = nil。実行するval = nil場合は、valのローカルコピーをnilに設定するだけで、テーブルのエントリは設定しません。

これを試して:

for i,val in ipairs(particles) do
    if(val.y > 160) then
        particles[i]:removeSelf()
        particles[i] = nil;
    end
end
于 2011-06-01T00:05:26.960 に答える