It looks like you're new here. If you want to get involved, click one of these buttons!
local function onCollision(event) if gameActive then local fixtureA = event.fixtureA local fixtureB = event.fixtureB local bodyA = fixtureA:getBody() local bodyB = fixtureB:getBody() local inst, other if (bodyA.info.material == "wood") then inst = bodyA other = bodyB elseif (bodyB.info.material == "wood") then inst = bodyB other = bodyA end if inst ~= nil then if (other.info.material == "woodHit") then player:setLinearVelocity(5, 5); elseif (other.info.material == "woodCount") then del = true delItem = inst end end end end del = false delItem = nil local function onEnterFrame() if del == true then print ("Item Deleted") delItem:setActive(false) --The next 2 lines are used in the documentation, although in a "touch" listener function local parent = delItem:getParent() --This line has the error parent.destroyBody(delItem) del = false delItem = nil end end level.world:addEventListener(Event.POST_SOLVE, onItemCollision) stage:addEventListener(Event.ENTER_FRAME, onEnterFrame) |
Comments
in which variable do you store the world instance? Because deleteing box2d object should be something like:
Likes: Bramanik
Body is already destroyed.
How your code looks now, can you show it?
The whole error code is:
.\slb-svgparser.lua:590: Body is already destroyed.
The error is coming up inside another onEnterFrame function inside the SVG builder and the line is trying to reference the body (which is obviously now destroyed).
[Edit] Nevermind, I realized it was because after I deleted there was the loop that went through the actors. So, one thing learned is you may get the error that the body is already destroyed if trying to act on it (other than a delete command). So my suspicion is either in your code somewhere else or in the SVG code it is trying to loop through a list of actors maybe and although you destroy the body, something else tries to act on the body elsewhere.
I tried a bool check (using del) on the final if before the SVG tries to set position and rotation of the body, although that just made it jittery and still came up with the same error eventually anyway.
I'm not sure if it increments the ID of an item after its cloned in the SVG builder, although I vaguely remember testing it and they all had the cloned instances ID. Maybe if I increment the ID on creating the instance, then checked that ID against the bodies inside the items layer on my level file, then it might not leave a reference for the onEnterFrame function to screw up. I don't think I can reach the custom.id or just id of an instance from the fixture or body though.
Are you doing anything else anywhere storing references to the bodies? (like how you keep other references to level.group etc for convenience?)
For example found something like this:
You can also disable physics behaviour in a body by adding the noPhysics attribute to it.
Although I don't know if it's used on init or can be applied to existing bodies
Otherwise you could manually remove references in your function like so:
Using the second solution I get:
sceneGame.lua:351: table index is nil (on the "level.bodies[delItem.name] = nil" line)
I'm thinking that I can't access any of the XML properties because the delItem is the body and not the actual instance, otherwise I could use the getParent method that is used in the example.
Maybe an additional check inside the SVG's onEnterFrame to check if it is the same body then delete the reference and/or body there?
EDIT: I tried adding an extra if inside the SVG's instance table/body in onEnterFrame and then used my del bool and delItem body to compare against the same body in the onEnterFrame and then remove the reference from the parent (ie. subchild). (If you are looking in the slb-svgparser class, the first if starts on line 585, I added the existing code just for relevance purposes)
.\slb-svgparser.lua:597: Body is already destroyed.
Here is the edited onEnterFrame function within the SVG code (starts on slb-svgparser.lua line 575) for anyone interested in the solution. This solution will only delete 1 body/table per frame even if there are more bodies to be deleted on that frame. You can just use a table to store multiple bodies if you wanted to implement that though.