Wow, two weeks goes by fast. Lots of paperwork and foolishness keeping me busy this last half month, but some work did get done. I had gone over some random implementation details last time and gave a quick overview of what was coming.
Well, I stuck to my word. As hinted at in the last post, the latest developments worthy of mention are in the following three areas:
- reworking of the component sprite system
- camera system
- straightening out the input system
Items 2 and 3 aren’t that interesting; the camera system stores a list of all local player-controlled bruisers and centers them on the screen within some defined tolerance; there’s an acceptable rectangular area in the middle of the screen when a bruiser can be, and if they attempt to move out of this area, the screen will follow them, slowly and first and quickly as the player continues to move toward the edge of the screen. I’ve prototyped this in other games, and I think it will work great this time around. …But, more on that next time when there’s something to demonstrate.
The composite sprite system is kind of fun, so I’ll go over how it’s implemented.
Essentially sprite data is sorted into sprite sheets and information about the sprite data is parsed and stored in memory for the loaded sprites on any given level. This ‘sprite data’ would be things like a sprite’s X and Y offset into the sheet, the width and height, a unique identifier, etc. There is also a separate dataset describing animations in terms of sets of sequences of “composite sprite data”, frame-durations, and characteristics (pause on last frame, loop, etc). Standard stuff here, except for two points: firstly, the bruisers are customizable, meaning that they’ll need to be constantly built of different parts on the fly, and secondly the application of a final outline to the characters.
Character sprites will be built of composite sprite data, which would be data sets of Z-ordered sprite IDs that make up a character ( as an example, from closest to farthest, hair + head + arms + body + legs ), as well as each part’s offset from the base of the character.
Breaking up tha’ bruisers
Since every sprite is now be treated as a separate entity, entire character sprites will just be built out of all the parts at run time continuously. The final tricky part of this is how to place an outline as previously mentioned. Basically, we do the following:
- For every component (head, body, etc), there is a corresponding set of per-pixel outline-mask data that essentially marks which pixels are outlines to be written black if they fall on the sprite’s border. They also mark all other non-transparent pixels as “no-touch”.
- As a composite sprite is built, another data set (the mask data) is compiled on the side as a sum of all the mask data associated with the different parts of the composite sprite. Each pixel in the final sprite will be marked as transparent, outline, “no-touch”, or overlapping outline and no-touch.
- Once the composite sprite is complete and produced as a texture to be rendered, the outline is applied using the now-complete mask data by drawing every pixel from the outline mask that is marked as “outline” and isn’t marked as “no-touch”. This produces an outline around the sprite that does not enter “into” the sprite over top of non-outline sprite data, ie, the neck and chin area. Or something.
Or more descriptively: Like this!
This ends the solitary late night work session + blog post for this week! So much for actually getting any sleep (or gaming time). Looks like Star Tropics 2 will have to wait for another night.