Skip to content

One press, one step

Wait for release, add a quit key and save the finished movement experiment.

  • Sinclair ZX Spectrum
  • BASIC

Holding a key is useful for travelling across a screen. Choosing one menu item or moving one board square may feel better with one action per press. We’ll keep the held-key version for comparison and make a second version that waits for release.

Save the program from Let the player steer as held before editing. Use the tape-saving workflow to keep an exported copy, not just a program name in memory.

Wait for the next press

Add 51, 59, 71, 72, 160, 170 and 200. Replace 90, 95 and 100, and delete 140 and 150. Here is the whole program:

step-01.bas
  10 PAPER 0
  20 INK 7
  30 BORDER 0
  40 CLS
  50 PRINT "o left   p right"
  51 PRINT "One press, one step. q quits."
  55 LET row=10
  56 LET col=15
  59 IF INKEY$<>"" THEN GO TO 59
  60 PRINT AT row,col;"O"
  70 LET k$=INKEY$
  71 IF k$="" THEN GO TO 70
  72 IF k$="q" THEN GO TO 200
  75 LET nextcol=col
  80 IF k$="o" THEN LET nextcol=col-1
  85 IF k$="p" THEN LET nextcol=col+1
  90 IF nextcol<1 THEN GO TO 160
  95 IF nextcol>30 THEN GO TO 160
 100 IF nextcol=col THEN GO TO 160
 110 PRINT AT row,col;" "
 120 LET col=nextcol
 130 PRINT AT row,col;"O"
 160 IF INKEY$<>"" THEN GO TO 160
 170 GO TO 70
 200 STOP

Line 59 waits until INKEY$ is empty. This stops a key still held from launching the program being treated as the first move. The marker appears when the keys are released. Enter INKEY$ using Shift+left Option/Alt, release the chord, then N. Enter the single not-equal token <> with left Option/Alt+W.

Line 71 returns to reading when no key was captured. Only a non-empty reading continues to the movement or quit decisions. This matters: if we entered the release loop while idle, a newly arriving press could be discarded before its action was considered.

The movement decisions retain their order. Their exits now reach line 160, which keeps reading until the key is released. Line 170 then returns to the main input check. Holding p gives one step; releasing and pressing p again gives a second step.

Rejected moves also wait for release. At an edge, one press remains one attempt, rather than a stream of attempts while the same key is held. The empty-input case returns at line 71, before the release loop.

Line 72 recognises lower-case q and goes to our deliberate STOP at 200. It sits before the movement tests, so q does not need to be interpreted as a move. If a direction is still held, release it before pressing q: the release loop waits for the current input to end. Shift+Space remains the emergency BREAK chord if you need to stop a mistyped program.

Give the ending a place

Replace line 200 and add 210:

step-02.bas
  10 PAPER 0
  20 INK 7
  30 BORDER 0
  40 CLS
  50 PRINT "o left   p right"
  51 PRINT "One press, one step. q quits."
  55 LET row=10
  56 LET col=15
  59 IF INKEY$<>"" THEN GO TO 59
  60 PRINT AT row,col;"O"
  70 LET k$=INKEY$
  71 IF k$="" THEN GO TO 70
  72 IF k$="q" THEN GO TO 200
  75 LET nextcol=col
  80 IF k$="o" THEN LET nextcol=col-1
  85 IF k$="p" THEN LET nextcol=col+1
  90 IF nextcol<1 THEN GO TO 160
  95 IF nextcol>30 THEN GO TO 160
 100 IF nextcol=col THEN GO TO 160
 110 PRINT AT row,col;" "
 120 LET col=nextcol
 130 PRINT AT row,col;"O"
 160 IF INKEY$<>"" THEN GO TO 160
 170 GO TO 70
 200 PRINT AT 20,0;"Finished. RUN to try again."
 210 STOP

After q, line 200 puts the message on row 20, away from the controls and marker. Line 210 stops. The marker remains where the player left it, and RUN offers another attempt. This is an experiment with a settled ending, not a game that needs a score or a win condition.

The experiment keeps the marker visible and prints a clear ending after q.
The experiment keeps the marker visible and prints a clear ending after q.

Test a long held press, release and press again, then try an unrelated key. Move to both boundaries. Try q after a move and while no direction is held. The stored position and the drawn marker should agree in every case.

Choose the behaviour for the job

Compare the saved held version with this one. Which would you choose for a character walking along a corridor? Which for choosing a square on a board? Neither response is universally right: travel often benefits from repetition; a single selection often needs a fresh press.

Could an enemy keep moving while this release loop waits?

Not if its update were elsewhere in this program. While line 160 loops, those other instructions do not run. A continuously moving game would keep updating the world and remember whether each key was down on the previous pass, instead of stopping everything to wait for release.

That distinction matters on modern machines too: input handling should support the player’s task without preventing other necessary work. The details of their input systems differ from this Spectrum polling loop.

Save this version as marker, keep the tape, reset the Spectrum and load it again. In the page, make the editor below match your program and press Download tape for marker.tap, then load it as in Remember a name; keep the program.

Original code

Opens in your Spectrum.

Edit this listing, then run it. Changes are marked against the original code.

Listing options

Original code

  10 PAPER 0
  20 INK 7
  30 BORDER 0
  40 CLS
  50 PRINT "o left   p right"
  51 PRINT "One press, one step. q quits."
  55 LET row=10
  56 LET col=15
  59 IF INKEY$<>"" THEN GO TO 59
  60 PRINT AT row,col;"O"
  70 LET k$=INKEY$
  71 IF k$="" THEN GO TO 70
  72 IF k$="q" THEN GO TO 200
  75 LET nextcol=col
  80 IF k$="o" THEN LET nextcol=col-1
  85 IF k$="p" THEN LET nextcol=col+1
  90 IF nextcol<1 THEN GO TO 160
  95 IF nextcol>30 THEN GO TO 160
 100 IF nextcol=col THEN GO TO 160
 110 PRINT AT row,col;" "
 120 LET col=nextcol
 130 PRINT AT row,col;"O"
 160 IF INKEY$<>"" THEN GO TO 160
 170 GO TO 70
 200 PRINT AT 20,0;"Finished. RUN to try again."
 210 STOP

Your Spectrum

48K · PAL

Click the screen to send it keys. Tab returns to the controls.

Not started.

On-screen keys
Keyboard and Session

Shift is CAPS SHIFT. Alt or Option is SYMBOL SHIFT. Comma and full stop use their Spectrum key combinations automatically. Escape sends BREAK while the screen has focus. Enter submits a line. Restart clears this session. Returning to the lesson pauses it.

To type into this screen, use a physical keyboard. On a touchscreen, edit the listing in the lesson and choose Run this code. Open On-screen keys here to answer numeric INPUT prompts or send BREAK.

Runs the Sinclair 48K ROM. Amstrad have kindly given their permission for the redistribution of their copyrighted material but retain that copyright.

Download Emu198x for desktop
Screen text
The Spectrum has not started yet.

Check one move and q. A successful save message is useful; loading and using the result checks that you kept the program you intended.

What we can now make

We have written a story toy, a guessing game, a playful oracle and a movement experiment. Each grows from instructions we can inspect: values are stored, conditions choose a route, loops repeat work, and routines give a repeated job one home. Printing and sound make that work perceptible.

Pick one small change and predict its effect before editing: a story prompt, a clue’s wording, an oracle reply, or the movement margin. Check the unchanged behaviour as well as the change. For a margin, that means testing both edges; for a reply, it means deliberately selecting that reply.

Bright Spark brings these ideas into a memory game. Foundations offers pseudocode views of the same concepts; The Craft explores how rules and feedback shape play. They are useful routes for curiosity, not attendance requirements. Keep the programs you have made. They are small enough to understand and substantial enough to change on purpose.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 18, “Motion”, pp. 129–131; appendix C, INKEY$, STOP and PRINT AT.

Run it here

This unit's program, built for you.

Program
step-02.tap
Machine
ZX Spectrum 48K (PAL)

Download step-02.tap