Log In  

Im having a bit of trouble understanding how to use tables, I'm quite new to programming so I took some code from Dylan Bennett who made some excellent tutorials on pico-8.

I'm using a table to create bills on screen and then delete them one by one from the screen.

So far so good.

But now I want to make a cursor that blinks on the last bill in the table, then after deletion, the cursor would hover on the next last bill in the table.

To make that work I would need the X and Y coordinates of the last placed bill and the ones following after that.

That's where I get into trouble. I'm using this function to set up the bills coordinates and sprite;

function make_bill(x,y)
    b={}
    b.x=x
    b.y=y
    b.sprite=rnd(3)+3 
    add(bills,b)
end

Then I use this to create the bills;

function make_bills()
    bills={}
    for i=1,100,1 do
        make_bill(32+rnd(56),32+rnd(56))
    end
end

But when I use a debug to find the b.x and b.y values it returns a fixed number that doesn't change as I delete the bills. Also checking in debug shows that the table b = 0.

I don't understand how to get the b.x and b.y values for each bill and am not even sure if these values are stored for each bill I create. To me it seems like the table b only stored the last created b.x and b.y values because they were simply overwritten in the creation of the other bills.

Maybe I'm not really understanding how tables work.

Any help would be greatly appreciated!

Thanks in advance!

Oh and here is my full code stack for clarity;

function _init()
    cls()
end

function _update()
    start_set()
    pop()
end

function _draw()
    cls()
    foreach(bills,draw_bill)
    debug()
end

function drawcursor()

end

function pop()
    poke(0x5f00+92,255)
    if btnp(🅾️) then
        deli(bills)
    end
end

function debug()
    if bills~=nil then
        print(#bills,0,0,7)
        returnxy(b)
    end
end

function start_set()
    poke(0x5f00+92,255)
    if btnp(❎) then
        make_bills()
    end
end

function make_bills()
    bills={}
    for i=1,100,1 do
        make_bill(32+rnd(56),32+rnd(56))
    end
end

function make_bill(x,y)
    b={}
    b.x=x
    b.y=y
    b.sprite=rnd(3)+3 
    add(bills,b)
end

function draw_bill(b)
    spr(b.sprite,b.x,b.y,1,2)
end

function returnxy(b)
    print(b.x,0,7,7)
    print(b.y,0,14,7)
    print(#b,0,21,7)
end
P#96181 2021-08-18 14:35

I'm not sure that I understand the exact problem, but I am pretty sure that you "mixed up" some informations about Tables in PICO8.

There was a Thread on the BBS which explains Tables better:
https://www.lexaloffle.com/bbs/?tid=42109

P#96192 2021-08-18 16:34 ( Edited 2021-08-18 16:37)

@borsjt

So there's a couple problems that I can see.

In make_bill, when you type this:

b={}

You're defining a global variable called b. This continues to exist even after the function exits and each time you call the function each new bill is assigned to that same variable b.

In your debug function where you're do this:

returnxy(b)

That 'b' is the global 'b' of which there is only one, the most recently created one. You're not looping through the table of bills, you're just printing the last one.

The 'add' function, apparently, creates a copy of 'b' before adding it to the table which is why all the bills display correctly on screen when you press ❎ and why they pop off correctly when pressing 🅾️.

Also:

print(#b)

Always prints zero because the table 'b' has text indices (x, y, sprite) and not number indices so '#' doesn't know what to count so it counts 0.

The fix is pretty easy.
First, just to keep from polluting the global namespace you can do this in 'make_bill':

local b={}

That's optional but it just makes it so 'b' doesn't exist outside of 'make_bill'. If you do that, you'll notice that 'returnxy' stops working and complains about 'b' being nil because when you call 'returnxy' from 'debug' that 'b' no longer exists. If you really want to see the x,y of all bills you'll need to loop through the bills array, either with a normal for loop or with foreach. The following will loop through all the bills in the reverse order:

for i=#bills,1,-1 do
    returnxy(bills[i])
end

Though the way you've got returnxy set up the values will just overwrite themselves on screen.

Anyway, the point is, to get the individual bills you'll need to index into the bills array using the square bracket notation. To get the last bill in the list do this:

some_bill = bills[#bills]

The one before that will be bills[#bills-1] and the one before that bill[#bills-2] and so on.

If you want them in the order they were created then the first bill is bills[1] the second is bills[2], etc.

Hope that helps.

P#96198 2021-08-18 18:18

a couple of things:

  1. you forgot "local" on this variable:

    function make_bill(x,y)
    local b={}
    b.x=x
    b.y=y
    b.sprite=rnd(3)+3 
    add(bills,b)
    end

    variables in Lua are global by default unless you specify local so it's important to remember to use "local"; it's kind of like "var" in javascript.

  2. if you want to always get the last bill, you should be using bills[#bills]. So if I understand correctly what you are trying to do, I think what you want to change "returnxy(b)" to "returnxy(bills[#bills])"
P#96199 2021-08-18 18:19

@jasondelaat @kittenm4ster thank you for trying to help me.

I feel like it's a lot to wrap my head around and I wasn't even aware I created an array. I will need to maybe look closer at the Lua documentation to get a grip on things.

@jasondelaat

I'm trying to implement your code but don't really understand where to put the code you wrote down

for i=#bills,1,-1 do
    returnxy(bills[i])
end
some_bill = bills[#bills]

Could you maybe make it so I can put it directly in my code? I feel kinda bad for asking but I can't find how to use it in my own code, maybe I'm not yet ready for this hahaha

P#96203 2021-08-18 18:52

@borsjt
Sorry about that!

The for loop goes into the debug function:

function debug()
    if bills~=nil then
        print(#bills,0,0,7)
        for i=#bills,1,-1 do
          returnxy(bills[i])
        end
    end
end

But you don't really need this. 'returnxy' is going to print them all at the same location on screen so what you'll probably see, instead of a bunch of numbers, is just a bunch of white boxes, kind of like if you had a bunch of numbers printed on plastic sheets and stacked them all together.

If you really want to see all the numbers you can change returnxy like so:

function returnxy(b)
    print(b.x)
    print(b.y)
end

Actually you won't see all the numbers because they'll scroll off the screen but it should at least convince you that you are creating a bunch of different bills. Once you're happy of that fact I'd just delete 'debug' and 'returnxy' entirely since you don't actually need them.

The other piece of code doesn't go anywhere in particular, it's just demonstrating how to access individual bills.

An array, in Lua, is just a table except all the indices are numbers. The 'add' function adds a new item to a table at the next available numerical index. So, when you create the 'bills' table (bills={}) it has no indices. When you 'add(bills, b)' the first time the new bill (b) goes into bills table/array at index 1. When you 'add(bills, b)' the second time, that one goes into index 2 and so on. Then you can access them by index: bills[1] or bills[2], etc.

So, wherever it is that you want to check the x and y coordinate of a bill you can do:

bills[1].x
bills[1].y

Which are the x and y coordinate of the first bill.

bills[2].x
bills[2].y

Are the x and y coordinate of the second bill, etc.

To make it easier you can assign that to a variable first:

some_bill = bills[1] -- assign the first bill to variable 'some_bill'
some_bill.x  -- then access the x coordinate
some_bill.y  -- and the y coordinate

So those are also the x and y coordinates of the first bill.

The '#' operator returns the number of elements in an array. So, if your array has 20 bills in it then #bills will be 20. If it has 47 bills in it then #bills will be 47. So the expression 'bills[#bills]' is the last bill in the bills array. I hope that made sense.

Otherwise, since I don't know exactly what it is you're trying to do, I can't really help much but don't hesitate to ask if you're not able to get things working the way you want. Don't feel bad, everybody's got to start somewhere. You're doing fine.

P#96209 2021-08-18 20:02
1

@jasondelaat

This is a HUGE help, thank you so much!!

In the end what I needed was quite simple; the correct way to access the indeces of the X and Y coordinates of the bills!

Your:

bills[1].x
bills[1].y

I turned into:

function debug()
    if bills~=nil then
        print(bills[#bills].x,0,0,7)
        print(bills[#bills].y,0,7,7)
    end
end

This prints out the X and Y coordinates and also updates them when I remove an indice from the bills table, amazing stuff!

Turning it into a variable is very neat too, I'm sure I will be using that somewhere in the near future :)

Again, thank you so much!

P#96211 2021-08-18 20:38 ( Edited 2021-08-18 20:39)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-29 10:03:14 | 0.035s | Q:18