How I Made a Kimmie Fish Swim on the ZX81


A retro animation written in ZX81 BASIC.


Reading posts in the BASIC group I follow, I was I was inspired to write my own version of the kimmie fish animation for the ZX81 computer. It was such a cute animation that I had to see if I could replicate it. Although not quite the same as the original, the spirt is there.

# Getting started.
Although the original version was written using BASIC, it was using commands not available on the ZX81. That usually isn't too big an issue as I can convert most. But in this case, it used graphic commands and a line generator. Although possible to replicate, it would make the animation extremely slow. Fortunately, there was a solution.

Kimmie Fish, Sprite Frames, 2023 by Steven ReidKimmie Fish, Sprite Frames, 2023 by Steven Reid

I realized that I could replace the line drawing routines with character graphics. Not only would it be faster, but it would simplify the program. I whipped up some sprites and got to work building the program.

Kimmie Fish, 2023 by Steven ReidKimmie Fish, 2023 by Steven Reid

# Coding it up.
The code was pretty straight forward. I started with a GOSUB to setup the screen and variable. I built a routine to for the aquarium—something not in the original. Having programed a number of animations in ZX81 BASIC, I decided to use a string array. More on that in a bit.

In actuality, I had two arrays. One for the fish moving right, and one left. The advantage of that was each fish prints over itself so I could avoid a double buffer. This kept the routine reasonably fast. But it had another advantage.

Kimmie Fish, 2023 by Steven ReidKimmie Fish, 2023 by Steven Reid

The problem I had to deal with was the fish swimming off screen. This was the advantage of using a string array. As the kimmie fish reached an edge, I would only print the part of the array that was visible. Although straightforward, it took time and testing to work out the math. Here is the routine.

 30 REM **MAIN LOOP
  40 LET LS=(-D+1 AND D<0)+(1
AND D>=0)
  50 LET LE=(6+(26-D) AND D>25)+
(6 AND D<26)
  60 LET DX=(0 AND D<0)+(D AND D
>=0)
  70 LET RS=(-B+1 AND B<0)+(1
AND B>=0)
  80 LET RE=(6+(26-B) AND B>25)+
(6 AND B<26)
  90 LET BX=(0 AND B<0)+(B AND B
>=0)
 100 PRINT AT A,BX;R$(R,1,RS TO
RE);AT A+1,BX;R$(R,2,RS TO RE);
AT A+2,BX;R$(R,3,RS TO RE)
 110 PRINT AT C,DX;L$(L,1,LS TO
LE);AT C+1,DX;L$(L,2,LS TO LE);
AT C+2,DX;L$(L,3,LS TO LE)

Although it looks complex, it is actually straight forward logic. The variables LS and LE, for example, stand for left start and left end. They are the calculated positions within the string array. Since the sprite doesn’t move at the edges, the DX variable is used to stop moving it. The other variables determine position and which frame to display.

# Putting it all together.
The final result is a decent little screen saver for the ZX81. I’m proud of the routine that moves the fish off the screen. In the past I brute forced that with an if statement. This program version is a bit more creative, although I suspect much slower.

Kimmie Fish, Video, 2023 by Steven ReidKimmie Fish, Video, 2023 by Steven Reid

One thing I didn’t like was that the animation felt a bit jerky at times. The display I rewrote the routine using a string array for the screen. This acted as a sort of double buffer. Although the print felt smoother, it was much slower. I ended up abandoning that solution for the original.

Now, although the BASIC version is nice. I kept thinking about all the ways I could make it better. Not only would assembly be faster, but I could enhance the overall look quite a bit. I’ll share how that came out in a future article. Until then, you can also view the animation on YouTube.



Comments on this article:

No comments so far.

Write a comment:

Type The Letters You See.
[captcha image][captcha image][captcha image][captcha image][captcha image][captcha image]
not case sensitive