Adding interest to your programs - part one
from ZX Computing, April/May 1983

In this two-part feature, Tim Hartnell describes the genesis of a simple
idea for a program through to a full-blown, arcade-style game on your ZX
Spectrum.


Once you've been using your Spectrum for a while, you may find that while
it is relatively easy to get some sort of program up and running, it is not
so simple to turn that program into something you'd be proud to show your
friends. In this article (to be continued in the next issue of ZX
Computing), I'll explain how a simple framework can be "dressed up" with
sound, colour and user-defined graphics.

Out for a duck
We're going to take a simple program  Duck Shoot  and gradually elaborate
it, showing how adding things such as sound and colour, border flashes and
user-defined graphics can add a great deal of interest to your programs. At
the end of this two-part feature, I'll give you four more suggestions to
apply if you wish to keep improving and elaborating the program I am going
[to] outline.

The program we're going to use as the core of our development work is a
fairly standard "Duck Shoot" listing, in which little objects fly across
the screen, and you have to try and shoot them down. In the first version
of the program, the little objects are letters chosen at random and you are
the letter 'X'. You fire at the "ducks" by pressing the 'F' key and you
move yourself left using the '5' key and right using the '8' key (moving in
the direction of the arrows on those keys).

Although there is no time limit on this program (so you don't have to
shoot the ducks in a specified time) there is a limit on the number of
shots you can fire. In all the versions of this game in this part of the
article, you'll see the program starts with a limit of 15 shots. In the
last, most complex version, you will have 50 shots. The number of shots is
deliberately kept low in the first version, so you are not able to get a
high score just by leaving your finger on the 'F' key and waiting for the
ducks to fly into the line of fire. Look now at Program 1. Type it
carefully into your Spectrum and type RUN, then press ENTER and you should
get the game underway.

You'll see the letters which are held in A$ (see line 40) moving across
near the top of the screen. You (the 'X') will be in about the middle of
the screen when the program starts. You can, as I mentioned a few moments
ago, move yourself back and forth using the '5' and '8' keys to get
yourself into the position which you think gives you the best possible
chance. When you judge a "duck" is directly overhead, press the 'F' key to
fire your patented anti-duck missile. The number after the words "SHOTS
LEFT" (in the top right-hand corner of the screen) will drop, and if you
have been accurate, the number after the word "SCORE" in the top left-hand
corner of the screen will rise.

Note, by the way, that I have deliberately used explicit names for the
variables within this program. That is, the variable name for the score is
"SCORE"; for shots left it is "SHOTS"; for your position down the screen,
"DOWN"; and for your position across the screen, the variable name is
"ACROSS". Even though it takes a little longer to type long variable names
into a program and (of course) they use up more memory than do shorter
names, running out of memory is rarely a problem on the ZX Spectrum, and
the advantages of using explicit names to keep the purpose of various parts
of the listing clear way outweighs the extra time it takes to type them in.
If, for example, you were writing a program like this and you decided that
it would be better if the 'X' was printed slightly further down the screen,
you would not have to search through the program to work out which variable
held your "down" coordinate. If you have used explicit names as in this
case, you would find it very easy to locate the variable you were looking for.

Disappearing ducks?
RUN the program a few times, then return to this magazine for the first
part of our discussion on it. Note the CAPS LOCK must be engaged, as INKEY$
is searching for an input of a capital 'F' to fire.

Line 40 defines the string variable, A$, as a long series of letters and
spaces. The letters can be anything you like; don't feel you need to copy
mine. The important thing, however, is that the string is 32 characters
long. You can check this by RUNning the program briefly, stopping it with
BREAK, then typing in as a direct command: PRINT LEN A$ (you'll find LEN in
green above the K key, and  as you know  you get the words above the keys
by pressing down both CAPS SHIFT and SYMBOL SHIFT at once, then touching
the key). If your string is the correct length, PRINT LEN A$, followed by
ENTER will give you the answer 32.

The appearance of movement which is given to the ducks is created by use of
Sinclair BASIC's string-handling commands, which allow for a technique
called "slicing". The vital line for the movement is line 130, which resets
A$ equal to all of the string without its first character  that is LET
A$=A$(2 T0)  and then adds to the very end of it the character of the string
which was at the beginning, a$(1). The string is reprinted, over and over
again, as the program RUNs (by line 70) in the same position at 7,0 (eight
lines down and starting hard in the left-hand margin). Because the string
is, in effect, being "shifted along" one character at a time before it is
re-printed, the elements in the string appear to move smoothly along. Using
strings in this way is one of the simplest ways there is to create smoothly
moving graphics on the Spectrum.

The string handling also makes it very simple to cause the shot duck to
disappear from the sky. As the string is 32 characters long, each character
"slot" can be refferred to by following A$ with a number in brackets. That
is, A$(1) is the first element of the string, A$(2) is the second one,
and so on, until A$(32) is the very last slot within the string.

Look at line 90. When the computer comes across an IF/THEN statement, it
checks to see if it finds that it is not true, then it moves along to the
next line in the program, without bothering to carry out any further
instructions which may be on the same line. If the computer finds, at the
start of line 90, that INKEY$ does not equal "F" (that is, you are not
pressing the "F" key) then it proceeds to line 100, missing all the
information and instructions which follow the IF INKEY$="F" line. If,
however, you are pressing "F" when the Spectrum gets to line 90, it
continues working through the line and decrements the variable, SHOTS, by
one. Then, it hits another IF/THEN condition, which makes use of the
ability of the Sinclair BASIC to isolate any element of a string instantly.
It looks as A$(ACROSS). The 'X' which is you is printed at ACROSS
(actually, as you see in line 80, a three-element string, with a space
either side of the 'X', is printed at ACROSS minus one, which has the
effect of printing the 'X' at the position referred to by the variable
ACROSS, so A$(ACROSS) lies directly above you.

If line 90 discovers that A$(ACROSS) is anything but a space, you have hit
a duck, so the computer continues working through the line. The variable,
SCORE, is incremented by 57, and finally in line 90, that element of A$ is
set to a blank, so the "duck" disappears.

Now all this takes some time to explain, but you'll find the computer does
it apparently instantaneously. You press 'F', the score increases by 57
(if you're a good shot), the number of shots left drops by one, and the
duck disappears. You'll see (line 110) that the program continues until you
run out of shots; the game then terminates. Take a note of your score at
this point, and see if you can beat it in subsequent runs.

'A l'orange?
Once you have this program running to your satisfaction, and you have a
pretty good idea of how it works, modify it to read like Program 2. (You do
not have to NEW the computer). Just compare the program you have in your
Spectrum, line by line, with the listing of Program 2 and make any changes
you need to (adding a complete new line 15, and modifying certain others).

When you RUN this, you'll see an immediate and quite striking improvement.
Colour certainly adds a lot to any program on the Spectrum. Line 15 sets
the PAPER (that is, the background) colour to white (PAPER colour 7); turns
the BRIGHT control (which affects, in this case, the entire screen); clears
the screen so that the PAPER and BRIGHT are activated (you could not see
them over all the screen unless you had included the CLS command); and
finally, sets the INK colour (the colour in which the computer prints on
the PAPER) to red (INK colour 2).

Even if we did not take the program any further, we would still have a
significant improvement on the first version. You would have the score,
shots left, ducks and the 'X' all printed in red on a bright white
background, which is far more interesting than just plain old black and
white.

However, we want to add two more commands to the program which will alter
the display for the better. These are in lines 70 and 100. In line 70,
the "INK RND*6" is used to choose a colour at random between black and yellow,
so that each time A$ (the ducks) is reprinted, it will occur in a different
colour! As you'll see when the program is RUNning, the change occurs so
rapidly the ducks appear to shimmer. Though it takes the Spectrum an
appreciable number of nanoseconds to generate a random number, the effect
on the speed of the program appears to be nil. (You are probably aware
that, in moving graphics programs, everything you get the computer to do 
from making an IF/THEN decision, adding two numbers together, or raising
one to the power of the other, to generating a random number  takes time,
and the more you get the computer to do before each subsequent frame of a
moving graphics program is printed, the more slowly the graphics will move,
and the more jerky they will appear.)

The last change we've made is in line 100, where FLASH is used to make sure
the actual number of the score, and the number of shots left, flash off and
on, but the rest of the line does not. This is why there are so many FLASH 0
and FLASH 1 commands in that line. Leave any one of them out and the
effect is ruined, as you can easily see by deleting one of them and
re-RUNning the program.

Looping the loop
Apart from the colour changes we've discussed, the program is the same as
the first listing. However, you can see that the few changes we have
introduced have improved it considerably. We'll now continue with the
improvements, by adding some sound, and getting the BORDER (the area around
the picture, or PAPER, area) to flash when a duck is shot.

Enter Program 3, RUN it to decimate a few flocks of ducks, then return to
the magazine for a discussion on the program.

The new lines are 25 and 35 which use the BEEP command to create two
"loops" of sound before the program gets underway. As you know, the BEEP
command has two parameters (and parameters are the numbers, or "arguments"
which follow a command to set its limits). The first number after BEEP
defines the duration of the sound, and the second one its pitch.

Line 25 is a loop, using 'G' as the control variable. The loop runs from
one to 20, and each value of G is used in the second part of line 25 to
create a tone, which  because G is increasing  rises rapidly. The
duration parameter is set at .008 which is about the shortest sound I've
found can be heard clearly. Line 35 produces another loop, this time
counting downwards. You'll discover that different STEP sizes produce quite
different types of loop effects, and you may well wish to change the STEP
size in both this line and in line 25.

These two loops, however, are little more than "window dressing", designed
to produce a good starting effect. The other BEEPs used, by contrast, are
related to other things happening within the program when it is RUNning.
You'll see that a BEEP line has been added at the end of line 70. This
takes the CODE (the number which the computer uses to refer to the
character being printed, so PRINT CHR$ 65 produces the letter 'A', whose
CODE is 65) of the first element of the string A$ (that is the element
which is the furthest to the left) and creates a tone from this. The effect
of this is to produce a short 'beep' just before a duck disappears off the
screen to the left.

You'll see another BEEP command at the end of line 80. This one is sounded
every time the program cycles and, because as the variable ACROSS gets
bigger the pitch of the note gets higher, you'll find that moving your 'X'
across the screen to the right will produce a constantly higher tone;
moving it to the left will lower the tone.

Trigger happy
Perhaps the most interesting sounds are in line 90. Firstly, you get a
BEEP, which is related to the number of shots you have left, every time you
touch 'F', whether you hit anything or not. RUN the program and hold your
finger on 'F'  you'll hear the tone steadily decrease till the "THAT'S THE
END OF THE GAME" message appears.

The next part of line 90, as you know, checks to see if your shot has hit
anything (that is, it checks to see if that particular element of the
string A$ is not equal to a space), and if it finds that it is not a space
(that is, that a "duck" is there and had just that instant been shot), the
computer - as well as increasing your score by 57  BEEPs again, with a
tone which, although different to the first one in the line, is related to
the number of shots left. This means that if you have a successful shot,
you'll hear first the tone (which falls with each shot fired) from the
first part of line 90, followed by a tone (which rises as the SHOTS
variable is decremented) which signals that a duck has been shot. And if
you're not quick in taking your finger off the "trigger", you'll hear a
third one, or even more.

The final part of line 90, which changes the BORDER colour four times, is 
of course  only triggered if you've downed a duck. It has the effect of
the BORDER flashing very quickly in randomly chosen colours, then reverting
to white. The delay caused by including this flash is very short, and gives
good visual feedback to back up the feedback from the BEEP to tell you that
you've bagged another duck.

What's for seconds?
In the second part of this feature, I will be introducing the concept of
the user-defined graphic and how to simply incorporate them into your
programs.

I will be introducing two new and updated versions of the Duck Shoot
program, which will include user-defined graphics as well as more than one
line of ducks! Join me next issue...
