Coming from C/C++ I really feel to old for this Lua s… and i really bothers me. Anyway…
I’m trying to get the basics down regarding tables and how to add/remove stuff properly.
My simple example is creating three blocks falling down to the ground and as they hit, they are supposed to be removed from the table (and also be removed correctly from the physics engine).
To avoid crashes in the physics engine I do not remove the item directly when a collision is detected, but mark it to be removed. Then I call the removeBlocksMarkedForRemoval() as per frame drawing.
The entire code looks like this:
local w = display.contentWidth local h = display.contentHeight local physics = require("physics") physics.start() -- Ground local ground = display.newRect(w/2, h-5, w, 10) ground.myName = "earth" physics.addBody(ground, "static", { density=5.0, friction=0.3, bounce=0.0}) local blockArr = {} local function addBlock() local newIdx = #blockArr+1 blockArr[newIdx] = display.newRect(math.random(w/2-100, w/2+100), -30, 30, 30) blockArr[newIdx].markedForRemoval = false blockArr[newIdx].myName = "block" physics.addBody(blockArr[newIdx], "dynamic", { density=2.0, friction=0.9, bounce=0.5}) end local function removeBlocksMarkedForRemoval() for i = #blockArr, 1, -1 do if (blockArr[i].markedForRemoval == true) then physics.removeBody(blockArr[i]) blockArr[i]:removeSelf() blockArr[i] = nil end end end timer.performWithDelay(250, addBlock, 3) -- Hit local hit = function(e) if (e.phase == "ended" and e.object1.myName == "earth" and e.object2.myName == "block") then e.object2.markedForRemoval = true end end local frameRedrawListener = function(e) print("blocks before call to removeBlocksMarkedForRemoval() = " .. #blockArr) removeBlocksMarkedForRemoval() print("blocks after call to removeBlocksMarkedForRemoval() = " .. #blockArr) end -- Add event listeners Runtime:addEventListener( "enterFrame", frameRedrawListener ) Runtime:addEventListener( "collision", hit )
But when I run it I get a " attempt to index field ‘?’ (a nil value)" for the line
if (blockArr[i].markedForRemoval == true) then
And I don’t understand why. It’s obvious that I’m doing something stupid.
But what is the correct way of doing such a thing?