I started this series as a bit of nostalgic homage to Imagine's Arcadia, a game as a 12 year Old back in 1982 I loved. If you recall, the original Arcadia didn't require to kill all of the enemies in each wave, rather you had to survive the timer.
I could implement the same gameplay for this game by implementing a timer, but I'm not trying to recreate Arcadia exactly so I think we'll do something else.
As an alternative, we could make it so that you have to kill all the enemies in each wave before the next wave appears.
Or, it might be good to have a set amount of each wave of enemies that are spawned after which the next wave will begin. So to get a top score you need to kill as many as possible, perhaps if you kill all enemies in a wave there's some kind of bonus or power up that you can be rewarded with.
I think this last approach is my favourite and is the one I'm going to attempt to start with.
To do this, we're going to need a variable that can count the enemies in each wave that we've killed, let's head back to our Spawner event code (Sprite Type 7)
and add in the highlighted lines of code below.
EVENT SPRITETYPE7
; SPAWNER
; ============
IF SETTINGA = 0 ; first time we run this
LET JUMPSPEED = 0 ; reset the enemies spawned counter
LET SETTINGB = 0 ; reset the timer
RESTORE ; start from the beginning of the data table
REPEAT L ; get the data for this level
READ AIRBORNE ; get the spawner movement
READ X ; get starting x position
READ Y ; get starting y position
READ J ; get the enemy sprite type
READ K ; get the enemy image
READ E ; how many enemies in this level?
READ G ; delay between releasing each enemy
READ P ; Number of points scored if enemy is killed
ENDREPEAT
LET D = E ; store the number of enemies to be killed in D
LET F = E ; also store #enemies in F to count kills & exits
ADD 1 TO SETTINGA ; prevent this running again
ENDIF
IF SETTINGB = G ; has timer reached the delay point?
IF JUMPSPEED < E ; are there still enemies left to spawn?
IF S <= 8 ; are there 10 or less enemies already on screen?
SPAWN J K ; spawn an enemy
ADD 1 TO JUMPSPEED ; increment the number spawned
SPAWNED ; switch to the enemy sprite
LET DIRECTION = 0 ; set its initial direction to 0
ENDSPRITE ; return to the spawner
ENDIF
ELSE ; all enemies in this level have been spawned
IF F = 0 ; if all enemies killed or exited
ADD 1 TO L ; get ready for next level
IF L = 3 ; have we reached the end of the levels?
LET L = 1 ; yes, start again
ENDIF
LET SETTINGA = 0 ; GET DATA FOR NEXT LEVEL
ENDIF
ENDIF
LET SETTINGB = 0 ; reset the timer
ENDIF
ADD 1 TO SETTINGB ; increment the timer
DATA 0 165 8 2 2 5 12 5 0 80 8 2 2 5 12 10
So, we read into E the total number of enemies in the wave, were not going to want to change this info during the wave so we'll copy it into another variable, D, which we will use as a Countdown each time we kill an enemy.
We will also store the number of enemies in the wave in F, we'll then decrement F every time an enemy is killed or exits the screen. We'll then only move to the next level/wave when all enemies have been removed from the screen,, otherwise we might run in to problems as new waves would otherwise appear before the last of the previous enemies had left the screen - which could mess up our counters.
We also need think about the scoring mechanism. In Arcadia, each enemy scored the same number or points as the level/wave. So in level 1 each kill scored 1 point, in Level 2 - 2pts and so on.
We could do the same here quite easily, but again, I'm not trying to recreate Arcadia exactly, and I want to retain some flexibility, so we'll use a new variable P which we will read from the DATA table, so you can see from the highlighted code above, killing an enemy in level 1 will score 5 points and killing an enemy in level 2 will score 10 points.
We also need to add the score to the Screen, first we'll drop it into our RESTART SCREEN event:
EVENT RESTARTSCREEN
LET S = 0 ; initialise the sprite counter
AT 0 1 ; position the cursor at Line 0 Column 1
SHOWSCORE ; display the score
That's OK to start with but we need it to update whenever points are scored, we could simply drop the same code into the MAIN LOOP, but in my experience if you want to keep your MPAGD game running efficiently its best not to refresh on screen scores and variables on every cycle, instead, we'll only update it when required.
One approach would be to repeat the above lines of code in every event where points are scored, but that could get quite repetitive codewise, instead my preference is to use a variable as a trigger, I'll use T.
Now in our Main Loop 1 we'll add some code:
EVENT MAINLOOP1
IF T = 1 ; Score bar update requested
AT 0 1 ; at Line 0 column 1
SHOWSCORE ; update the score
LET T = 0 ; reset the trigger
ENDIF
So now, whenever we want to update the score bar we'll just need to add LET T = 1 in the relevant events.
Let's go back to our explosion sprite event (Type 6) and add the triggers, countdowns and score code in:
EVENT SPRITETYPE6
ANIMATE ; regular amination
IF FRAME = 4 ; are we on the last frame?
IF DIRECTION = 0 ; was enemy hit by a torpedo?
REMOVE ; yes, remove this sprite
SUBTRACT 1 FROM S ; decrement the sprite counter
SUBTRACT 1 FROM D ; decrement the enemy kill countdown
SUBTRACT 1 FROM F ; decrement the kill/exit countdown
IF D = 0 ; have all enemies been killed?
SCORE 500 ; yes, score extra 500 points
ELSE ; no, still some more to kill
SCORE P ; score P number of points
ENDIF
ELSE
IF DIRECTION = 1 ; is this the player exploding?
KILL
ENDIF
ENDIF
LET T = 1 ; update the score bar
ENDIF
Now we'll score P points for each kill, but if we kill all enemeies in a wave D will be 0 and we will score a bonus 500 points.
Let's give it a test...
Looks ok to me, the bonus is working as expected.
But these enemies are a bit toothless, so next we'll give them some weapons of their own.
NEXT: PART 8 : THE ALIENS FIGHT BACK!
Comments