If you feel like you don't understand Lua's tables, I hope this post helps. I use tables all the time when I'm programming; they are super useful. Let's study them so you can use them too!
Tables can do several different things, which makes them a bit tricky. We'll start by exploring a common use: using tables to store a list of things, such as:
- A hand of cards: 2♠, 3♥, Q♦, K♣, J♣
- A list of monsters: Ogre, goblin, slime mold
- The positions of all the black checkers: 12, 24, 20, 27
Making lists
This makes an empty list:
items={} |
This makes a list with the names of some things found in a forest:
items={'tree', 'rock', 'stream'} |
Now items
contains 3 things; you can think of it like 3 boxes:
The first box contains 'tree', the second contains 'rock', the third contains 'stream'.
Getting items out of a list
Each box has a number, called its "index". To get the value from the first box, we do items[1]
like this:
> print(items[1]) tree |
We can also store the index in a variable, like this:
> current_index=1 > print(items[current_index]) tree |
To pick a random item from a list, we can use rnd():
> print(rnd(items)) stream > print(rnd(items)) tree |
Changing items in a list
We can change the value stored in a box by using its index. Here's how to replace 'rock' with 'moss':
> items[2]='moss' |
Length of a list
To get the number of items in a list, we use #items:
> length=#items > print(length) 3 |
Here's a common way to get the last item of the list. It uses the list's length as an index:
> print(items[#items]) stream |
Adding items
Items can be added to a list using add().
This adds to the end of the list:
add(items, 'mushroom') -- adds at end |
This adds at the start of the list:
add(items, 'wolf', 1) -- adds at index 1 |
Deleting items
We can delete items by value:
del(items, 'tree') |
or by index:
deli(items,2) |
Looping over a list
We can access every item in a list using a for loop and all():
for item in all(items) do print(item) end |
That would print this:
wolf stream mushroom |
If you need the index too, you can use a numeric for loop from 1 up to the length of the list:
for i=1,#items do print(i..': '..items[i]) end |
That would print this:
1: wolf 2: stream 3: mushroom |
Ok, that's it for lists.
Wow, that turned out longer than I expected. I also want to explore using tables to store dictionaries, but before I do, does anyone have any questions? Or feedback? Is this useful? Would it be better with more (or less) detail? Let me know what you think...
I feel like making a set of tutorial carts. What topic would help people the most?
I was thinking of a simple introduction to math for games, since that topic comes up frequently on the forums. Or maybe how to do collision detection? I see people asking about that fairly often too.
Any thoughts? Or suggestions of a topic? Would you find this useful?
King Minos has thrown you into the minotaur's labrynth! Can you kill the minotaur, rescue your fellow Athenians, and find your way out of the labrynth?
Controls:
Arrows to move.
Z to attack.
3D texture mapping with tline (plus some other stuff, like wireframe rendering, and solid color polygon rendering). Did this as a learning project, to study old-school pre-GPU 3D graphics.
Thanks to freds72 and johanp for inspiration & example code.
References if you want to learn.
http://www.multi.fi/~mbc/sources/fatmap2.txt
https://chrishecker.com/miscellaneous_technical_articles#perspective_texture_mapping
https://www.cs.cmu.edu/~fp/courses/graphics/pdf-color/14-raster.pdf
https://en.wikipedia.org/wiki/digital_differential_analyzer_(graphics_algorithm)
https://en.wikipedia.org/wiki/selection_sort
https://en.wikipedia.org/wiki/sutherland%e2%80%93hodgman_algorithm
Book: "Computer Graphics: Principles and Practice 2nd ed."
I'm trying to use anonymous inline functions and I'm finding some weird behavior when they are on tabs.
Putting everything in tab #0 works:
x=1 function _draw() cls(1) print('x is '..x) end (function() x=2 end)() |
And moving the inline function call to tab #1 works:
x=1 function _draw() cls(1) print('x is '..x) end -->8 (function() x=3 end)() |
But putting an inline function call on both tab #0 and tab #1 does not work:
x=1 function _draw() cls(1) print('x is '..x) end (function() x=2 end)() -->8 (function() x=3 end)() |
I don't understand why. It gives this error:
runtime error line 7 tab 0 (function() attempt to call a nil value at line 7 (tab 0) |
I'm trying to figure out why this cart only runs at 10 FPS on a Raspberry Pi Zero. stat(1) returns 0.49 and stat(7) returns 30. However, the screen is only updating at 10-11 FPS. Other carts with higher stat(1) values don't show this problem, so it seems specific to something in this cart.
I can optimize to get the CPU usage down to 17%, and then the real framerate becomes acceptable. However, I'd actually like to understand why it is slow so I can work around it. (Also, I'd prefer to be able to use the whole CPU budget instead of just 17% of it!)
I assume what's happening is that the pico-8 CPU costs are optimistic for some instructions, and the actual cost on the Pi Zero hardware is higher. But which instructions?
Are there specific instructions I should be avoiding?
Are there specific types of drawing (like large map areas, or off-screen drawing) I should avoid?
Can I hook up a profiler to see what it is spending its time on?
The original raspberry pi post (https://www.lexaloffle.com/bbs/?tid=3085) says math-heavy carts run slowly. Is that still true?
Are there any performance tricks for writing carts that run well on a raspberry pi?