Now we start with a few game essentials: Progressing to the next level.
Not too complicated. We keep a counter of enemies alive (NUMBER_ENEMIES_ALIVE) which is initially set to 0. Since we already have a lookup table IS_TYPE_ENEMY we simply add a check inside AddObject. If the new object is an enemy, increase the counter:
;adjust enemy counter
ldx PARAM3
lda IS_TYPE_ENEMY,x
beq .NoEnemy
inc NUMBER_ENEMIES_ALIVE
.NoEnemy
The other spot where this comes in is when we kill an enemy. Inside our FireShot routine we add:
.EnemyKilled
ldy SPRITE_ACTIVE,x
lda IS_TYPE_ENEMY,y
beq .NoEnemy
dec NUMBER_ENEMIES_ALIVE
.NoEnemy
jsr RemoveObject
For the level change we add a new control routine (GameFlowControl) in the main game loop. Once the enemy count reaches 0 we increase a level done delay so we don't immediately jump onwards. Once reached, disable all sprites, build next level and continue.
For now there's two simple levels with the last looping back to the first.
;------------------------------------------------------------
;the main game loop
;------------------------------------------------------------
GameLoop
jsr WaitFrame
jsr GameFlowControl
jsr DeadControl
jsr ObjectControl
jsr CheckCollisions
jmp GameLoop
;------------------------------------------------------------
;controls the game flow
;------------------------------------------------------------
!zone GameFlowControl
GameFlowControl
inc DELAYED_GENERIC_COUNTER
lda DELAYED_GENERIC_COUNTER
cmp #8
bne .NoTimedActionYet
lda #0
sta DELAYED_GENERIC_COUNTER
;level done delay
lda NUMBER_ENEMIES_ALIVE
bne .NotDoneYet
inc LEVEL_DONE_DELAY
lda LEVEL_DONE_DELAY
cmp #20
beq .GoToNextLevel
inc VIC_BORDER_COLOR
.NotDoneYet
.NoTimedActionYet
rts
.GoToNextLevel
lda #0
sta VIC_SPRITE_ENABLE
inc LEVEL_NR
jsr BuildScreen
jsr CopyLevelToBackBuffer
rts