Skip to content

Arrive gently

Combine position and velocity in a soft docking challenge.

  • Sinclair ZX Spectrum
  • BASIC

Give the journey a destination: a white docking box. Getting there is only half the task. You must arrive slowly enough to stay in control.

Replace lines 1010, 6020.

Add lines 360, 1040, 1050.

changes.bas
 360 IF x>=190 AND x<=210 AND y>=94 AND y<=114 AND vx*vx+vy*vy<=.16 THEN LET e$="Docked. A soft arrival!": GO TO 4000
1010 PRINT AT 0,2; INK 5;"DRIFT";AT 0,19; INK 7;"SOFT DOCK"
1040 PLOT INK 7;184,88: DRAW INK 7;32,0: DRAW INK 7;0,32: DRAW INK 7;-32,0: DRAW INK 7;0,-32
1050 PRINT AT 5,23; INK 5;"DOCK"
6020 IF vx*vx+vy*vy<=.16 THEN PRINT AT 1,17; INK 4;"DOCK OK "

RUN the changed program.

Complete source at this checkpoint
drift.bas
  10 GO SUB 7000
 100 LET x=48: LET y=56: LET vx=0: LET vy=0: LET h=2: LET steps=0
 110 GO SUB 1000: GO SUB 3000: GO SUB 6000
 200 LET k$=INKEY$
 210 IF k$="q" OR k$="Q" THEN GO TO 9000
 220 IF k$="r" OR k$="R" THEN GO TO 100
 230 GO SUB 3000
 240 IF k$="o" OR k$="O" THEN LET h=h+1
 250 IF k$="p" OR k$="P" THEN LET h=h-1
 260 IF h=9 THEN LET h=1
 270 IF h=0 THEN LET h=8
 280 IF k$<>" " THEN GO TO 320
 290 LET vx=vx+.2 *a(h): LET vy=vy+.2 *b(h)
 300 LET speed=SQR (vx*vx+vy*vy)
 310 IF speed>3 THEN LET vx=3 *vx/speed: LET vy=3 *vy/speed
 320 LET nx=x+vx: LET ny=y+vy
 330 IF nx<22 OR nx>233 OR ny<30 OR ny>145 THEN GO SUB 3000: LET e$="Hull lost. Try a gentler burn.": GO TO 4000
 340 LET x=nx: LET y=ny: LET steps=steps+1
 350 GO SUB 3000
 355 IF k$=" " THEN GO SUB 6000
 360 IF x>=190 AND x<=210 AND y>=94 AND y<=114 AND vx*vx+vy*vy<=.16 THEN LET e$="Docked. A soft arrival!": GO TO 4000
 370 GO TO 200
1000 BORDER 0: PAPER 0: INK 7: CLS
1010 PRINT AT 0,2; INK 5;"DRIFT";AT 0,19; INK 7;"SOFT DOCK"
1020 PRINT AT 1,2;"SPEED"
1030 PLOT INK 1;15,24: DRAW INK 1;0,128: DRAW INK 1;225,0: DRAW INK 1;0,-128: DRAW INK 1;-225,0
1040 PLOT INK 7;184,88: DRAW INK 7;32,0: DRAW INK 7;0,32: DRAW INK 7;-32,0: DRAW INK 7;0,-32
1050 PRINT AT 5,23; INK 5;"DOCK"
1060 PRINT AT 19,2; INK 5;"O/P turn   SPACE thrust"
1070 PRINT AT 20,2; INK 7;"DRIFT"
1080 PRINT AT 21,2; INK 5;"R retry              Q quit";
1090 RETURN
3000 LET px=INT (x+.5): LET py=INT (y+.5)
3010 PLOT INK 7; OVER 1;px+c(h),py+d(h)
3020 DRAW INK 7; OVER 1;e(h)-c(h),f(h)-d(h)
3030 DRAW INK 7; OVER 1;g(h)-e(h),j(h)-f(h)
3040 DRAW INK 7; OVER 1;c(h)-g(h),d(h)-j(h): RETURN
4000 PRINT AT 1,0;"                                ";AT 1,2; INK 6;e$
4010 PRINT AT 20,2;"R plays again. Q quits.      "
4020 IF INKEY$<>"" THEN GO TO 4020
4030 LET k$=INKEY$
4040 IF k$="q" OR k$="Q" THEN GO TO 9000
4050 IF k$="r" OR k$="R" THEN GO TO 100
4060 GO TO 4030
6000 LET speed=SQR (vx*vx+vy*vy)
6010 PRINT AT 1,8; INK 7;INT (10 *speed+.5)/10;"  "
6020 IF vx*vx+vy*vy<=.16 THEN PRINT AT 1,17; INK 4;"DOCK OK "
6030 IF vx*vx+vy*vy>.16 THEN PRINT AT 1,17; INK 6;"TOO FAST"
6040 LET u$="E": LET w$="N"
6050 IF vx<-.001 THEN LET u$="W"
6060 IF vy<-.001 THEN LET w$="S"
6070 IF ABS vx<.001 THEN LET u$="-"
6080 IF ABS vy<.001 THEN LET w$="-"
6090 PRINT AT 20,8; INK 7;u$;" ";INT (10 *ABS vx+.5)/10;"  ";AT 20,16;w$;" ";INT (10 *ABS vy+.5)/10;"  ": RETURN
7000 DIM a(8): DIM b(8): DIM c(8): DIM d(8): DIM e(8): DIM f(8): DIM g(8): DIM j(8)
7010 FOR i=1 TO 8: LET angle=(i-1)*PI/4
7020 LET a(i)=COS angle: LET b(i)=SIN angle
7030 LET c(i)=INT (5 *a(i)+.5): LET d(i)=INT (5 *b(i)+.5)
7040 LET e(i)=INT (-3 *a(i)-3 *b(i)+.5): LET f(i)=INT (-3 *b(i)+3 *a(i)+.5)
7050 LET g(i)=INT (-3 *a(i)+3 *b(i)+.5): LET j(i)=INT (-3 *b(i)-3 *a(i)+.5)
7060 NEXT i: RETURN
9000 PAPER 0: INK 7: PRINT AT 21,0;"Finished. RUN to try again.     ";: STOP

The ship starts at the lower left, pointing towards the upper right. Use a short initial burn, then turn and counterthrust before reaching the dock. Adjust the horizontal and vertical motion as needed. R lets you try a different approach.

The white vector ship resting inside the docking square, with the message Docked. A soft arrival!
A successful approach freezes the ship and offers another attempt.

The box and the centre

The drawn box spans x=184–216 and y=88–120. Our success test uses a smaller rectangle for the ship’s centre: x=190–210 and y=94–114, including the edges.

That six-pixel margin leaves room for the ship. At any heading, no triangle offset extends more than five pixels along either axis. Testing the centre against the inner rectangle therefore keeps the complete outline within the drawn box, with some room to spare.

These are geometric tests. The white border is a guide, not a solid wall: you can pass through it too quickly without winning or crashing. The outer arena still ends a flight.

Position and speed together

Line 360 joins five conditions with AND: a lower and upper bound for x, a lower and upper bound for y, and the squared-speed limit. All must be true in the same update.

The cue now reads DOCK OK instead of SLOW. It still describes speed only. You can see DOCK OK at the starting position because the ship is stationary, but that does not mean it has docked. Conversely, being in the box while TOO FAST is showing does not finish the flight.

The test uses the unrounded velocity, just like the cue. A displayed speed of .4 is not enough to decide: values slightly above .4 can round to the same number.

At x=200, y=104 with vx=.3 and vy=.3, will the game announce a successful dock?

Show the explanation

The centre is within both position ranges, but squared speed is .18. That exceeds .16, so the flight continues. Reducing either component enough could bring the speed within the limit while the ship is still inside the box.

Finish at a valid position

The loop checks the candidate position against the arena first. If it is safe, the program accepts the position, draws the ship and refreshes the readout when necessary. Only then does it test docking.

Success puts a message into e$ and jumps to the same result routine used by wall failure. There is no further position update there. The ship freezes, and the routine waits until the current key is released before listening for R or Q. That prevents the key held at arrival from immediately choosing another action.

Try entering the box too quickly, then returning slowly. Also stop outside it and inspect the cue. If the game announces success outside the dock, check all four position comparisons and their ANDs. If a slow approach fails, look at both components and ensure the centre, rather than just the nose, has entered the inner region.

Sources

Steven Vickers, edited by Robin Bradbeer, ZX Spectrum BASIC Programming, second edition (Sinclair Research, 1983), chapter 13, chapter 17. Chapter 13 describes AND in conditions; chapter 17 describes the drawing commands. Dock dimensions and the .4 speed threshold are game-design choices.

Run it here

This unit's program, built for you.

Program
drift.tap
Machine
ZX Spectrum 48K (PAL)

Download drift.tap