"Next level"

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
"Next level"
by on (#144275)
Okay guys, I'm learning to make simple crossing to the next level or room include different sprites, music, background etc. How it works? It's something like clears memory from NT1 (or both of NT, whatever) and after that begins another code with different data, is it correct? Give me please an example.
Re: "Next level"
by on (#144276)
You should try to keep the "low level I/O" stuff (writing to name tables) separate than the "high level logic" (go to next level) stuff.

What I did (and it works perfectly, but it's not the *only* way to do it) is to have two flags, the "game over flag" and the "level cleared flag". As long as both of these are clear, the game loop continue to loop.

When "game over flag" is set, then it calls some cleanup functions : Fade the screen out, decrease number of lives, if it is still >= 0 then re-initiate the level and restart.

When "level cleared" is set, then some cleanup functions are also called, depending on what you want to do. (I have a function where the main character walks to the border of the screen, for example) Then also, the screen is faded out, the level number is increased, some stuff is backed up, and it goes back to the main loop.

Of course you'd want to check if the level reach a threshold and exit form the main loop and show the ending/credits, but I'm not at this point yet in the development of my game :(

I hope this helps. There is usually no need to clear the name table, because it will be overwritten by other data anyway. It depends on what you want to do, though. Again, don't merge the I/O and the logic.
Re: "Next level"
by on (#144277)
Thank you Bregalad, that's simple to write and makes sense instead what I wrote above. :)
Re: "Next level"
by on (#144285)
It makes sense to separate each part of your game (title screen, menus, cutscenes, gameplay, etc.) in two parts: initialization and loop. The initialization will run once and set up all the variables necessary for that part, draw name tables, and so on. The loop comes after the initialization, and will run every frame, updating things based on input, AI, whatever.

When you're in the gameplay loop and decide that the level has ended, you'll have to increment a variable that indicates which level you're in, and after doing any other procedures you judge necessary (fading out, for example), you can simply jump back to the gameplay initialization, which will take care of initializing the next level.

The initialization code should be able to use the level number as an index, that can be used to load different data for each level. For handling different backgrounds, for example, you first have to make a list of pointers to all backgrounds you have, in order:

Code:
Level1Background:
   .db $01, $01, $01, $02, (...)

Level2Background:
   .db $04, $04, $02, $02, (...)

Level3Background:
   .db $00, $08, $08, $08, (...)

LevelBackgrounds:
   .dw Level1Background, Level2Background, Level3Background

Then you can use the level number as an index to read the address of the name table you need to draw from that table:

Code:
   lda LevelNumber ;get the number of the level
   asl ;multiply it by 2 since each address is 2 bytes
   tax ;use it as an index
   lda LevelBackgrounds+0, x ;copy the lower byte of the address
   sta BackgroundPointer+0
   lda LevelBackgrounds+1, x ;copy the higher byte of the address
   sta BackgroundPointer+1
   jsr UpdateNT ;go update the name table

UpdateNT is just a routine that copies map data from the address pointed by BackgroundPointer to the name tables.

The same principle can be applied to all other attributes of the level, such as the list of enemies, song played, starting position for the player, and so on. As long as you index all of those in order, you can read the appropriate data for each level using the level number as an index.