This is a guide for how sprite data is stored, parsed, and drawn to the visual canvas in GameStartr projects. It's built on the PixelDrawr and PixelRendr modules.
A GameStartr instance's PixelRendr keeps sprite data stored as a library using a StringFilr. Each sprite is stored as a series of numbers that represents the ordered pixels in a rectangle.
"00000001112"
A mapping of which numbers represent which color are stored in a global "palette".
[
[0, 0, 0, 0], // transparent
[255, 255, 255, 255], // white
[0, 0, 0, 255], // black
// ... and so on
]
Using the above palette, the sprite represents seven transparent pixels, three white pixels, and a black pixel.
Most images are much larger and more complex so a few compression techniques are applied.
-
It is necessary to have a consistent number of digits in images, as
010
could be[0, 1, 0]
,[0, 10]
, or etc. Palettes with more than ten colors therefore have to prefix single-digit numbers with0
. For example,[1, 14, 1]
would use["01", "14", "01"]
:"011401011401011401011401011401011401011401"
We can avoid this wasted character space by instructing a sprite to only use a subset of the pre-defined palette:
"p[1,14]010010010010010010010"
The
p[0,14]
tells the renderer that this sprite only uses colors 0 and 14. The number 0 then refers to palette number 1 and the number 1 should refer to palette number 14. -
Take the following wasteful sprite:
"p[0]0000000000000000000000000000000000000000000000000"
We know the 0 should be repeated 35 times, so the following notation is used to indicate "repeat ('x') 0 35 times (','))":
"p[0]x035,"
-
Filters
Many sprites are different versions of other sprites, often simply identical or miscolored (the only two commands supported so far). A library may declare a filter:
"Sample": [ "palette", { "00": "03" } ]
...along with its sprites:
"foo": "p[0,7,14]000111222000111222000111222", "bar": [ "filter", ["foo"], "Sample"]
The
"bar"
sprite will be a filtered version of foo, using the"Sample"
filter. The"Sample"
filter instructs the sprite to replace all instances of"00"
with"03"
, making"bar"
equivalent to:"bar": "p[3,7,14]000111222000111222000111222"
Another instruction you may use is
"same"
, which is equivalent to directly copying a sprite with no changes:"baz": [ "same", ["bar"] ]
-
"Multiple" sprites
Sprites are oftentimes of variable height. Pipes in Mario, for example, have a top opening and a shaft of potentially infinite height. Rather than use two objects to represent the two parts, sprites may be directed to have one sub-sprite for the top/bottom or left/right, with a single sub-sprite filling in the middle. Pipes, then, would use a top and middle.
[ "multiple", "vertical", { "top": "{upper image data}", "bottom": "{repeated image data}" } ]