Bruce

Aug 2, 20225 min

Vertical Shmup - Part 7 - A Gameplay Decision

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!

    270
    0