Page 1 of 3
Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 2:53 pm
by Strutyk
Hi all. We have a table with objects:
Code: Select all
objectsArray = {objectOne, objectTwo, objectThree ...}
Each object has a properties:
Code: Select all
objectOne.active = false objectOne.x = 333, ...
We need to choose a random object and set
then remove selected object from
Upon reaching a certain condition, we must set
and to add it back in
Help please realize this
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 3:22 pm
by Beelz
If you posted a copy of your .love file(or a snippet of the part in question), it would be about a million times easier to help you point out where you went wrong.
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 4:09 pm
by ivan
Hello.
Hi all. We have a table with objects:
Code: Select all
objectsArray = {objectOne, objectTwo, objectThree ...}
This called a "list" or "numerically indexed" table.
We don't call tables "arrays", because array is a C thing and if you do then the Lua goblins will come after you at night.
Note that it doesn't really matter what type of elements are contained in the list.
The only thing that matters is that there is no "nil" in the list:
Code: Select all
list = { 1,2,3,4,5,6,7,8 } -- classic list
We can add new elements or remove the last element from this list using:
Code: Select all
list[#list] = nil -- remove last
list[#list + 1] = element -- insert
Just don't assign "nil" in the middle of the list because it will introduce gaps and will no longer be a proper list.
If you want to add/remove something in the beginning or middle of the list, use:
Code: Select all
table.remove(list, index) -- remove first
table.insert(list, index, element) -- insert
The rest of what you are describing doesn't make much sense.
What is your code trying to do?
One common approach is to have two lists: "active" and "inactive" and to move elements between the two lists.
But if each of your elements already has an "active" flag, then you shouldn't need to move elements around.
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 5:51 pm
by cval
Also a note about removing table entries in a loop - you have to count backwards to avoid loop jumps.
Code: Select all
for i=count,1,-1 do
if objectsArray[i].active == true then
table.remove(objectsArray,i)
end
end
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 6:00 pm
by Strutyk
Now is:
in load
Code: Select all
table.insert(mansPool, manOne)
table.insert(mansPool, manTwo)
table.insert(mansPool, manThree)
table.insert(mansPool, manFour)
in update
Code: Select all
timer = timer + (1 * dt)
if timer >= 3 then
timer = 0
rand = mansPool[math.random(#mansPool)]
randName = rand.name
rand.active = true
end
in draw
Code: Select all
love.graphics.print(randName, 10, 10)
Now, every 3 seconds, we get the name of the object
Approximately I understand that there should be something like:
Code: Select all
timer = timer + (1 * dt)
if timer >= 3 then
timer = 0
rand = mansPool[math.random(#mansPool)]
if(rand.active == false) then
rand.active = true
table.insert(mansArray, rand)
elseif (rand.active == true) then
rand = mansPool[math.random(#mansPool)]
else
print("All mans is out")
end
end
for i, man in ipairs(mansArray) do
man.X = man.X - 128 * dt
if man.X < 0 then
man.active = false
table.insert(mansPool, i)
table.remove(mansArray, i)
end
man.anim:update(dt)
end
But, how to correct check whether the rand object is active or not?
My brains do not work today
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 8:12 pm
by pgimeno
@Strutik:
I guess you want to remove it from the pool so that it isn't a candidate to be picked up at random the next time? If so, strictly speaking, it's not necessary to remove it from the table, but I agree it would be simpler in your case to do that.
After picking one at random, you can do:
Code: Select all
rand = mansPool[math.random(#mansPool)]
randName = rand.name
rand.active = true
for i = 1, #mansPool do
if mansPool[i] == rand then
table.remove(mansPool, i)
break
end
end
(No need to count backwards in this case since we're not mass-removing).
@Ivan:
Sorry to be pedantic, the actual name in Lua is
sequence, see
http://www.lua.org/manual/5.2/manual.html#3.4.6
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 8:54 pm
by Strutyk
pgimeno - Thank you! The 'picture' has cleared up a bit, but now I can't correctly add a remote object in mansPool a table
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 9:32 pm
by pgimeno
What do you mean by a remote object? To add something to a table, you can just do: mansPool[#mansPool+1] = something, or use table.insert like you did.
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 9:50 pm
by Strutyk
my update function:
Code: Select all
timer = timer + (1 * dt)
if timer >= 3 then
timer = 0
rand = mansPool[math.random(#mansPool)]
table.insert(mansArray, rand)
end
for i = 1, #mansPool do
if mansPool[i] == rand then
table.remove(mansPool, i)
break
end
end
for i, man in ipairs(mansArray) do
man.X = man.X - 128 * dt
if man.X < 0 then
table.insert(mansPool, man)
table.remove(mansArray, i)
end
man.anim:update(dt)
end
But after all 4 man's move, тew men do not come from mansPool
Re: Objects table(active/inactive) - removing and adding
Posted: Sat May 07, 2016 10:24 pm
by pgimeno
I don't understand what you're trying to achieve. The way you've written your update function, you're attempting to remove one every frame. I doubt that that's what you want. Furthermore, every 3 seconds you're inserting one of the elements of the array back into the array, rather than the one you removed earlier. I doubt you want that.
Here's how I'd do it.Depending on how many you want active at the same time, you may need a variable holding a man, or a sequence of men. This considers you only have one active:
Code: Select all
local mansPool = { (put here your 4 men) }
local activeMan = nil
local function activateMan()
-- If there is already an active man, don't do anything.
if activeMan then return end
activeMan = table.remove(mansPool, love.math.random(1, #mansPool))
activeMan.active = true
end
local function deactivateMan()
-- don't do anything if there's no active man
if activeMan == nil then return end
mansPool[#mansPool+1] = activeMan
activeMan = nil
end
Then call activateMan() or deactivateMan() as appropriate. I don't know when you want them to activate or deactivate.
In draw, you can directly use love.graphics.print(activeMan.name, 10, 10); you don't need an extra variable. But you first need to check if activeMan is nil.
If you want more than one active at a time, instead of activeMan being a man, you'd have activeMen being a sequence of men, and manage it very much like mansPool.
Not sure if that makes sense for your purpose.