Bruce

Oct 30, 20217 min

Let's create an MPAGD game - Part 20: SCOREs, LIVES and DISPLAYing stuff.

Our game is starting to take shape, now is probably a good time to sort out the mess that is currently the score bar at the top of the screen. Before this, let's take a look at how MPAGD stores the player's score, how we can add to it and how we display it on the screen.

First, the score is not a normal 8bit variable. As you recall 8bit variables can hold a number from 0-255. The score in an MPAGD game can hold a value from 0 to 999,999 after which point it will reset to 0. You don't need to understand how it does this, just that it does!

Remember back in Part 11 we added a score every time Stinky Dog collected a bone. We did this by adding the command

SCORE 100

into the COLLECTBLOCK event. The SCORE command will accept a 16 bit number, i.e. any number from 0 to 65,535 (2 to the power 16). The number you put after the SCORE command is then added to the players current score.

Note that SCORE is not a variable, so you can't do any coding that interrogates it, like IF SCORE >50000 ADD 1 TO LIVES.

We also updated the score on screen by including the command:

AT 0 6
 
SHOWSCORE

The AT command is a shorthand way of positioning the cursor on the screen, so the code above is the same as:

LET LINE = 0
 
LET COLUMN = 6
 
SHOWSCORE

But what if we also wanted to have the word 'SCORE:' before the score, so it displays: SCORE: 000000... that might look neater.

Let's open up our GAME INITIALISATION script:

EVENT GAMEINIT
 

 

 
LET LIVES = 3
 
AT 0 27
 
DISPLAY LIVES
 

 
AT 0 6
 
SHOWSCORE

...and let's tidy it up a bit:

EVENT GAMEINIT
 

 
AT 0 0
 
PRINT "SCORE:"
 
SHOWSCORE
 

 

 
LET LIVES = 3
 
AT 0 21
 
PRINT "LIVES:"
 
DISPLAY LIVES

Now our score bar is looking a little neater:

So we can see that AT 0 0 positions the cursor in the top left character cell of the screen, we then PRINT the word 'SCORE': display the actual score next to it (note that the cursor automatically moves to the next column available, which is why in our game initialisation event we can save a few bytes by removing the AT 0 6 before SHOWSCORE...since after printing 'SCORE:' the cursor is already there!.

Then we shift the cursor to 0 21 to display the LIVES remaining.

Another score related bonus in MPAGD is...BONUS. This works in a similar way to SCORE, in that you can add to the players bonus with a command like:

BONUS 50

That you trigger when the player does something. Lets give Stinky Dog a BONUS if one of his noxious farts stuns Sideways Clive...

Open up your SPRITETYPE 1 event and find the part that deals with the fart colliding with Sideways Clive...

IF COLLISION 2 ; if Clive touches a Type 2 sprite (the fart)
 
IF DIRECTION = LEFT ; if Clive is going left
 
LET SETTINGB = 0 ; remember the direction he was going, 0 = Left
 
ELSE ; if he wasn't going left
 
LET SETTINGB = 1 ; he was going RIGHT, 1 = RIGHT
 
ENDIF
 
LET DIRECTION = 5 ; set the direction to STUNNED
 
LET SETTINGA = 0 ; start the stunned timer
 
OTHER ; switch to the Fart
 
REMOVE ; remove the fart
 
ENDSPRITE ; switch back to this event
 
LET F = 0 ; reset the Fart in play to no fart in play
 
BONUS 50 ; add 50 to the bonus
 
ENDIF

Now when a fart hits Clive we'll increase the bonus.

Note that the BONUS won't automatically be added to the score, it will tot up as we play, we're going to add it later, when Stinky Dog completes a level of the game.

Like SCORE, you are limited to incrementing the BONUS by numbers up to 65535 and it will max out at 999999.

At the moment, in our game, a level is completed when Stinky Dog collects all the Bones on screen, we test if they have all been collected in our COLLECTBLOCK event which currently looks like this:

EVENT COLLECTBLOCK
 

 
SCORE 100 ; score 100 points when we collect a Bone
 
AT 0 6
 
SHOWSCORE ; display the score
 

 
SUBTRACT 1 FROM B ; decrement the number of bones left on screen
 
IF B = 0 ; have all Bones been collected?
 
NEXTLEVEL ; if so move to the next screen
 
ENDIF

Let's make it a bit more interesting, we will clear the screen, display the bonus, add it to the score and then start the next level.

When it comes to clearing the screen, we have two commands we can choose from:

CLS - will clear the entire screen

CLW - will clear only the play window and not the score bar that we have at the top (or wherever you positioned yours!)

Let's just clear the screen, display the score, the bonus, add the bonus to the score and display the new total score, then we'll wait for the player to press a key to start the next level.

EVENT COLLECTBLOCK
 

 
SCORE 100 ; score 100 points when we collect a Bone
 
AT 0 6
 
SHOWSCORE ; display the score
 

 
SUBTRACT 1 FROM B ; decrement the number of bones left on screen
 
IF B = 0 ; have all Bones been collected?
 
CLS ; clear the screen
 
AT 10 2 ; at line 10, column 2...
 
SHOWSCORE ; display the score
 
DELAY 25 ; wait 1 second
 
PRINT " + " ; display +
 
DELAY 25 ; wait another second
 
SHOWBONUS ; display the bonus
 
DELAY 25 ; wait another second
 
PRINT " = " ; display =
 
DELAY 25 ; wait another second
 
ADDBONUS ; add the bonus to the score
 
ZEROBONUS ; reset the bonus to 0 now we've added it
 
SHOWSCORE ; display the new score
 
AT 15 8 ; at line 15 column 8
 
PRINT "PRESS KEY TO START"
 
WAITKEY ; wait for a key press
 
NEXTLEVEL ; if so move to the next screen
 
ENDIF

Let's give it a go...

That seemed to work...but did you spot the problem?

Right at the end, when the next level started, the screen bar at the top has completely disappeared. But then the score value and lives value return...

Why is that?

Well, first we used the CLS command when Stinky Dog collects the final bone. CLS wipes the entire screen clean, so the score bar goes too.

So, why isn't it reinstated when the next level starts.

Simply put, the answer is that our code doesn't tell it to. At the moment we put the PRINT "SCORE:" and PRINT "LIVES" code in our GAME INITIALISATION event. This event is only run when the Game first starts. The score then appears when we first collect a bone, and the lives appear when we are killed, that's because we have SHOWSCORE and SHOWLIVES commands in the COLLECTBLOCK and KILL PLAYER events respectively.

To remedy this, we'll move the PRINT commands to the RESTARTSCREEN event. This event is run every time we restart a screen (including after a death and when we start a new level).

So, open up your GAME INITIALISATION script and cut everything beneath EVENT GAMEINIT except the LET LIVES = 3, so it should now look like this:

EVENT GAMEINIT
 

 
LET LIVES = 3

then open up you RESTART SCREEN Event and paste it in above the DATA statement...it should now look like this:

EVENT RESTARTSCREEN
 
RESTORE
 
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
 

 
AT 0 0
 
PRINT "SCORE:"
 
AT 0 6
 
SHOWSCORE
 

 
AT 0 21
 
PRINT "LIVES:"
 
DISPLAY DOUBLEDIGITS LIVES
 

 

 
;-------------------number of Bones per screen-------------------------
 
DATA 5 7 3 4 6 9 5 8 5 6 4 8 6 9 3 8 9
 
DATA 4 7 8 10

We leave the LET LIVES = 3 statement in Game initialisation, since we only want this to run once, when the game first starts, otherwise the number of lives will reset every time the screen is restarted if we put it in the RESTARTSCREEN event.

The lives variable in MPAGD can contain an 8bit number (0-255) and unlike SCORE and BONUS we can write code around it, for example, we could 'ADD 1 TO LIVES' if the player collected a particular object.

It does behave a bit differently to normal variables, in that if it reaches 0 (no lives remaining) MPAGD will run the 'LOST GAME' event.

As LIVES is an 8 bit variable we also need to use the DISPLAY command to display it.

The DISPLAY command also has additional parameters we can use to control how it displays on screen, these are:
 

 
DISPLAY SINGLEDIGIT - will only display 0 - 9,

DISPLAY DOUBLEDIGITS - will only display 0-99 with a leading 0 for 0-9 (00,01,02 etc)

DISPLAY TRIPLEDIGITS - will display 0-255 with a leading 00 for 0-9 , and 0 for 10-99

In our game I'm going to restrict the number of lives that can ever be gained to a maximum of 10, so I've added in the DOUBLEDIGITS parameter in the command in the code above (highlighted). As for the way we can restrict lives to a maximum of 10...we'll come back to that later.

As we've used DOUBLEDIGITS to display the lives in the RESTARTSCREEN event, we're going to need to do the same wherever our code tells the game to display the lives. At the moment, there should be only one other reference to LIVES, which is in our KILL PLAYER event, which is triggered whenever we KILL the player, open up your KILL PLAYER event and add the DOUBLEDIGITS...


 
EVENT KILLPLAYER
 

 

 
SUBTRACT 1 FROM LIVES
 
AT 0 27
 
DISPLAY DOUBLEDIGITS LIVES
 
ZEROBONUS

I also want to tweak the game a little, so I've also added a ZEROBONUS into the KILLPLAYER event too, that way, if Stinky Dog is killed, he will lose any fart bonuses he has accumulated.

Let's test the game...

OK, that seems to be working as expected, but I'm not too keen on the font or colours surrounding the play area, I think it's about time we looked at that next...

NEXT: PART 21: Changing fonts, COLOUR, PAPER, INK and CLUT

    4560
    4