Let's create an MPAGD game - Part 15: Game objectives and introducing DATA and READ
Updated: Oct 30, 2021
Sorry for the delay in continuing this series, I've been busy most of the year writing The Swarm is Coming... back now to Stinky Dog. When we left off, we'd built the basics of a game, we have a character, Stinky Dog, an enemy, Sideways Clive, some platforms, ladders and basic movement. We also added some collectable blocks, bones, for Stinky Dog to collect whilst avoiding Sideways Clive.
Let's think about how we can turn this into a game. Perhaps Stinky Dog needs to collect all the bones on screen before the door opens to the next level. Now, we could make things easy for ourselves by always having the same number of collectable bones on each screen....then all we'd need is a variable to count how many bones we have collected - and when it reaches the target number - progress to the next level. That would be pretty easy. First we need a variable, in MPAGD you can't just make up any old name for a variable, you are limited to:
A, B, C, D, E , F, G, H , I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, Z
Basically, all the letters in the alphabet less X & Y. Also, I'd advise you not to use Z, that's one that is generally reserved for Music - which we'll cover another day.
OK, we'll use B for Bones!
Let's say there are 5 bones on each screen that Stinky Dog needs to collect without being killed before he can progress to the next screen.
In our RESTARTSCREEN event (which is run every time we start a screen, including after a death) we would add:
LET B = 5 ; 5 Bones on screen
Then we need to subtract one each time Stinky Dog collects one, remember back in Part 11 we worked with the COLLECTBLOCK event which is called each time the player collects a collectable block - open it up and add the line
SUBTRACT 1 FROM B ; decrement the number of bones left to collect
Now all we need to do is handle what should happen when all 5 bones have been collected, so beneath the last line in the COLLECTBLOCK event we can add:
IF B = 0 ; have all Bones been collected? NEXTLEVEL ; move to the next screen ENDIF
NEXTLEVEL will increment the screen number - this means, if your first screen is (as standard) SCREEN 0 , by collecting all 5 bones, Stinky Dog will progress to SCREEN 1.
But, what if we wanted different numbers of collectables on each level? we could write a huge bunch of IF statements to handle it in our RESTART SCREEN event...
IF SCREEN = 0 LET B = 5 ELSE IF SCREEN = 1 LET B = 7 ELSE IF SCREEN = 2 LET B = 3 .....aggghh!!!!!!!!!
...but that would be horrible and inefficient....there's got to be a better way....and there is...one (well two) of MPAGDs most powerful tools - DATA and READ.
In each event you are allowed to add one DATA statement, a Data Statement is just a collection of numbers. We can then 'get' one of these numbers by using the READ command and putting the value into one of our variables.
So, all we need to do is write a DATA statement that contains, in order, each screen's number of collectable bones. Let's say we are going to have 20 screens, our DATA would look something like this:
DATA 5 7 3 4 6 9 5 8 5 6 4 8 6 9 3 8 9 DATA 4 7 8 10
Note that you should have a maximum of 16 in each line of DATA so we have two lines in our 20 room example.
So, in screen 0 (the first screen of our game) we have 5, in screen 1 we have 7 ...and so on.
Now all we need to do is write a way of, when the screen is started/restarted, retrieving the correct number of bones for the current screen.
And this is where READ comes in.
Here's how we do it, in the RESTARTSCREEN event we replace the LET B= 5 that we added earlier with:
RESTORE ; start READing from the beginning of the DATA list READ B ; read the first value of the DATA and put it in B IF SCREEN >= 1 ; if it is screen 1 or above REPEAT SCREEN ; then repeat SCREEN-many times READ B ; read the next value ENDREPEAT ; so we've found the right B value for the Screen ENDIF DATA 5 7 3 4 6 9 5 8 5 6 4 8 6 9 3 8 9 DATA 4 7 8 10
Now each time we restart the screen, we'll automatically populate the number of Bones that Stinky Dog needs to collect into our variable B.
While we are here...let's add the number of bones left to collect to the score bar.
We'll add this to the RESTART SCREEN event (put it above the DATA statement) and to the COLLECTBLOCK event so that it updates during the game:
AT 0 18 ; show the number of bones left to collect DISPLAY DOUBLEDIGITS B
Now let's give it a test...
To explain this further, the SCREEN variable always holds the value of the current screen. If Screen is 0 we will get its B value by the first READ B command, if the screen number is 1 or greater we'll REPEAT the READ B the correct number of times so that we find the right B value for the screen. READ remembers how far it got through the list of DATA last time it ran, so after the first READ B (screen 0) it knows next time it runs it will read the next DATA value (i.e. 7, the value for SCREEN 1).
That's why we need to use RESTORE at the start of this code, this tells MPAGD to forget how far it got through the list last time and start from the beginning again
I wanted to introduce you to DATA and READ quite early in this series as they are really useful. Get your head around it now and you'll find countless uses for them in the future.
We've also learned about REPEAT & ENDREPEAT - this is a loop that will run as many times as you want - dependent on either the number or the value of the variable (in our example we used the variable SCREEN).