Add two Breakout examples and the tutorials that build them
Some checks failed
akbasic CI Build / cmake_build (push) Failing after 3m10s
akbasic CI Build / sanitizers (push) Failing after 4m5s
akbasic CI Build / coverage (push) Failing after 3m29s
akbasic CI Build / akgl_build (push) Failing after 21s
akbasic CI Build / mutation_test (push) Failing after 3m19s
Some checks failed
akbasic CI Build / cmake_build (push) Failing after 3m10s
akbasic CI Build / sanitizers (push) Failing after 4m5s
akbasic CI Build / coverage (push) Failing after 3m29s
akbasic CI Build / akgl_build (push) Failing after 21s
akbasic CI Build / mutation_test (push) Failing after 3m19s
Two complete games in `examples/breakout/`, both 100% BASIC: `characters/` draws its wall in the text grid with two `DATA` sprites for the ball and paddle, and `sprites/` loads CC0 artwork and captures its whole screen with `SSHAPE`/`SPRSAV`. They take opposite shapes for reasons that are entirely this interpreter's, which is what the chapters are for. `docs/17-tutorial-breakout.md` and `docs/18-tutorial-breakout-artwork.md` build each one a step at a time, and end in a checklist of the rules a real program runs into: create every name before the loop starts, write a text row whole, loop with `GOTO` rather than `DO`, put the float on the left. Every trap is a runnable block with its own output rather than a claim -- the value pool dying at four thousand names, the skipped `BEGIN` block that breaks its caller's `RETURN`, `SSHAPE` ignoring a subscript, `READ`'s single cursor. Five figures, generated from the listings beside them by `docs_screenshots`, and a `breakout_art` setup so the ones that load artwork load the example's own. The character game's wall cannot be photographed -- the screenshot host omits the text layer on purpose -- so it is shown as compared output instead. `docs/07-sound.md` never said `SOUND`'s frequency is a SID register value rather than hertz, which both games depend on. It says so now, with the conversion from `src/audio_tables.c:84`. `TODO.md` gains the thirteen defects the two games turned up -- §6 items 30 to 33 and all of §9 -- each with a reduction that fits on a screen, the file and line of the cause, and what a fix would touch. Verified: `docs_examples` passes in both build configurations, `docs_screenshots --check` re-renders all thirteen figures and byte-compares them, the full 109-test suite passes in both builds, every quoted fragment was checked to appear verbatim in the listing it came from, and every relative link and anchor resolves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
86
examples/breakout/sprites/README.md
Normal file
86
examples/breakout/sprites/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Breakout, with artwork
|
||||
|
||||
Breakout, written entirely in BASIC for the AKGL BASIC interpreter, using downloaded CC0
|
||||
sprite artwork for the paddles, the balls and the powerup gems. The bricks, the HUD and
|
||||
the lettering are drawn, captured with `SSHAPE` and installed as sprites — which is the
|
||||
only way a program in this interpreter can put a picture on the screen.
|
||||
|
||||
```sh
|
||||
../../../build-akgl/basic breakout.bas
|
||||
```
|
||||
|
||||
It needs the SDL build. Without a graphics device the first `SPRSAV` refuses by name and
|
||||
the program stops there, which is the right thing for it to do.
|
||||
|
||||
| Key | Does |
|
||||
|---|---|
|
||||
| left / right | move the paddle |
|
||||
| space | start a game, launch the ball, release a stuck ball |
|
||||
| P | pause |
|
||||
| S | sound on and off |
|
||||
| Q or escape | quit |
|
||||
|
||||
Three lives, six rows of bricks worth 60 down to 10 points a row, and a field that cycles
|
||||
six rows, then five, then four while the ball gets faster every level up to a ceiling. A
|
||||
gem is worth 50 on top of whatever it does.
|
||||
|
||||
## The powerups
|
||||
|
||||
A broken brick drops a gem about one time in seven, and only ever one at a time. Catch it
|
||||
with the paddle. The colour of the gem is what tells you which it is; the banner that
|
||||
flashes over the field names it as well.
|
||||
|
||||
| Gem | Name | Does | For |
|
||||
|---|---|---|---|
|
||||
| red | EXPAND | doubles the paddle's width | 20 seconds |
|
||||
| yellow | MULTI | throws two more balls off the one in play | until they are lost |
|
||||
| green | SLOW | drops the ball's speed to about two thirds | 16 seconds |
|
||||
| blue | STICKY | the ball sticks where it lands; space fires it | 18 seconds |
|
||||
| purple | CATCH | a second bar appears higher up the field | 24 seconds |
|
||||
|
||||
The second bar **mirrors** the paddle rather than following it, so it covers the side you
|
||||
just left. A second bar directly above the first is worth nothing; a mirrored one turns a
|
||||
dive across the field into a save at both ends.
|
||||
|
||||
## How it works, and how to write your own
|
||||
|
||||
**[Chapter 18 of the guide](../../../docs/18-tutorial-breakout-artwork.md)** builds this
|
||||
program a step at a time: budgeting the eight sprite slots, capturing a drawing into one,
|
||||
finding the host's frame boundary with `TI#`, moving everything that is not drawing out of
|
||||
the deadline, the stroke font, and the five things in this dialect that do not do what
|
||||
they look like.
|
||||
|
||||
[Chapter 17](../../../docs/17-tutorial-breakout.md) does the same for
|
||||
[`../characters`](../characters), which builds the same game out of the text grid and two
|
||||
`DATA` sprites — a completely different program, and the shorter one to read first.
|
||||
|
||||
## Where the artwork came from
|
||||
|
||||
Kenney's [Puzzle Pack 1](https://kenney.nl/assets/puzzle-pack-1), released under
|
||||
[CC0](http://creativecommons.org/publicdomain/zero/1.0/). The files in `art/` are the
|
||||
pack's own `PNG/Default/` versions, unmodified, with the pack's licence file beside them.
|
||||
`art/PROVENANCE.md` says which file is used for what and why the double-size set is not.
|
||||
|
||||
Crediting Kenney is not required by CC0. It is here because it should be.
|
||||
|
||||
## What is not in it
|
||||
|
||||
Named honestly rather than left to be discovered:
|
||||
|
||||
- **No music under the game**, only event sounds and two four-note stings. There is room in
|
||||
the third voice for it; there is not much room anywhere else. 121 of the interpreter's
|
||||
128 variables are spoken for, four more are the ones it makes itself, and the label table
|
||||
is at 61 of 64.
|
||||
- **One gem at a time.** There is one sprite slot for it. A brick broken while a gem is
|
||||
falling drops nothing.
|
||||
- **Sticky and multiball share one offset.** Two balls stuck to the paddle at once sit on
|
||||
top of each other. It is rare enough that fixing it would cost a variable I do not have.
|
||||
- **The score lags a frame behind the bricks.** Only one capture happens per frame and the
|
||||
field goes first, so a brick disappears one frame before the score that counts it. At
|
||||
thirty frames a second nobody can see it, and it is a deliberate trade rather than an
|
||||
oversight.
|
||||
- **No high score on disk.** There is no disk.
|
||||
|
||||
The eight interpreter defects this game turned up are filed in `TODO.md` §9, each with a
|
||||
reduction that fits on a screen, the file and line of the cause, and what a fix would
|
||||
touch.
|
||||
Reference in New Issue
Block a user