Turbo Pascal 2.0 course cover
← Back to Courses
module
24

Keys Without ENTER

Introduction

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)

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.

The Einstein's Keys As Characters

Every key arrives as a character, and some of the Einstein's special keys arrive as characters you might not expect:

KeyArrives asCode
UP^94
LEFT[91
RIGHT]93
DOWNa control character10
ENTERa control character13
ESCa control character27

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.

A Key-Driven Loop

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.

KeyPressed

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);

The Code

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.

Change One Thing

  • Take out the two lines that rub out the @ (GotoXY(X, Y); and Write(' ');, straight after the Read). What does moving leave behind?
  • Change 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?
  • Change the four letters to I, J, K and L (and the instructions to match). Which do you prefer?

Exercises

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.

When It Goes Wrong

SymptomCause
The letter keys do nothingThe program compares Ch with capitals but CAPS LOCK is off (or the other way round). Use UpCase(Ch).
The DOWN key does nothingIts code, 10, is not in the case. Add #10.
A trail of characters is left behindThe old position is not rubbed out before moving.
The screen jumps up a lineSomething was drawn in (40, 24) (S23). Keep the walker off the bottom row.

Summary

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.

Next

S25, Chance - random numbers, and a program that does something different every time.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.