When we first started Defendy Rocket, all of the enemy rockets that come down the screen were defined by X and Y offsets (in game units).
For example, a wave of three rockets could be defined as spawning at the centre of the screen, with the three rockets have an offset of (0, 0), (-100, 100), and (-100, 200) units:
This worked fine at a very basic level, but we found we started to get into problems once we started to hypothesise more complicated rocket waves. With rockets of different sizes and speeds, it was very easy to get into a situation where one rocket would likely pass through another and/or the player would have multiple groups of rockets spawning in the same parts of the game screen.
So we started to design a new system:
The idea was simple, but we figured it would cover all of the bases: Divide the game screen up into three columns (left, centre, right), lockout each column whenever a rocket spawned (so they couldn't overlap) and release the lock when enough time had passed (the time would vary based on the rocket so that the slower rockets wouldn't be over-taken by the faster ones). Waves of rockets would still be defined by a positional offset from each other, except now they would be given one of the three columns to spawn in.
But as we started to build it and thought about some of the minor issues, we came across a few key problems. The biggest of which was: What if you wanted to do this:
Well, you couldn't. The two outer rockets would invalidate the left and right columns and, if a big, slower rocket was in any of the columns ahead, you'd have to wait ages before you could spawn this wave. Not to mention that you could never spawn this wave in the left or right columns without the edge rockets spawning outside of the game screen. And it was still really hard to calculate at run time if two rockets would overlap each other in separate waves.
This greatly limited our options as to which patterns of rockets we could create to make interesting gameplay, so we went back to the drawing board and came up with a variation on the columns theme:
This time we have 13, much smaller columns labelled by index 0-12. By spawning rockets in each of the columns (rather than based on positions, you can get a very clear picture of which rockets are where, and can eliminate overlap. Now, rather than specifying the rockets within ours waves by positional offset from each other, we could spawn them by column offset for horizontal positioning and by vertical offset for height:
Taking the wave above as an example, we could randomly choose to spawn it in column seven. The first rocket would spawn in column seven with no vertical offset, the second would spawn in column six with a vertical offset of one and the third rocket would also spawn in column six, with a vertical offset of two. We could then lock down columns six and seven for a short duration, and continue to spawn waves in other columns.
This allows us to quite easily create some fairly complex rocket wave patterns, running some some logic to check that the columns they need to spawn are available first. The duration lockout on each column prevents any overlap (the red boxes show an example of how the lockout system works):
This also works for the large rockets too. We simply spawn the rocket in one column (making sure we never spawn it in the outer columns, obviously) and lock out multiple columns. For example, we determined that the mega rocket takes up five columns: