@UberGoober When you add a body to a table, you’ll use that table position to destroy it. You can iterate thru the table to destroy everything in the table. If you remove a lot of entries, you have to go thru the table in reverse order because anytime you remove a table entry, the other entries are shifted to fill the empty space. If you iterate the table from beginning to end, when an entry is removed, the next item will fill the empty space and get skipped as you iterate forward thru the table.
PS. I had a lot of examples where I destroyed bodies from a table. If you want one, let me know.
@UberGoober Heres an example of adding bodies to a table and destroying them. There a 2 touched functions. One delete the bodies in a forward direction, the other in reverse. Change the touched function to execute one or the other to demo what I mentioned above about destroying and deleting bodies. Tap the screen to delete the bodies. One deletes them all at once, the other only half each time.
viewer.mode=FULLSCREEN
function setup()
fill(255)
tab={}
physics.body(EDGE,vec2(0,50),vec2(WIDTH,50))
physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
physics.body(EDGE,vec2(WIDTH,50),vec2(WIDTH,HEIGHT))
for z=1,300 do
local b=physics.body(CIRCLE,10)
b.x=math.random(WIDTH)
b.y=math.random(HEIGHT)
table.insert(tab,b)
end
end
function draw()
background()
for a,b in pairs(tab) do
ellipse(b.x,b.y,20)
end
text(#tab,WIDTH/2,HEIGHT-50)
end
function touched(t) -- delete table in reverse direction
if t.state==BEGAN then
for z=#tab,1,-1 do
tab[z]:destroy()
table.remove(tab,z)
end
end
end
function touched(t) -- delete table in forward direction
if t.state==BEGAN then
for a,b in pairs(tab) do
b:destroy()
table.remove(tab,a)
end
end
end
@dave1707 I think that only matters if you’re using ipairs to iterate?
I’m using pairs though, so technically I’m using keys and not positions to nil them out, I think.
But in any case the problem isn’t getting them out of a single table, I’m doing that just fine, it’s that they must be included in some table I haven’t found yet, buried somewhere in my code, because even when I empty them out of one table successfully, the physics bodies are still in the physics.bodies table.
@UberGoober Only part are removed each time even doing pairs in my above example. I don’t know of any way to find where bodies are hidden. They should only be in whatever table you put them in. If you don’t destroy them, they’ll still remain even though you might not see them.
In my above example, comment out the b:destroy in the last touched function. When you tap the screen, some of the balls disappear but they’re still there as physics bodies.
So unless I’m wrong here, neither of your touched functions will remove bodies that are not indexed by a number, I think. Also mightn’t the second one throw an error if there are any text keys?
@UberGoober If you put a body in the table using a key, then you would use the table with that key when you want to destroy the body. I’m not sure about the nil value. I’ll have to try different things and see what the different results are.
@UberGoober What’s happening that you think you have hidden bodies.
Here’s an example of hidden bodies. I’m creating them in the first for loop but doing nothing with them. Run the code, wait approx 10 sec then tap the screen. You see 300 circles created like the other examples, but they won’t go all the way to the bottom of the screen because that’s where the hidden bodies are. They’re there because you created them even though you’re not doing anything with them.
viewer.mode=FULLSCREEN
function setup()
fill(255)
tab={}
physics.body(EDGE,vec2(0,50),vec2(WIDTH,50))
physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
physics.body(EDGE,vec2(WIDTH,50),vec2(WIDTH,HEIGHT))
for z=1,300 do
b=physics.body(CIRCLE,10)
b.x=math.random(WIDTH)
b.y=math.random(HEIGHT)
end
end
function draw()
background()
for a,b in pairs(tab) do
ellipse(b.x,b.y,20)
end
text("wait approx 10 seconds then tap the screen",WIDTH/2,HEIGHT-100)
end
function touched(t) -- delete table in reverse direction
if t.state==BEGAN and #tab==0 then
for z=1,300 do
b=physics.body(CIRCLE,10)
b.x=math.random(WIDTH)
b.y=math.random(200,HEIGHT)
table.insert(tab,b)
end
end
end
@UberGoober How many tables do you have with bodies in them and how many bodies do you have. You could add an if statement where you add a body and print something or stop the program if you don’t think a body should be added.
@UberGoober Here’s a way you can track down what’s happening. Using the physics.bodies table, you can print information about the bodies you create and where you put them. When I create the physics.body, I add information about what it is and where. Tap the screen to print the info.
viewer.mode=STANDARD
function setup()
fill(255)
tab={}
e1=physics.body(EDGE,vec2(0,50),vec2(WIDTH,50))
e1.info="edge bottom"
e2=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
e2.info="edge left"
e3=physics.body(EDGE,vec2(WIDTH,50),vec2(WIDTH,HEIGHT))
e3.info="edge right"
for z=1,10 do
local b=physics.body(CIRCLE,10)
b.x=math.random(WIDTH)
b.y=math.random(HEIGHT)
b.info="circle "..z.." in table tab"
table.insert(tab,b)
end
end
function draw()
background()
for a,b in pairs(tab) do
ellipse(b.x,b.y,20)
end
end
function touched(t)
if t.state==BEGAN then
for a,b in pairs(physics.bodies) do
print(b.info)
end
end
end
@dave1707 I already have things like this, it doesn’t really address the core issue.
See, if I could find the place where the bodies are being added to the table that keeps them from being destroyed, I wouldn’t need a trick to help me find it, right?
Problem is that I haven’t been able to find it, so I’m trying to see if there’s something I can do without that information.
@skar That’s exactly the kind of thing I’m trying to do, but I need to find a way to apply it to all tables by default. Like somehow attach that metamethod to the table creation routine itself, so any table that gets created automatically uses it. Is there any possible way to do that? Again, if I could find just the one specific table that needs it, I wouldn’t need help finding that table, which is the whole point of this in the first place.