• Bruce

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!



2 views0 comments

Recent Posts

See All

A couple of people have asked for some tutorials on creating a Vertical Shoot-em up with MPAGD, something along the lines of Imagine's classic, Arcadia. This sounded like a good challenge....but one I

Want to support my work?....Buy my games!

aboutME

Hello, I'm Bruce and I write games for old 8bit computers using Jonathan Cauldwell's excellent Multi-Platform Arcade Games Designer (MPAGD)

I've written a few successful* games for the Sinclair ZX Spectrum and MSX platforms that have been (largely) well received with my most recent game - Twenty Four Hour Parsley People scoring a 10 out of 10 on Planeta Sinclair.

In my blog I am sharing lots of the code that I wrote for my games, in a way that you can use in your own games.   I've commented it so that you'll learn some of the techniques I use to create interesting new mechanics and help your games stand out from the pack.

MPAGD includes lots of standard scripts, they're great to get you started, but if you're new (or just rusty) when it comes to writing code, hopefully my tutorials will help you get started and  turn your imagination into awesome 8 bit games!

All my code is free to use and do with as you please, but if you find them useful please feel free to buy me a coffee ...or better still - buy or download my games :)

*successful is a very relative term in 8bit computer games