Removing the extras

To make the squares more realistic enemies, we're going to remove them when they go off the screen. That calls for a new routine:

Variables
  • L: current length of array (initialized to 0 at the beginning of the program and updated by the routine itself)
Input
  • r1: index of element to remove
Output

None. (Again, you can modify it to return something useful, but we won't in our example.)

Code
:Lbl RE
:Copy(r1*4+L1+4,-4,L-1→L-r1*4+1)
:Return

You can probably tell that it's a copy statement. What we're trying to do is copy everything after the element to be removed four bytes back—overwriting the element you want to remove. The routine also takes care of the array length variable (L) by subtracting one.

The only thing that should seem weird here is the extra +1 at the end. It might not make sense, but it takes care of the case where you're trying to remove the very last element. If that extra little bit of code weren't there, the Copy( statement would try to copy 0 bytes backwards, which gets translated to a copy a 65536 bytes, which is definitely not what you want. This extra bit doesn't do us any harm besides slowing the program down a tiny, tiny bit, but it takes care of that scenario for us.

So now that you have the routine down, let's actually use it. Go back into the main program and change it to this:

PROGRAM:ASQUARES
:.SQUARES
:prgmASQUI
:Repeat getKey(15)
:If rand<4096
:sub(PE,44,28,rand^3,rand^3) :End
:If L
:For(I,1,L)
:If {{I*4+L1-4→J}+{J+2}→{J}}≥96
:Goto RM
:End
:If {{J+1}+{J+3} →{J+1}}≥64
:Lbl RM
:sub(RE,I-1→I)
:End
:End
:End
:sub(DA)
:DispGraph :sub(DA)
:End
:Return
:prgmASQUR

All the changes are in the For(I,1,L) loop. It basically tests the X- and Y-values after they're changed to see if they're completely off the screen, and if so, they get removed. The reason I jump to a lable RM instead of writing the code twice is because it's smaller and even gets rid of any chance of some certain nasty coincidences I won't talk about here. The point is it works.

+ Tweet