add and remove on tables with code example, small error

Hello,
i am working with tables in corona, and had learned about it, and the code is running almost perfectly, have 1/2 errors.

what is working good well:

  • i only can create until 3 block

what isnt working well:

  • when i remove a object i need to remove on the table, because, when i create a object it is counting +1 on the table, and when i remove the object i want to remove it on table, -1, the algorithm do it but not well, i create 3 objects and i remove 1 object, i should stay with #table = 2 and can only create one more object because the limit is 3, but it is the part that dont work well

Try the code and will understand what is wrong

 display.setStatusBar( display.HiddenStatusBar )  
 local physics = require "physics"  
 physics.start( true )  
 physics.setDrawMode( "normal" )   
 physics.setGravity( 0,0 )  
  
 --\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
 -- Game   
  
 --\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
  
 local pausegame = function()  
  
 local active = 0  
 print(active)  
 local ball1 = display.newCircle( 80, 120, 20 )   
 ball1:setFillColor( 0, 255, 0 )   
 physics.addBody(ball1,"kinematic", { density=2, bounce=0.3, radius=25});  
 ball1.x = 250; ball1.y = 200  
  
  
 local spawner = display.newRect( 50, 5, 40, 40 )  
 spawner:setFillColor(150, 0, 0)  
 physics.addBody(spawner, "static", {isSensor = true})  
 spawner:addEventListener("collision", spawner)  
  
 local function touch(event)  
 if event.phase == "ended" then  
 active = active + 1  
 print(active)  
 physics.setGravity( 0,9.8 )  
 ball1.bodyType="dynamic"  
 end  
 end  
 ball1:addEventListener( "touch", touch )  
  
 ---------------it is the important part because is where is the lua table that i am working, to add and remove objects------------  
  
 local block1 = {}  
  
 function spawner:collision (event)  
 event.other:removeSelf()  
 block1 = block1[#block1-1]   
 end  
   
 local function spawnMyObject (event)  
 if event.phase == "began" then  
  
 if #block1 \< 3 then  
 block1[#block1+1] = display.newRect( 50, 50, 50, 50 )  
 block1[#block1]:setFillColor( 255, 255, 255, 100 )  
 physics.addBody(block1[#block1], "kinematic", { density=2, friction=0, bounce=0, shape=barril })  
 block1[#block1].isFixedRotation = true  
  
 -----------------end the important part---------------   
  
 local function startDrag( event )  
 local t = event.target  
 local phase = event.phase  
 if "began" == phase then  
 display.getCurrentStage():setFocus( t )  
 t.isFocus = true  
  
  
 t.x0 = event.x - t.x  
 t.y0 = event.y - t.y  
  
 event.target:setLinearVelocity( 0, 0 )  
 event.target.angularVelocity = 0  
   
 elseif t.isFocus then  
 if "moved" == phase then  
 t.x = event.x - t.x0  
 t.y = event.y - t.y0  
  
 event.target.bodyType = "dynamic"  
  
 elseif "ended" == phase or "cancelled" == phase then  
 display.getCurrentStage():setFocus( nil )  
 t.isFocus = false  
  
 -- Switch body type to kinematic, to avoid gravity  
 if ( not event.target.isPlatform ) then  
 event.target.bodyType = "kinematic"  
  
 end -- last if  
  
 end-- 2º if "move" end  
 end --if begin  
  
  
  
 end -- startdrag end   
  
 if active == 0 then  
 block1[#block1]:addEventListener("touch", startDrag)  
 elseif active == 1 then  
 block1[#block1]:removeEventListener("touch", startDrag)  
 end  
  
 end -- if #block end   
  
 end -- 1º if "begin" end   
  
 end --spawnMyObject end  
  
  
 spawner:addEventListener("touch", spawnMyObject)  
  
 end--pausegame ()  
  
 pausegame()  

thank you very much :slight_smile: [import]uid: 26056 topic_id: 16082 reply_id: 316082[/import]

what does [lua] block1 = block1[#block1-1] [/lua]
do inside the function spawner:collision (event) ?

you may try using table.remove() for that just assign an id to each objects you are using.
see the code below
[lua] display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start( true )
physics.setDrawMode( “normal” )
physics.setGravity( 0,0 )

–***************************************************

– Game

–***************************************************

local pausegame = function()

local active = 0
print(active)
local ball1 = display.newCircle( 80, 120, 20 )
ball1:setFillColor( 0, 255, 0 )
physics.addBody(ball1,“kinematic”, { density=2, bounce=0.3, radius=25});
ball1.x = 250; ball1.y = 200

local spawner = display.newRect( 50, 5, 40, 40 )
spawner:setFillColor(150, 0, 0)
physics.addBody(spawner, “static”, {isSensor = true})
spawner:addEventListener(“collision”, spawner)

local function touch(event)
if event.phase == “ended” then
active = active + 1
print(active)
physics.setGravity( 0,9.8 )
ball1.bodyType=“dynamic”
end
end
ball1:addEventListener( “touch”, touch )

---------------it is the important part because is where is the lua table that i am working, to add and remove objects------------

local block1 = {}

function spawner:collision (event)
table.remove(block1,event.other.id)
event.other:removeSelf()
event.other = nil
end

local function spawnMyObject (event)
if event.phase == “began” then

if #block1 < 3 then
block1[#block1+1] = display.newRect( 50, 50, 50, 50 )
block1[#block1]:setFillColor( 255, 255, 255, 100 )
block1[#block1].id = #block1
physics.addBody(block1[#block1], “kinematic”, { density=2, friction=0, bounce=0, shape=barril })
block1[#block1].isFixedRotation = true

-----------------end the important part---------------

local function startDrag( event )
local t = event.target
local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )
t.isFocus = true

t.x0 = event.x - t.x
t.y0 = event.y - t.y

event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

event.target.bodyType = “dynamic”

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

– Switch body type to kinematic, to avoid gravity
if ( not event.target.isPlatform ) then
event.target.bodyType = “kinematic”

end – last if

end-- 2º if “move” end
end --if begin

end – startdrag end

if active == 0 then
block1[#block1]:addEventListener(“touch”, startDrag)
elseif active == 1 then
block1[#block1]:removeEventListener(“touch”, startDrag)
end

end – if #block end

end – 1º if “begin” end

end --spawnMyObject end

spawner:addEventListener(“touch”, spawnMyObject)

end–pausegame ()

pausegame()[/lua] [import]uid: 71210 topic_id: 16082 reply_id: 59796[/import]

renvis@technowand, thank you very much is really it that i need, it help me so much, only one question, try to create 3 blocks and remove 1 block and create another block and remove 2 blocks and create 2 more etc, because it have one bug, when i sometimes when i create 3 objects and remove 2 after i only create one more block, try some different ways, you know why? [import]uid: 26056 topic_id: 16082 reply_id: 59864[/import]

yea…there is a small bug in the code i posted. may be you should use variable to keep the count of items in the table. [import]uid: 71210 topic_id: 16082 reply_id: 59895[/import]

hmmm…

local block_count = 0
block_count= block_count +1

and when object is removed:

block_count= block_count -1

something like it? but i am not understading how it will resolve the bug, this variable will count the objects on table but how i will interact it to resolve the bug?

[import]uid: 26056 topic_id: 16082 reply_id: 60082[/import]

Hi Andre,
the problem with your code is that, when you remove the object on collision its reference in table is not deleted so it will still show that the table have 3 items. so instead of doing that we use a variable for keeping count of elements added.

do it the way as you mentioned above and instead of
if #block1 < 3 then use if block_count <3.

but the problem here is that the table will still refer to the object even when it is removed.

another solution I can think of is to assign an id to each element added (use a variable to do so). then on collision function remove the element from the table based on the id. you may need to loop through elements in table to match the id. by this way you can remove the item from the table and can use table count also.

hope this is clear… :slight_smile:
[import]uid: 71210 topic_id: 16082 reply_id: 60086[/import]

yes, “if #block1 < 3 then use if block_count <3”. it will not do nothing. i need to count objects on table and by the id i need to create and remove the right object.

i was read and learn this topic to help me with tables:

http://blog.anscamobile.com/2011/06/understanding-lua-tables-in-corona-sdk/

and when you tell me to create id to each object is some like it?

local colorTable = {}  
  
 colorTable[1] = "blue"  
 colorTable[2] = "red"  
 colorTable[3] = "yellow"  
 colorTable[4] = "green"  
 colorTable[5] = "purple"  

Check it on simulator and can see the error, when he add and remove objects, by 1,2,3 can see on simulator.

 display.setStatusBar( display.HiddenStatusBar )  
 local physics = require "physics"  
 physics.start( true )  
 physics.setDrawMode( "normal" )   
 physics.setGravity( 0,0 )  
   
 --\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
   
 -- Game   
  
 --\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
  
  
 local pausegame = function()  
  
 local active = 0  
 print(active)  
 local ball1 = display.newCircle( 80, 120, 20 )   
 ball1:setFillColor( 0, 255, 0 )   
 physics.addBody(ball1,"kinematic", { density=2, bounce=0.3, radius=25});  
 ball1.x = 250; ball1.y = 200  
  
   
 local spawner = display.newRect( 50, 5, 40, 40 )  
 spawner:setFillColor(150, 0, 0)  
 physics.addBody(spawner, "static", {isSensor = true})  
 spawner:addEventListener("collision", spawner)  
  
 local function touch(event)  
 if event.phase == "ended" then  
 active = active + 1  
 print(active)  
 physics.setGravity( 0,9.8 )  
 ball1.bodyType="dynamic"  
 end  
 end  
 ball1:addEventListener( "touch", touch )  
   
 ---------------it is the important part because is where is the lua table that i am working, to add and remove objects------------  
   
 local block1 = {}  
  
  
   
 local function spawnMyObject (event)  
 if event.phase == "began" then  
  
  
  
 if #block1 \< 3 then  
 block1[#block1+1] = display.newRect( 50, 50, 50, 50 )  
 block1[#block1]:setFillColor( 255, 255, 255, 100 )  
 block1[#block1].id = #block1  
 physics.addBody(block1[#block1], "kinematic", { density=2, friction=0, bounce=0, shape=barril })  
 block1[#block1].isFixedRotation = true  
 print( block1[#block1].id)  
  
  
  
 function spawner:collision (event)  
 table.remove(block1,event.other.id)  
 event.other:removeSelf()  
 event.other = nil   
 print( block1[#block1].id)  
  
  
 end  
   
 -----------------end the important part---------------   
   
 local function startDrag( event )  
 local t = event.target  
 local phase = event.phase  
 if "began" == phase then  
 display.getCurrentStage():setFocus( t )  
 t.isFocus = true  
   
  
 t.x0 = event.x - t.x  
 t.y0 = event.y - t.y  
  
 event.target:setLinearVelocity( 0, 0 )  
 event.target.angularVelocity = 0  
   
 elseif t.isFocus then  
 if "moved" == phase then  
 t.x = event.x - t.x0  
 t.y = event.y - t.y0  
  
 event.target.bodyType = "dynamic"  
  
 elseif "ended" == phase or "cancelled" == phase then  
 display.getCurrentStage():setFocus( nil )  
 t.isFocus = false  
  
 -- Switch body type to kinematic, to avoid gravity  
 if ( not event.target.isPlatform ) then  
 event.target.bodyType = "kinematic"  
   
 end -- last if  
   
 end-- 2º if "move" end  
 end --if begin  
   
  
   
 end -- startdrag end   
   
 if active == 0 then  
 block1[#block1]:addEventListener("touch", startDrag)  
 elseif active == 1 then  
 block1[#block1]:removeEventListener("touch", startDrag)  
 end  
  
 end -- if #block end   
  
 end -- 1º if "begin" end   
   
 end --spawnMyObject end  
   
  
 spawner:addEventListener("touch", spawnMyObject)  
  
 end--pausegame ()  
   
 pausegame()  

[import]uid: 26056 topic_id: 16082 reply_id: 60158[/import]

instead of use block1[#block1+1] = display.newRect( 50, 50, 50, 50 ), i can use it?

local block1 = {}  
if #block1 \<3  
t[#t + 1] = x  
table.insert(t,x)  
and to remove:  
t[#t - 1] = x  
table.remove (t,x)  

this code work and i dont know how hahaha :smiley: try it :slight_smile:
but is not good because have errors

[code]
display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start( true )
physics.setDrawMode( “normal” )
physics.setGravity( 0,0 )

–***************************************************

– Game

–***************************************************

local pausegame = function()

local active = 0
print(active)
local ball1 = display.newCircle( 80, 120, 20 )
ball1:setFillColor( 0, 255, 0 )
physics.addBody(ball1,“kinematic”, { density=2, bounce=0.3, radius=25});
ball1.x = 250; ball1.y = 200

local spawner = display.newRect( 50, 5, 40, 40 )
spawner:setFillColor(150, 0, 0)
physics.addBody(spawner, “static”, {isSensor = true})
spawner:addEventListener(“collision”, spawner)

local function touch(event)
if event.phase == “ended” then
active = active + 1
print(active)
physics.setGravity( 0,9.8 )
ball1.bodyType=“dynamic”
end
end
ball1:addEventListener( “touch”, touch )

---------------it is the important part because is where is the lua table that i am working, to add and remove objects------------

local block1 = {}

print (table.maxn (block1))

local function spawnMyObject (event)
if event.phase == “began” then

if #block1 < 3 then
block1[#block1+1] = display.newRect( 50, 50, 50, 50 )
block1[#block1]:setFillColor( 255, 255, 255, 100 )
– block1[#block1 + 1] = x
–table.insert(block1,x)
–block1[#block1].id = #block1
physics.addBody(block1[#block1], “kinematic”, { density=2, friction=0, bounce=0, shape=barril })
block1[#block1].isFixedRotation = true
–print( block1[#block1].id)
print (table.maxn (block1))

function spawner:collision (event)
table.remove(block1,event.other.id)
event.other:removeSelf()
event.other = nil
print( block1[#block1].id)

end

-----------------end the important part---------------

local function startDrag( event )
local t = event.target
local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )
t.isFocus = true

t.x0 = event.x - t.x
t.y0 = event.y - t.y

event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

event.target.bodyType = “dynamic”

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

– Switch body type to kinematic, to avoid gravity
if ( not event.target.isPlatform ) then
event.target.bodyType = “kinematic”

end – last if

end-- 2º if “move” end
end --if begin

end – startdrag end

if active == 0 then
block1[#block1]:addEventListener(“touch”, startDrag)
elseif active == 1 then
block1[#block1]:removeEventListener(“touch”, startDrag)
end

end – if #block end

end – 1º if “begin” end

end --spawnMyObject end

spawner:addEventListener(“touch”, spawnMyObject)

end–pausegame ()

pausegame()

[/code] [import]uid: 26056 topic_id: 16082 reply_id: 60274[/import]

implementation with individual id for each object goes like this.
[lua] display.setStatusBar( display.HiddenStatusBar )
local physics = require “physics”
physics.start( true )
physics.setDrawMode( “normal” )
physics.setGravity( 0,0 )

–***************************************************

– Game

–***************************************************

local pausegame = function()

local active = 0
print(active)
local ball1 = display.newCircle( 80, 120, 20 )
ball1:setFillColor( 0, 255, 0 )
physics.addBody(ball1,“kinematic”, { density=2, bounce=0.3, radius=25});
ball1.x = 250; ball1.y = 200

local spawner = display.newRect( 50, 5, 40, 40 )
spawner:setFillColor(150, 0, 0)
physics.addBody(spawner, “static”, {isSensor = true})
spawner:addEventListener(“collision”, spawner)

local function touch(event)
if event.phase == “ended” then
active = active + 1
print(active)
physics.setGravity( 0,9.8 )
ball1.bodyType=“dynamic”
end
end
ball1:addEventListener( “touch”, touch )

---------------it is the important part because is where is the lua table that i am working, to add and remove objects------------

local block1 = {}

print (table.maxn (block1))

local spawnID = 0
local function spawnMyObject (event)
if event.phase == “began” then

spawnID = spawnID + 1
if #block1 < 3 then
block1[#block1+1] = display.newRect( 50, 50, 50, 50 )
block1[#block1]:setFillColor( 255, 255, 255, 100 )
block1[#block1].id = spawnID
physics.addBody(block1[#block1], “kinematic”, { density=2, friction=0, bounce=0, shape=barril })
block1[#block1].isFixedRotation = true

function spawner:collision (event)
if event.phase == “began” then
for i = 1, #block1, 1 do
if block1[i].id == event.other.id then
block1[i]:removeSelf()
table.remove(block1,i)
return true
end
end
end
end

-----------------end the important part---------------

local function startDrag( event )
local t = event.target
local phase = event.phase
if “began” == phase then
display.getCurrentStage():setFocus( t )
t.isFocus = true

t.x0 = event.x - t.x
t.y0 = event.y - t.y

event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

event.target.bodyType = “dynamic”

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

– Switch body type to kinematic, to avoid gravity
if ( not event.target.isPlatform ) then
event.target.bodyType = “kinematic”

end – last if

end-- 2º if “move” end
end --if begin

end – startdrag end

if active == 0 then
block1[#block1]:addEventListener(“touch”, startDrag)
elseif active == 1 then
block1[#block1]:removeEventListener(“touch”, startDrag)
end

end – if #block end

end – 1º if “begin” end

end --spawnMyObject end

spawner:addEventListener(“touch”, spawnMyObject)

end–pausegame ()

pausegame()[/lua]

[import]uid: 71210 topic_id: 16082 reply_id: 60280[/import]

I did not know the right way to make a relationship with blocks on table and variable spawid, thanks you very much for all the help renvis@technowand.

I do not want to be boring but I liked what you saw only one more detail because is the last bug that i have on this code and have some doubts to resolve, the value of the ball is set active = 0 but when I click on the ball enable the variable increases by one -> active = active +1, and when the active variable is equal the one I want to stop all the objects that were created, and in my code just can not stop objects that are created after I click on the ball, those that have been created and are in the field continue to move and I liked to stop them, you have any idea what can I do?

Thanks again :slight_smile: [import]uid: 26056 topic_id: 16082 reply_id: 60392[/import]

good to know that it worked.
am happy to help you but I din’t get what you really want to do. if you have any code then just post it and let me know what you want to attain. I will try to help you out… :slight_smile: [import]uid: 71210 topic_id: 16082 reply_id: 60401[/import]

Thank You very much :slight_smile: your help, help me to learn for this game and others games and others programming language etc etc :slight_smile:

the code is that i and you post above, but on other part of code, only need to work with this other wrong part, try the complete code that i or you post above, and create one or two objects, and you will can drag it, after click on the ball, and create another object, you will can not drag this created object, but can drag the other objects that you create before touch on the ball and i want to cant drag any object, when i touch on the ball i want to cant drag any object, try it and will understand better :slight_smile:

[code]
local active = 0
print(active)
local ball1 = display.newCircle( 80, 120, 20 )
ball1:setFillColor( 0, 255, 0 )
physics.addBody(ball1,“kinematic”, { density=2, bounce=0.3, radius=25});
ball1.x = 250; ball1.y = 200

local function touch(event)
if event.phase == “ended” then
active = active + 1
print(active)
physics.setGravity( 0,9.8 )
ball1.bodyType=“dynamic”
end
end
ball1:addEventListener( “touch”, touch )



if active == 0 then
block1[#block1]:addEventListener(“touch”, startDrag)
elseif active == 1 then
block1[#block1]:removeEventListener(“touch”, startDrag)
end [import]uid: 26056 topic_id: 16082 reply_id: 60407[/import]

anyone know how i can stop all draggable objects created on a table? [import]uid: 26056 topic_id: 16082 reply_id: 60698[/import]