# 8. Sprites Eight sprites, numbered 1 to 8, as on a C128. They need the SDL build. A sprite here is a real object in the host's graphics library, registered alongside whatever the host's own game is drawing — so a game that embeds this interpreter can see and manipulate a script's sprites. ## Giving a sprite a picture `SPRSAV` does it, and it takes three kinds of source. ### From an image file ``` 10 SPRSAV "ship.png", 1 ``` The most useful form, and not one a C128 has. The path is tried against the working directory first and then against the directory the running program was loaded from — so a `.bas` stored beside its artwork works wherever you launch it from. Anything the image library can decode will do. A sprite loaded this way takes **the image's own size**. It is not forced to 24 by 21. ### From a saved region ``` 10 BOX 1, 0, 0, 24, 21 20 SSHAPE A$, 0, 0, 24, 21 30 SPRSAV A$, 1 ``` Draw it with the graphics verbs, capture it, install it. The C128 documents `SPRSAV`'s string as the `SSHAPE` data format at a fixed 24 by 21, so sharing the mechanism is faithful rather than a shortcut. ### From data ``` 10 DIM P#(63) 20 FOR I# = 0 TO 62 30 READ P#(I#) 40 NEXT I# 50 SPRSAV P#, 1 60 DATA 255, 129, 129, ... ``` 63 bytes: three per row, twenty-one rows, most significant bit leftmost. This is the form a type-in listing uses. **It takes an integer array, not a string.** A C128 puts the raw bytes in a string; a string here is NUL-terminated, so it cannot hold a zero byte and therefore cannot hold a sprite. `DIM P#(63)` is exactly the right size. Writing a sprite back out — `SPRSAV 1, A$` — is refused. That would be a disk operation. ## Showing and moving ``` 10 SPRITE 1, 1, 3 20 MOVSPR 1, 100, 50 ``` `SPRITE n [,on] [,colour] [,priority] [,xexpand] [,yexpand] [,multicolour]`. Only the number is required and **an argument you leave out is left alone**, so `SPRITE 1, 1` turns sprite 1 on without disturbing its colour. `MOVSPR` has four forms, and the punctuation is what tells them apart: | Form | What it does | |---|---| | `MOVSPR 1, 100, 50` | put it at (100, 50) | | `MOVSPR 1, +10, -20` | move it *by* that much | | `MOVSPR 1, 10 ; 90` | move it 10 pixels along bearing 90 | | `MOVSPR 1, 45 # 8` | set it moving along bearing 45 at speed 8 | A bearing is degrees **clockwise from straight up**, so 0 is north and 90 is east. In the polar form the distance comes first and the angle second — the opposite order from the continuous form, which is a trap worth remembering. The continuous form does not move anything on the statement itself. The sprite moves as the program runs, paced by the host's clock. Speed 0 stops it. Coordinates are the same 320 by 200 space the drawing verbs use, not the VIC-II's raster coordinates. ## Collision ``` 10 COLLISION 1, BUMPED 20 REM ... main loop ... 90 GOTO 20 100 LABEL BUMPED 110 PRINT "HIT: " + BUMP(1) 120 RETURN ``` `COLLISION 1, target` calls a subroutine when two sprites overlap. The handler is entered between lines and must end in `RETURN`, exactly like a `GOSUB` body. Omitting the target disarms it. `BUMP(1)` returns a bitmask of which sprites have collided — bit 0 is sprite 1 — and **reading it clears it**, which is what makes "has anything hit me since I last looked" answerable. Only type 1, sprite-to-sprite, is implemented. Types 2 and 3 are refused by name. Collision is by bounding box, not by pixel: two sprites whose boxes overlap but whose artwork does not are reported as colliding. ## Reading state back | Function | Gives | |---|---| | `RSPPOS(n, 0)` | x | | `RSPPOS(n, 1)` | y | | `RSPPOS(n, 2)` | speed | | `RSPRITE(n, f)` | one of `SPRITE`'s settings, in `SPRITE`'s own argument order | | `RSPCOLOR(1)` or `RSPCOLOR(2)` | one of the shared multicolour registers | These read the interpreter's own state rather than asking the device, so they work even with no device attached. ## SPRDEF Not implemented, and deliberately. It is an interactive full-screen sprite editor driven by single keystrokes, not something a program can call — and this interpreter does not own the screen it would take over. The three `SPRSAV` forms replace it.