Finally, I’ve finished rewriting all of this.
Let’s run down what happens each frame…
I moved the ‘set scroll, wait for sprite-zero hit, change scroll’ to the NMI code. Then we…
1. Get Input
2. Push all sprites (in buffer) offscreen, then put Sprite Zero back in
3. If Master_Delay goes from 1 to 0 on this frame, init new wave of enemies
- I’m using memcpy to transfer enemy data from ROM to RAM
4. Check to see if we just finished the wave (All enemies have Y value of zero)
5. Check to see if we’re injured (lot’s of hitbox checks for every active enemy ship and bullet vs hero ship). Lives-1 if yes, and draw the ship as an explosion for a little bit (marked with an injury timer).
6. Move the ship (based on button presses)
7. Check to see if our bullets are hitting the enemy ships (give them Y = 0 if yes, and spawn an explosion).
8. Draw all the active sprite objects (by putting their data into the OAM buffer).
9. Play music (this could be done in the NMI code)
10. Update the scoreboard (in ASM…the NMI code will push it to the PPU).
11. Handle switching to Pause Mode (START pressed)
12. Handle dying (Lives rolled past zero to 0xff)
Then I wrote the pattern system. At the start of each wave, it sets starting positions and a delay for each ship. Each frame, it goes to a specific pattern code, and moves the ships based on either their position, a count, or a move list. It will stay in a wave until every ship has a Y value of zero…either because they moved offscreen or were shot. Once all the ships have a Y value zero, it sets a short delay (Master_Delay), then starts the next wave. Until we run out of waves, and start the Boss Mode…
Boss mode is pretty straightforward…the boss has a list of moves, and a health. Bullets hitting the boss decrease the health until zero, and we trigger the boss death (shaking and noise sound fx), and then jump into Victory Mode.
I added a final Continue screen, in case someone wants to keep going. It just resets the game as usual, but it saves the ‘lives’ and ‘scores’ when it erases the RAM.
Hopefully, someone out there can learn something from this example code. Feel free to build on this code and make a bigger / better version of it. Thanks for reading.