So, as I've posted help about before, I am rewriting a level editor for my game. I'm working on placing (placing is done, actually) and now I need to work on deleting tiles. My code right now is a for loop that gets the length of the tiles table (where all the data is stored) and then draws that tile there. I want to use table.remove to delete a tile but.. (prepare for a bad explanation)
Say tiles has a length of ten. If I remove tile #5, tiles now has a length of 9, but still has tile #10. Problem is, this for loop will not reach that 10th tile, because it runs for only 9. How do I get it to accommodate for this? A variable?
I hope I explained it well enough for you to understand. Before, it would set the tile's ID to 0 (which was a blank image), but kept it's X and Y. Problem with this is then that tile is there forever, and eventually will slow the editor down if a large map is being built, and one needs to delete tiles.
Thanks!
-Eric
Odd Table Math Dilemma
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
- MicroMacro
- Citizen
- Posts: 92
- Joined: Fri May 30, 2014 2:30 am
- Location: Boston, MA, USA
- Contact:
Odd Table Math Dilemma
https://github.com/ebernerd- where you can find all my work.
Re: Odd Table Math Dilemma
I wonder why do you need "id" field at all?
Your table "tiles" is a simple indexed array so "tile[tiles.id]" is the same as "tile".
EDIT: I'm little lost in your data structure...
EDIT: I'm little lost in your data structure...
- MicroMacro
- Citizen
- Posts: 92
- Joined: Fri May 30, 2014 2:30 am
- Location: Boston, MA, USA
- Contact:
Re: Odd Table Math Dilemma
So, tiles is a table that holds all the data for my tiles.
tiles[1] holds all the information for tile #1.
It looks like this:
tiles[1].x = 10
tiles[1].y = 10
tiles[1].id = 1
So, if I have 10 tiles (1-10), and remove tile #5, I have tiles 1,2,3,4,6,7,8,9,10, which is 9 objects. That for loop only does "for i=1,#tiles do" (which would be 9). So, it would draw 1,2,3,4,6,7,8,9 (skips over the empty 5), but not for the 10 tile. How do I accommodate for that?
tiles[1] holds all the information for tile #1.
It looks like this:
tiles[1].x = 10
tiles[1].y = 10
tiles[1].id = 1
So, if I have 10 tiles (1-10), and remove tile #5, I have tiles 1,2,3,4,6,7,8,9,10, which is 9 objects. That for loop only does "for i=1,#tiles do" (which would be 9). So, it would draw 1,2,3,4,6,7,8,9 (skips over the empty 5), but not for the 10 tile. How do I accommodate for that?
https://github.com/ebernerd- where you can find all my work.
Re: Odd Table Math Dilemma
If you remove 5th element from t = {"1", "2", "3", "4", "5", "6", "7", "8"} (#t = 8) for example
then table becomes simply {"1", "2", "3", "4", "6", "7", "8"} with 7 elements so #t becomes = 7
Your for i = 1, #t loop will always reach all elements (if table contains only integer keys).
IMHO Problem is that you use "id" field, which of course becomes outdated after removing element.
IMHO tile[1].id = 1 is useless.
You can use other loop types (like "foreach" loop in other languages):
OUTPUT:
******************
simple loop:
1 Fire
2 Water
3 Air
4 Earth
foreach with only integer keys:
1 Fire
2 Water
3 Air
4 Earth
foreach with non-integer keys:
water Water
fire Fire
earth Earth
air Air
********* AFTER REMOVING 2ND ELEMENT ("water") ********
simple loop:
1 Fire
2 Air
3 Earth
foreach with only integer keys:
1 Fire
2 Air
3 Earth
foreach with non-integer keys:
fire Fire
earth Earth
air Air
P.S. Table can be mixed with integer and non-integer keys (table with 2 parts).
then table becomes simply {"1", "2", "3", "4", "6", "7", "8"} with 7 elements so #t becomes = 7
Your for i = 1, #t loop will always reach all elements (if table contains only integer keys).
IMHO Problem is that you use "id" field, which of course becomes outdated after removing element.
IMHO tile[1].id = 1 is useless.
You can use other loop types (like "foreach" loop in other languages):
Code: Select all
-- indexed array (all keys are integers)
t = {}
t[1] = "Fire"
t[2] = "Water"
t[3] = "Air"
t[4] = "Earth"
-- hash table
t2 = {}
t2["fire"] = "Fire"
t2["water"] = "Water"
t2["air"] = "Air"
t2["earth"] = "Earth"
function show()
print("\nsimple loop:\n")
for i = 1, #t do
print(i, t[i])
end
print("\nforeach with only integer keys:\n")
for k, v in ipairs(t) do
print(k, v)
end
print("\nforeach with non-integer keys:\n")
for k, v in pairs(t2) do
print(k, v)
end
end
print("******************")
show()
table.remove(t, 2)
t2["water"] = nil
print('\n ********* AFTER REMOVING 2ND ELEMENT ("water") ********')
show()
******************
simple loop:
1 Fire
2 Water
3 Air
4 Earth
foreach with only integer keys:
1 Fire
2 Water
3 Air
4 Earth
foreach with non-integer keys:
water Water
fire Fire
earth Earth
air Air
********* AFTER REMOVING 2ND ELEMENT ("water") ********
simple loop:
1 Fire
2 Air
3 Earth
foreach with only integer keys:
1 Fire
2 Air
3 Earth
foreach with non-integer keys:
fire Fire
earth Earth
air Air
P.S. Table can be mixed with integer and non-integer keys (table with 2 parts).
Re: Odd Table Math Dilemma
Hi Micromacro,
what you want to do can be achieved with table.remove.
However, for tiles it is a good idea to use the index as coordinates directly. Instead of numbering tiles arbitrarily by the order they are created, number them by their coordinates. Here is an example of the idea:
This is what you have:
Instead I suggest this kind of notation:
That way the memory structure resembles the spatial structure of the tiles. Image you have some coordinates and want to find out, what kind of tile there is. In you notation, you would need a for loop to check of all tiles and you have to compare the coordinates to the given ones. In my suggested way, you can immediately access the id of a tile at any position.
This was a very short explanation. If you need to know more, please ask.
what you want to do can be achieved with table.remove.
Code: Select all
a = {'one','two','three','four'}
for i,v in ipairs(a) do
print(v)
end -- prints one, two, three, four
table.remove(a,3) -- remove the third entry
for i,v in ipairs(a) do
print(v)
end -- prints one, two, four
This is what you have:
Code: Select all
tile[1].x = 3
tile[1].y = 4
tile[1].id = 7
Code: Select all
tile[3][4] = 7
This was a very short explanation. If you need to know more, please ask.
Check out my blog on gamedev
Re: Odd Table Math Dilemma
Sometimes keeping redundant data like the x and y values is reasonable. The storage of the id is what really makes no sense (to me).
The actual problem he has is the deletion in a loop over a same table. The easiest solution is this one:
You might even think about using a "set" type table to hold all types if the index was only there to access an item without a search:
The actual problem he has is the deletion in a loop over a same table. The easiest solution is this one:
Code: Select all
for i=#tbl,0,-1 do -- go back-to-front
if shouldRemove(tbl[i]) then
table.remove(tbl, i)
end
end
Code: Select all
-- insertion:
local newTile = { x=15, y=46 }
tbl[newTile] = newTile
-- deletion:
tbl[sometile] = nil
-- iterarion:
for tile,_ in pairs(tbl) do
tile:doSomething()
end
- MicroMacro
- Citizen
- Posts: 92
- Joined: Fri May 30, 2014 2:30 am
- Location: Boston, MA, USA
- Contact:
Re: Odd Table Math Dilemma
I completely forgot to tell you all that the ID is for the type of tile it is. I've got a bunch of different tile images that it goes through. Tile ID #1 is grass.
Woops. :\
Woops. :\
https://github.com/ebernerd- where you can find all my work.
- MicroMacro
- Citizen
- Posts: 92
- Joined: Fri May 30, 2014 2:30 am
- Location: Boston, MA, USA
- Contact:
Re: Odd Table Math Dilemma
Here's that for loop that's wrong:
Sorry about that.
Code: Select all
function editor.drawWorld()
for i=1, #tiles do
if tile[tiles[i].id] ~= nil then
love.graphics.draw(tile[tiles[i].id],tiles[i].x,tiles[i].y)
end
end
end
https://github.com/ebernerd- where you can find all my work.
- kikito
- Inner party member
- Posts: 3153
- Joined: Sat Oct 03, 2009 5:22 pm
- Location: Madrid, Spain
- Contact:
Re: Odd Table Math Dilemma
I would just create a new type of tile called "empty" or "void". Instead of "removing the earth tile" from position 6, replace it with an empty tile, doing something like tiles[6] = emptyTile. emptyTiles are like regular tiles, except that they don't do nothing when drawn, they don't collide with anything, etc.
Your world size remains the same all the time and you don't have to fight with indexes at all. As a bonus point, inserting tiles is also very easy, and you can start with a map with holes on it.
Your world size remains the same all the time and you don't have to fight with indexes at all. As a bonus point, inserting tiles is also very easy, and you can start with a map with holes on it.
When I write def I mean function.
Who is online
Users browsing this forum: No registered users and 48 guests