battagline wrote:
I've been thinking about how to display more than 8 sprites on a single scanline. My understanding is you make them flicker in and out by setting the priority bit in byte 2 of the oam to be behind the background. What I'm not sure is if there is some sort of scanline collision detection that would somehow determine if there are more than 8 sprites on a single line, or if the sprites should be set to randomly flicker at different times to just decrease the likelyhood of them all showing at the same time on the same scanline.
No, the priority bit will not help with this. That only draws that sprite behind the background, but it does not move it to a separate pass, so it will still interfere with other sprites on the same scanline even if they're not behind the background.
The way to deal with this is to change the order of the sprites within the OAM buffer.
The first step is not to put any particular character in a location. A lot of games hard-code sprites like this, but it makes flicker impossible. When you start a frame, set an "OAM index" to 0, every time you add a new sprite, put it at the index location, and add 4 to that index. To finish the frame, fill the rest of the OAM Y coordinates with $FF to hide any unused sprites.
Once you have a system like that in place, cycling the sprite order can be achieved by drawing your sprites in a different order each frame. You might try going through your object list forwards and backwards on different frames, or cycling thruogh them, or maybe have a few different orders.
Simple example:
Code:
jsr oam_begin ; set index to 0
inc order_sequence
lda order_sequence
and #3
bne @order1
@order0:
jsr draw_player
jsr draw_enemies
jsr draw_bullets
jmp @order_end
@order1:
cmp #1
bne @order2:
jsr draw_bullets
jsr draw_enemies
jsr draw_player
jmp @order_end
@order2:
cmp #2
bne @order3:
jsr draw_enemies
jsr draw_player
jsr draw_bullets
jmp @order_end
@order3:
jsr draw_player
jsr draw_bullets
jsr draw_enemies
@order_end:
jsr oam_finish ; fill unused sprite Ys
There are a lot of ways to do this reordering, and what's appropriate depends on your game (often you might want one sprite to always draw first so it never disappears), but this is the general idea. In my last game I
use a table of prime numbers as an
increment through my game object list, so that they get iterated in a different order each frame.
Though a lot of older games did things in pairs of frames one off, one on, I'd recommend against a sequence with only two steps if you're making a new game, otherwise you'll get the "Mega Man disappears when hit" thing when YouTube or Twitch shows the video at 30fps. Use sequences of 3 frames or longer to ensure that the flickering is still comprehensible at half framerate.
One more general recommendation: don't try to detect overlap, it's easier just keep changing the order every frame. (Technically the sprite overflow flag in $2002 is supposed to detect this in a limited way, but its implementation was broken and it reports false positives. Not very useful.)