Ships Attack

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

Ships Attack is a dodge-and-survive game in which the player moves a ship left and right along the bottom of the screen to avoid falling bombs. Four bombs descend simultaneously at staggered starting rows, each assigned a different INK color (1–4) for visual distinction. When the score reaches 25 points, the variable `s` increments from 1 to 2, doubling the descent speed of all bombs. Collision detection is handled by checking whether the horizontal distance between a bomb column and the ship position falls within a five-cell window.


Program Structure

The program is divided into two logical sections. Lines 10–15 display the title screen and instructions, then line 20 calls the initialization subroutine at line 200. The main game loop runs from line 30 to line 170, with the subroutine (lines 200–270) and a DATA statement (line 280) sitting below the REM marker at line 199.

LinesRole
10–15Title screen and instructions
20GO SUB to initialization
30Erase old bomb sprites
40Read keyboard and update ship column v
50Draw player ship at row 20
60–160FOR loop updating and drawing each bomb, checking collision
170GO TO 30 (main loop back-edge)
200–270Initialization subroutine
280DATA for initial bomb positions

Initialization Subroutine

The subroutine at line 200 sets PAPER color 5, clears the screen, defines sprite strings, resets game variables, dimensions the bomb arrays, reads starting row/column pairs from DATA, and prints the score header. Four bombs begin at rows 16, 12, 4, and 8 (columns 4, 8, 16, 20 respectively), giving them staggered vertical positions so they do not all arrive at the player simultaneously.

Sprite Representation

Both the player ship and the bombs are represented as string literals built from block graphics characters. v$ (line 210) is a multi-character ship sprite using block graphic tiles to form a wider visual. s$ (line 220) is the two-character bomb sprite. Each bomb is rendered with INK i where i is the loop index (1–4), giving each bomb a unique color without any extra variables.

Movement and Input

Line 40 uses a compact Boolean arithmetic idiom common in Sinclair BASIC:

LET v=v+(INKEY$="8" AND v<23)-(INKEY$="5" AND v>3)

The relational expressions evaluate to 1 (true) or 0 (false), so the addition and subtraction act as conditional increments/decrements. Boundary checks (v<23 and v>3) are embedded directly in the same expression, preventing the ship from moving off-screen.

Bomb Descent and Speed Increase

Each bomb’s row is stored in b(i) and its column in c(i). On each frame, if a bomb has not yet reached row 20 it is advanced by s rows (line 120). Initially s=1; when the score p reaches 25, line 100 sets s=2, doubling descent speed for all bombs simultaneously. When a bomb passes row 20 it is recycled (line 80): its row resets to 4 and its column is randomized near the current ship position (v-3 + INT(RND*11)), which creates mild homing behavior.

Scoring

A point is awarded each time any bomb is recycled (i.e., successfully dodged), incrementing p and immediately updating the display at line 90. The score is printed at position row 0, column 8 over the pre-printed “POINTS: 0” header established in the subroutine.

Collision Detection

Collision is tested only when a bomb reaches row 20 or beyond (line 140 guards line 150). The check on line 150 is:

IF (c(i)-v<5 AND c(i)-v>0)

This tests a five-column window to the right of the ship’s left edge. Notably, it does not catch cases where c(i)-v is zero or negative beyond the window (e.g., a bomb directly on or to the left of the ship anchor). This means bombs landing exactly on the ship column or slightly left may not trigger a game over, which is a minor collision detection anomaly. On a hit, a BEEP is sounded, colors are reset, and the program restarts at line 10.

Screen Erasure

Rather than clearing the entire screen each frame, line 30 erases only the previous bomb positions by printing a space at each stored b(i), c(i) coordinate before updating them. This avoids flicker from full-screen CLS calls during gameplay and is a standard sprite-erasure technique for this platform.

Notable Idioms

  • PAUSE NOT PI on line 15 — since PI is non-zero, NOT PI evaluates to 0, so PAUSE 0 waits indefinitely for a keypress.
  • Using INK i inside the PRINT statement to color-code each bomb by loop index.
  • Recycling bombs near the player’s position to maintain game pressure as the player’s score climbs.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

   10 CLS :PRINT '' TAB 10;"SHIPS ATTACK"
   15 PRINT '''"USE 5 KEY TO MOVE SHIP TO LEFT   AND 8 KEY TO MOVE SHIP TO RIGHT .. THIS WILL AVOID THE BOMBS     AND BUILD UP YOUR SCORE."'''''"Press any key when ready":PAUSE NOT PI
   20 GO SUB 200
   30 FOR i=1 TO 4:PRINT AT b(i),c(i);" ";:NEXT i
   40 LET v=v+(INKEY$="8" AND v<23)-(INKEY$="5" AND v>3)
   50 PRINT AT 20,v; INK 6;v$;
   60 FOR i=1 TO 4
   70 IF b(i)<20 THEN GO TO 120
   80 LET b(i)=4:LET c(i)=v-3+ INT (RND*11)
   90 LET p=p+1:PRINT AT 0,8;p;
  100 IF p=25 THEN LET s=2
  110 GO TO 130
  120 LET b(i)=b(i)+s
  130 PRINT AT b(i),c(i); INK i;s$;
  140 IF b(i)<20 THEN GO TO 160
  150  IF (c(i)-v<5 AND c(i)-v>0) THEN BEEP 2,20:INK 0:PAPER 7:CLS :GO TO 10
  160 NEXT i
  170 GO TO 30
  199 REM init.
  200 PAPER 5:CLS 
  210 LET v$=" \'.\..\..\.' "
  220 LET s$="\.."
  230 LET s=1:LET p=0:LET v=13
  240 DIM b(4):DIM c(4)
  250 FOR i=1 TO 4:READ b(i):READ c(i):NEXT i
  260 PRINT AT 0,0;\{19}\{0}\{19}\{0}\{19}\{0}"POINTS: 0";
  270 RETURN 
  280 DATA 16,4,12,8,4,16,8,20
 9999 SAVE "S. Attack"\{17}\{3} LINE 1

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top