So far, we have two waves of aliens, and they're pretty easy to defeat, but I can see a problem with the way we wrote it. In the game I hope to have lots of different Alien movement patterns, I'm thinking Galaga style - or at least the parts where the Aliens fly into the screen.
With our initial Alien pattern there was a degree of code re-use, but I think we can really take advantage of MPAGDS DATA & READ commands to come up with a far more flexible approach, which could quickly help us create infinite alien movement patterns (or at least, until we run out of memory!
First I'll create a new Alien Ship Sprite:
I'm going to start a new Sprite Type for my new flexi-aliens...I'll use Sprite Type 5.
Let's consider the possible directions an Alien can move in, I'm thinking the extended 16 compass directions should give us enough flexibility:
We'll then write some movement code for each of the compass points, using the DIRECTION local variable, starting at 0 for N, 1 for NNE and so on in a clockwise fashion:
EVENT SPRITETYPE5
ANIMATE SLOW
; FLEXI ALIENS
; =====================
IF DIRECTION = 0 ; Move N
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 1 ; Move NNE
SPRITERIGHT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 2 ; Move NE
SPRITERIGHT
SPRITERIGHT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 3 ; Move ENE
SPRITERIGHT
SPRITERIGHT
SPRITEUP
ENDIF
IF DIRECTION = 4 ; Move E
SPRITERIGHT
SPRITERIGHT
ENDIF
IF DIRECTION = 5 ; Move ESE
SPRITERIGHT
SPRITERIGHT
SPRITEDOWN
ENDIF
IF DIRECTION = 6 ; MOVE SE
SPRITERIGHT
SPRITERIGHT
SPRITEDOWN
SPRITEDOWN
ENDIF
IF DIRECTION = 7 ; MOVE SSE
SPRITEDOWN
SPRITEDOWN
SPRITERIGHT
ENDIF
IF DIRECTION = 8 ; MOVE S
SPRITEDOWN
SPRITEDOWN
ENDIF
IF DIRECTION = 9 ; MOVE SSW
SPRITEDOWN
SPRITEDOWN
SPRITELEFT
ENDIF
IF DIRECTION = 10 ; MOVE SW
SPRITEDOWN
SPRITEDOWN
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 11 ; MOVE WSW
SPRITEDOWN
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 12 ; MOVE W
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 13 ; MOVE WNW
SPRITELEFT
SPRITELEFT
SPRITEUP
ENDIF
IF DIRECTION = 14 ; MOVE NW
SPRITELEFT
SPRITELEFT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 15 ; MOVE NNW
SPRITELEFT
SPRITEUP
SPRITEUP
ENDIF
OK, so that will define each of the possible movements that an Alien can perform, now all we need is a way to define a pattern of movements, this could be as simple as a sequence of values for the DIRECTION and the number of repetitions.
So, 8 20 would mean, perform the # DIRECTION (South) 20 times.
If you think back to our previous method of moving the first wave of aliens, they went South, then veered off to the south west,
In our new method that could be represented as:
8 20 (south 20 times)
7 8 (SSE 8 times)
6 8 (SE 8 times)
5 8 (ESE 8 times)
4 16 (E 16 times)
Which lends itself perfectly to be stored in a DATA table. e.g:
DATA 8 20 7 8 6 8 5 8 4 16
We could then simply create new patterns that describe the movement of the aliens for each level, in just this single event.
That should be really efficient!
There's a couple of things we'll need though to make this work:
1) A variable to store the number of repetitions of the current movement direction
2) A way to find the right starting point for the pattern specific to the level/wave.
1, is pretty easy to handle, we'll just use SETTINGB to read into for the number of repetitions
We'll use SETTINGA as a control variable, that ensures we do things at the right time
And we'll use JUMPSPEED as a counter of the # repetitions.
Add in the highlighted code to your SPRITE TYPE 5 Event:
EVENT SPRITETYPE5
; FLEXI ALIENS
; =====================
SPRITEINK C ; Colour the aliens
; FIND THE STARTING POINT FOR THIS LEVEL
;=======================================
IF SETTINGA = 0 ; Alien first appears
RESTORE ; Restore the data table
LET RND = L ; Store the Level number in RND
ADD 50 TO RND ; and increase it by 50
WHILE DIRECTION <> RND ; While DIRECTION doesnt = RND
READ DIRECTION ; Read value from DATA table
READ SETTINGB ; Also read second value
ENDWHILE ; Keep going until we find the value in RND
LET SETTINGA = 1 ; When we find it change SA to 1
ENDIF
; GET THE NEXT DIRECTION & # REPETITIONS
;=======================================
IF SETTINGA = 1 ; Ready to get direction & reptitions
READ DIRECTION ; Read the next movement into DIRECTION
READ SETTINGB ; Read the repetitions into SettingB
LET JUMPSPEED = 0 ; reset the counter
LET SETTINGA = 2 ; now we are ready to move
ENDIF
; MOVEMENTS
;==============
IF DIRECTION = 0 ; Move N
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 1 ; Move NNE
SPRITERIGHT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 2 ; Move NE
SPRITERIGHT
SPRITERIGHT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 3 ; Move ENE
SPRITERIGHT
SPRITERIGHT
SPRITEUP
ENDIF
IF DIRECTION = 4 ; Move E
SPRITERIGHT
SPRITERIGHT
ENDIF
IF DIRECTION = 5 ; Move ESE
SPRITERIGHT
SPRITERIGHT
SPRITEDOWN
ENDIF
IF DIRECTION = 6 ; MOVE SE
SPRITERIGHT
SPRITERIGHT
SPRITEDOWN
SPRITEDOWN
ENDIF
IF DIRECTION = 7 ; MOVE SSE
SPRITEDOWN
SPRITEDOWN
SPRITERIGHT
ENDIF
IF DIRECTION = 8 ; MOVE S
SPRITEDOWN
SPRITEDOWN
ENDIF
IF DIRECTION = 9 ; MOVE SSW
SPRITEDOWN
SPRITEDOWN
SPRITELEFT
ENDIF
IF DIRECTION = 10 ; MOVE SW
SPRITEDOWN
SPRITEDOWN
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 11 ; MOVE WSW
SPRITEDOWN
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 12 ; MOVE W
SPRITELEFT
SPRITELEFT
ENDIF
IF DIRECTION = 13 ; MOVE WNW
SPRITELEFT
SPRITELEFT
SPRITEUP
ENDIF
IF DIRECTION = 14 ; MOVE NW
SPRITELEFT
SPRITELEFT
SPRITEUP
SPRITEUP
ENDIF
IF DIRECTION = 15 ; MOVE NNW
SPRITELEFT
SPRITEUP
SPRITEUP
ENDIF
; BOUNDARY CHECKING
; ===================
IF X <= LEFTEDGE ; if alien reaches the left edge
REMOVE ; remove it
SUBTRACT 1 FROM S ; decrement the sprite counter
SUBTRACT 1 FROM F ; decrement the number of aliens still in
ENDIF
IF X >= RIGHTEDGE ; if alien reaches the right edge
REMOVE ; remove it
SUBTRACT 1 FROM S ; decrement the sprite counter
SUBTRACT 1 FROM F ; decrement the number of aliens still in
ENDIF
IF Y >= BOTTOMEDGE ; if alien reaches the right edge
REMOVE ; remove it
SUBTRACT 1 FROM S ; decrement the sprite counter
SUBTRACT 1 FROM F ; decrement the number of aliens still in
ENDIF
; INCREMENT REPETITION COUNTER & CHECK IF WE NEED NEXT DIRECTION
;==============================
SUBTRACT 1 FROM SETTINGB ; decrement the number of repetitions
IF SETTINGB = 0 ; have we done all the required repetitions
LET SETTINGA = 1 ; yes, request the next direction
ENDIF
; MOVEMENT & REPETITIONS DATA TABLE
DATA 51 0 8 20 7 8 6 8 5 8 4 16
DATA 5e2 0 8 20 9 8 10 8 11 8 12 16
First, I've added in a spriteink command to colour the aliens with the value C (we'll add this in to the spawner Data table in a moment)
So, when this event first runs for a n alien sprite SettingA will be 0 (we'll need to add that in to Initialise Sprites in a moment)
This will then restore the data table (which means the next READ will be the very first value in the table). We will then cycle through the data until we find a value equal to 50 + the Level number (so, for level 1 we are looking for 51, for level 2 we look for 52 and so on).
I chose 50 since it's unlikely I'll need more than 50 directions (0-15 represent our 16 compass points.) but it leaves me room to add more later and means I could have over 200 movement patterns in this event, which should be more than enough.
Once we've found it, we will read in the next number to SETTINGB (we'll just use 0) and we will then set SettingA to 1 so that we don't restore the data each cycle.
It's important to recognise that each sprite always knows how far it has read through the data table, unless we RESTORE, at which point it goes back to the start.
Now that SettingA is 1, we will READ in the actual DIRECTION number and the number of REPETITIONS required into SETTINGB, we then set settingA to 2 to prevent this running again until all repetitions of the movement direction have been performed..
Note that I've also put some Boundary checking in place (not very efficiently, we'll improve it later) this will remove any aliens that travel off screen.
Finally, we have our DATA table, at the moment I have just replicated our original two movement pattern down and veer right, and down and veer left.
OK, before we test it, we have a couple more tasks to complete.
MENU: EVENTS > INITIALISE SPRITES:
EVENT INITSPRITE
ADD 1 TO S ; increment the sprite counter
IF TYPE 1 ; PHOTON TORPEDO
LET SETTINGB = 0 ; initialise the distance counter
ENDIF
IF TYPE 5 ; FLEXI ALIENS
LET SETTINGA = 0 ; Initialise SettingA
ENDIF
IF TYPE 7 ; SPAWNER
LET SETTINGA = 0 ; RESET SETTINGA
ENDIF
Next, we'll update the Spawner Event code:
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
READ C ; get the colour value for the alien
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 132 8 5 2 8 8 5 67
DATA 0 100 8 5 2 8 8 10 68
Here I have added a new value to each data set and split the two levels onto lines of their own to make it easier to read, the new (9th) value is the one that will be read into C.
I think we are ready to test!, let's build this bad boy!
Yeah! look at them fly!
OK, now let's have some fun, and create some new patterns to the DATA table in sprite type 5, be sure to start each pattern with 200+Level# followed by a zero and then your pairs of DIRECTION # and Repetition #
Try these for starters, then make up your own:
Replace the DATA table in your Alien event (Sprite Type 5) with:
DATA 51 0 8 20 7 8 6 8 5 8 4 16
DATA 52 0 8 20 9 8 10 8 11 8 12 16
DATA 53 0 12 48 11 2 10 2 9 2 8 2 7 2 6 2 5 2 4 40 5 2 6 2 7 2 8 2 9 2 10 40
DATA 54 0 4 48 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 40 11 2 10 2 9 2 8 2 7 2 6 40
DATA 55 0 13 26 14 4 15 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 4 10 40
DATA 56 0 3 26 1 4 0 4 15 4 14 4 13 4 12 4 11 4 10 4 9 4 8 4 7 4 6 40
And replace your Spawner Data table (Sprite Type 7) with:
DATA 0 132 8 5 2 8 8 5 67
DATA 0 100 8 5 2 8 8 10 68
DATA 0 232 16 5 5 8 6 15 69
DATA 0 8 16 5 5 8 6 15 70
DATA 0 232 146 5 2 16 6 20 71
DATA 0 8 146 5 2 16 6 20 66
Now that we have 6 attack waves / levels you 'll need to update this line in your spawner event
IF L = 3 ; have we reached the end of the levels?
to:
IF L = 7 ; have we reached the end of the levels?
Save your game, then let's build it and shoot some aliens!!
Cool! feel free to experiment and create lots more attack patterns!
However, its about time we gave the aliens some weapons of their own, building on the framework we have already created and using some of the tricks we've learnt, we should be able to add lots more variety to the game.
NEXT: Part 9: The Aliens Fight Back!
Comments