--- title: "Ships Attack" id: 71339 type: "computer_media" slug: "ships-attack-2" url: "http://localhost/computer_media/ships-attack-2/" markdown_url: "http://localhost/computer_media/ships-attack-2.md" published_at: "2026-09-02T06:54:43+00:00" modified_at: "2026-09-02T06:54:43+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/Ships-Attack.png" excerpt: "Dodge four color-coded falling bombs with your ship, and survive long enough to face the speed increase that kicks in at 25 points." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Ships%20Attack%20(198x)(-)(TS2068)(US)(Program).zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/Ships-Attack.png" media_type_tags: "Game" --- # Ships Attack 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. | Lines | Role | | --- | --- | | 10–15 | Title screen and instructions | | 20 | GO SUB to initialization | | 30 | Erase old bomb sprites | | 40 | Read keyboard and update ship column `v` | | 50 | Draw player ship at row 20 | | 60–160 | FOR loop updating and drawing each bomb, checking collision | | 170 | GO TO 30 (main loop back-edge) | | 200–270 | Initialization subroutine | | 280 | DATA 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. ## 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 ```