
Readln waits for a whole line and ENTER. That is right for a question, and hopeless for a game: nobody wants to press ENTER after every step. This section reads a single key, the instant it is pressed, and uses it to move something round the screen - which is most of what Warehouse's controls are.
Read(Kbd, Ch);
waits for one key and puts it in the Char variable Ch. No ENTER, and nothing appears on the screen: the program decides what, if anything, to show. Kbd is Turbo's name for the keyboard read that way.
Letters arrive as CAPS LOCK makes them - D or d. A program that does not care which should compare UpCase(Ch), not Ch.
Every key arrives as a character, and some of the Einstein's special keys arrive as characters you might not expect:
| Key | Arrives as | Code |
|---|---|---|
| UP | ^ | 94 |
| LEFT | [ | 91 |
| RIGHT | ] | 93 |
| DOWN | a control character | 10 |
| ENTER | a control character | 13 |
| ESC | a control character | 27 |
The Einstein's arrow keys type characters (S3), which means a game can use them: the program just looks for those characters. A character with no printable form is written in a program as # and its code: #10 is the DOWN key, #27 is ESC. Appendix IV has the full list.
The shape of every key-driven program is the same:
repeat
{ show things as they are }
Read(Kbd, Ch);
{ change things by the key }
until { the key that means stop };
Nothing happens between keys - Read(Kbd, Ch) simply waits - so there is no loop running flat out, no need for {$U+}, and the program costs nothing while the player thinks. For a game where things happen only when the player moves, as in Warehouse, it is exactly right.
When something should keep happening until a key is pressed, the program cannot sit waiting in Read. S14's KeyPressed is true once a key has been pressed; the key is then waiting, and Read(Kbd, Ch) collects it:
repeat
N := N + 1;
GotoXY(10, 5);
Write(N);
until KeyPressed;
Read(Kbd, Ch);
program Walk;
var
X, Y: Integer;
Ch: Char;
begin
ClrScr;
GotoXY(1, 1);
Write('E S D X to move, Q to quit');
X := 20;
Y := 10;
repeat
GotoXY(X, Y);
Write('@');
Read(Kbd, Ch);
GotoXY(X, Y);
Write(' ');
case UpCase(Ch) of
'E', '^': Y := Y - 1;
'X', #10: Y := Y + 1;
'S', '[': X := X - 1;
'D', ']': X := X + 1;
end;
until UpCase(Ch) = 'Q';
GotoXY(1, 20);
end.
Each time round: draw the @, wait for a key, rub the @ out, work out where it goes. The letters E, S, D and X make the same diamond as the editor's keys (S5), and the arrow keys work too, because the case accepts the characters they send.
Starting from
Turbo freshly started, Y, a new work file called WALK.
What you should see
The instructions at the top and an @ near the middle. Each press of E, S, D or X - or an arrow key - moves it one square. Q stops the program. Press D three times, X twice, S once and E once, then UP, LEFT and DOWN once each, and the @ ends one column right of and one row below where it started.
@ (GotoXY(X, Y); and Write(' ');, straight after the Read). What does moving leave behind?case UpCase(Ch) of to case Ch of, and try it with CAPS LOCK on and then off. When does it stop answering the letter keys?24.1 Print the code of every key pressed, until Q is pressed. Try the arrows, ENTER, ESC and DELETE.
24.2 Count upwards in the same place on the screen until any key is pressed.
24.3 Stop the walker leaving the screen: keep it between columns 1 and 39, and rows 2 and 23.
Worked solutions are in Appendix II.
| Symptom | Cause |
|---|---|
| The letter keys do nothing | The program compares Ch with capitals but CAPS LOCK is off (or the other way round). Use UpCase(Ch). |
| The DOWN key does nothing | Its code, 10, is not in the case. Add #10. |
| A trail of characters is left behind | The old position is not rubbed out before moving. |
| The screen jumps up a line | Something was drawn in (40, 24) (S23). Keep the walker off the bottom row. |
Read(Kbd, Ch) takes one key, with no ENTER and no echo. The Einstein's arrows arrive as ^, [, ] and #10, so games can use them; letters come as CAPS LOCK makes them, so compare with UpCase. KeyPressed says a key is waiting. A key-driven game waits for a key, acts, redraws what changed, and goes round again.
S25, Chance - random numbers, and a program that does something different every time.