Happy new year! Here’s some dog- and bird-friendly fireworks
Most explosion type animations on classic NES games keep to a 16×16 pixel pattern (that is, 2 by 2 8×8 pixel sprites). There are some ramifications that encourage this, but it’s not a hard limit. The main one being the famed sprites per scanline limit, which means only 8 sprites can be shown at the same horizontal line at any one time, leading to sprite cancellation (or flickering if the programmer has seen to it that the PPU takes turns showing up to 8 at a time). Another is that some game engines limit how an objects’ sprites may be positioned in a compromise between simplicity and utility. And sometimes, that’s what you want.
A bit on the technical side, but for HALCYON i’m simply exporting raw chunks of Object Attribute Memory (OAM) data for each animation cel, which is in a way the simplest and most versatile way to handle metasprite animation. Positions can be made relative by adding object position to the OAM position. Additionally, you can hard-code palette, layer priority and mirror-flip attributes into them to be manipulated (or not), and used (or mask-ignored at will) by the object handler. One way to know where one metasprite ends and another starts is to include a terminator message in the form of a byte after all the metasprite data of an object or animation cel is done. For example, a value of 128 will set off the signed math flag which can be used to determine this, or if you really need bigger offsets than 127, you could let $FF be the terminating value. INC, INX or INY it once, and test the zero bit. The rationale for this is that the first byte is the Y position, and you’re completely unlikely to give any sprite an Y axis offset so great that the metasprite component will be be put offscreen or wrap around to the other side. A metasprite handler like that could use the same object handler for sprite overlays on title screens and the like, aswell as gameplay objects (at the same time even), but i’m getting way off topic.
Anyway, this allows objects to be position animated.
I want the explosion to be 1)big, 2)use no more than 4 sprites at any one time 3)clear itself out of the way to not cause clutter. The first goal is in order to have a satisfying impression on the player after defeating an adversary and to make ”more” than was traditionally done for the console. The second and 3rd goals work together to minimize sprites per scanline over time. Since the 4 sprites spiral outward in a diagonal pattern, they clear themselves away from any frontal position the player character might be likely to have, ie. avoiding taxing the scanlines as fast as possible.
In the video, i’m stepping through some of the animation cels to give a better insight into how i move the sprites.
Since quite a hefty percentage of the total tilespace is used to do smooth main movement animations of the main player character, tile recycling is helpful. The explosion is mostly reusing the same tiles with the help of tile mirroring. Note that the NES PPU can’t properly rotate sprites (not even in 90 degrees), but sometimes mirror-flipping is good enough, as shown in the video. I also figured the 4 first cels of the explosion may be good for for energy obtainables or the like.
The one of the right is made out of 4 sprites, but is only using as many tiles as the one to the right (which is one sprite) thanks to the mirroring bits.
I’m using similar tricks for the pie chart-type meter i posted about earlier.
Here’s the explosion with a more didactic timing, a grid and sprite boundaries, to show what is happening. A nice thing is that the twirly movement lets it expand while not taxing any more than 2 sprites per scanline From the moment it expands into four sprites, it takes 12 frames before it starts clearing up scanlines from clutter to an extent that is lesser than the classical 2-sprite-width explosion. Lastly, you see that sprites are removed from the list. That’s another nice thing with variable metasprite sizes and termination bytes – you don’t need to use more sprites than necessary.
Not shown here is that the four first cels take 2 frames each in realtime, and the twirl outward goes at a rate of 1 frame per cel, but eventually slowing down gradually to 4 frames per cel as the last ember flades in a floating state.
Looking at it frame for frame, you can spot plenty of beauty faults. The gap between the 1 initial sprite and the 4 following them is one – but given how fast the explosion goes, you can get away with it and save some tilespace.
One thing that i changed from the first iteration (you’ll notice that the gif is named explosion4) is to stagger the changes from one tile to the next on each sprite. That helped it look a bit more naturally chaotic. The same goes for the sprites being deleted off the metasprite list in the end.
Now, a variable total sprite usage during gameplay might not be that useful in itself, apart from the obvious advantage of having somewhat leaner object representations on any one scanline. You could seemingly get away with more action on-screen in something like a hectic shoot em up this way since you might be more efficient before reaching the 64 sprite hardware cap. But having an action game run smoothly with that much stuff going on would be the bigger challenge. And for the hardware cap, that’s just another occasion where you hypothetically can use priority flickering again if you get to that point of unusual sprite density.