In the game I'm building, I often have a need for an entity to basically make the map solid and impassable at a given location, but in the actual map editor these spaces would all be empty. Since the "flags" all reside in sprites, it seems the only way I could have dynamic collision flags or other metadata would be to use my own collision map. It would first be built from the map itself, then used dynamically thereafter by entities that need it.
It seems like a sensible thing to do and I am curious if anyone else has done this for similar reasons.
It depends on how much sprite space you have left, but.. you could always just have multiple copies of a sprite with different flags. And use mset/mget as needed.
The other way would be to make a 2d array with those sorts of things..
map={} for x=0,#mapwidth do map[x]={} for y=0,#mapheight do map[x][y]=0 //use bitflags just like sprite flags end end |
Then to set or check a flag, do this..
//save flags using bits; same as sprite flags blocked_flag = 0b00000001 map[x][y] = bor(map[x][y], blocked_flag) //check flags using bits to see if the tile is blocked; same as sprite flags blocked_flag = 0b00000001 map[x][y] = band(map[x][y], blocked_flag) //to un-save a flag using bits, you do this to get an inverse and then band() with that; same as sprite flags blocked_flag = 0b00000001 inverted_blocked_flag = bxor(blocked_flag,0b11111111) map[x][y] = band(map[x][y], inverted_blocked_flag) |
I would think multiple copies of a sprite with different flags could be wasteful given how tight pico 8's rom is. But using a lua table seems pretty sensible since there's a lot of ram available for general lua usage. Thanks.
Plenty of RAM but sadly uninitialized...
There's another solution:
Use half of your map for flags information (this is like a quarter if you use more than 128 sprites), then use tile index as code (this map isn't rendered but serve as flags), you can access that with mget(celx, cely)
Disadvantage is that you have even less map space but in other hand you don't need to get out of the map editor and no need of any special tool at all!
Hint: You can swap spritesheet into a code one while editing to make your metadata painting easier. (careful while swapping! you can easily destroy either the last 128 sprites or the bottom half map easily!)
...and continuing with enargy suggestion:
Map in RAM as 2D array... you can either initialize with a const table (very wasteful due to limited tokens) or as string (cost like 1 token for a huge string! You can convert each string character as a code).
For simplicity you can have 1 character == 1 tile and break your string in lines, then map your codes with characters, that will cost like 2 tokens per line but still way better than 1 token per tile!
// A 8x4 map as string, readable and easily editable map_str = "11111111".. "10002001".. "10002001".. "11111111" |
If you don't care about readability you can finish off by merging all lines into 1 huge string but I only recommend doing that if you are really tight with tokens... if your map is big you'll most likely be fighting with compressed size ratio anyway.
Here's example codes of how to convert your string map:
// Index between 0 to w-1 (C way) function loadmap(str,w,h) map={} for x=0,w-1 do map[x]={} for y=0,h-1 do local i=y*w+x+1 map[x][y]=sub(str,i,i) end end end |
// Index between 1 to w (LUA way) function loadmap(str,w,h) map={} for x=1,w do map[x]={} for y=1,h do local i=(y-1)*w+x map[x][y]=sub(str,i,i) end end end |
Notice that value will be 1-character string and not a number!
If that's undesirable and want to use numbers instead you can modify line 8 with:
- map[x][y]=tonum(sub(str,i,i)) // Code between 0 to 9: [0-9]
- map[x][y]=tonum("0x"..sub(str,i,i)) // Code between 0 to 15 in hexadecimal notation: [0-9a-f]
Note you can also modify to read 2 of more characters per cell if is not enough!
Also if you're brave enough you can even use compression/decompression or write a special tool to aid on optimizing even more (like 2 or more tiles per 1 character), the choice is yours.
[Please log in to post a comment]