table question

I am still having a lot of trouble wrapping my head around tables. Here is what I want to do. I want to create 8 sprite images (girders) side by side so the only thing that varies is the x-position. This seems like a perfect opportunity to practice tables but I’m not sure how to do it. Here is what I have done:

In my function setup() I have created a new table G: so…


function setup()

G={}

gsX=100 – x start postion

gsY=130 – y start postion

girderSpace=64 – length of each girder in pixels

end

then I created a new function to make girders and put them in the G table…

function CreateGirder()

g={}

for i=0,8 do

gsX=gsX+girderSpace*i

table.insert(G,g)

end

end

So now my question is this. To draw each girder I created an instance of my Girder class called girder. The Girder class takes the parameters, startX,startY, and scale. How do I unpack my table and have Girder Class put in the correct parameters from the table?

I really hope the above makes sense

just an example:

function setup()
    Girders = {} -- all girders positions
    
    local gsX = 100 -- x start postion
    local gsY = 130 -- y start postion
    local space = 64 -- length of each girder in pixels
    
    for i = 1, 8 do
        table.insert(Girders, vec2(gsX + space * i, gsY))
    end
end

function draw()
    background(40)
    
    for _, pos in ipairs(Girders) do
        rect(pos.x, pos.y, 50)
    end
end

you dont need any classes for this to work, and actually even no function, because the loop is a funktion itself. but if you want to:

local function createGirders()
    local Girders = {} -- all giders positions
    
    local gsX = 100 -- x start postion
    local gsY = 130 -- y start postion
    local space = 64 -- length of each girder in pixels
    
    for i = 1, 8 do
        table.insert(Girders, vec2(gsX + space * i, gsY))
    end
    
    return Girders
end

local function drawGirders(fromTable)
    for _, pos in ipairs(fromTable) do
        rect(pos.x, pos.y, 50)
    end
end

function setup()
    girdersList = createGirders()
end

function draw()
    background(40)
    drawGirders(girdersList)
end

Make variables local, if they are not used across the whole project. - Saves you some RAM and doesnt produce to much junk.

tables have keys vor their values. Those can be ordered (numbers) or just strings.
In your case you have not to borther with this. Just use vec2, which is made for positions. vec2 is basically a table itself, and stores x and y values like that:

{
    x = 100,
    y = 130
}

When using vec2 with table.insert(Girders, vec2(gsX + space * i, gsY)) this produces something like:

{
    [1] = {
        x = 164,
        y = 130
    }
}

notice the keys start at 1, and thats why your for loops should start with: for i = 1, 8 do. If dont, your first x position would be calculated like gsX + space * 0, where i is 0, which might be what you want, or not. Its up to you here, but have in mind.

After you precalculated all positions of all your girders, you have to draw them. Again, you have to loop through the table, but this time through the one with all the positions, which is Girders or girdersList in my examples.

So basically you need two for loops. One for creating your girders and another for drawing all of them. I would even reduce it to one loop and calculation everything live, because this calcs are not to expensive on such a small example…


If you still want to use classes:

Girders = class()

function Girders:init(startX, startY, startScale)
    self.girders = {} -- all giders positions
    self.gsX = startX -- x start postion
    self.gsY = startY -- y start postion
    self.gsS = startScale
    self.space = 64 -- length of each girder in pixels
    
    self:create()
end

function Girders:create()
    for i = 0, 8 do
        local template = {
            scale = self.gsS * i,
            pos = vec2(self.gsX + self.space * i, self.gsY)
        }
        table.insert(self.girders, template)
    end
end

function Girders:draw()
    for _, girder in ipairs(self.girders) do
        local size = 10
        rect(girder.pos.x, girder.pos.y, size * girder.scale)
    end
end


function setup()
    girders = Girders(100, 130, 1)
end

function draw()
    background(40)
    girders:draw()
end

wow! thank you so much for explaining that so well. That really clears it up

Your welcome. Tables are rough, I had a hard time to understand them myself, but as soon as you get them to know, they seem really easy and straight forward. Just keep practicing and asking)

@velkroe Just in case you want to do multiple levels of girders, here’s an example.

supportedOrientations(LANDSCAPE_ANY)
displayMode(FULLSCREEN)

function setup()
    tab={}
    xSize=52
    ySize=100
    for x=1,19 do
        for y=1,7 do
            table.insert(tab,vec2(x*xSize,y*ySize))
        end
    end
end

function draw()
    background(40, 40, 50)
    for a,b in pairs(tab) do
        sprite("Cargo Bot:Loading Bar",b.x,b.y,50)
    end
end

Thanks again for this. This really clears up tables for me.