Trying My Hand at Animation by Moving a Sailboat on My ZX81
A refinement of my earlier picture scene adding in movement using a double buffer.
I was hoping to have finished Gem Quest by now, but May didn’t afford much time. With Summer arriving and the pandemic seeming to be winding down, at least in Boise, my attention is elsewhere. With a short list of ideas, I decided to play off last month's theme. Picture in Motion isn’t new, but it is more interesting to watch.
Playing off last month's ideas.
Not straying too far, I decided to work on something that would’t take me too long to complete. I wanted to try my hand at animating the line drawing. Time kept me from getting too grandiose. As such, Picture In Motion (PIM) is short on excitement.
Like before, the sun and horizon are the same. The boat is technical the same as well, except that it now moves up and down. I added some variability in the motion. It isn’t perfect, but keeps it from being too robotic. The result is a nice floating motion—almost like a paper boat in a pond.
What makes this different?
My real intent was to try my hand at double buffering. I haven‘t used the technique much in my games. Some BASIC games I’ve written used a string variable that acts like a buffer. This time, however, I used a copy of the screen.
In all respects, the buffer is just another version of what the ZX81 usually displays. I set up a place in memory with all the same details. So much so, I had to remember to add in the extra carriage return that is at the start of the real display. Each line also has the invisible return as well. This makes it really easy to mimic what will end up on screen.
Since the line drawing routine first determine where to the screen is, I just swapped that out with the buffer location. Each line is then drawn into the buffer like before. Once everything was done, I bulk copied the buffer into the screen location. As easy as that sounds, I struggled at first to get everything working just right. Mostly, I kept getting little commands wrong.
Fortunately, I was able to get everything working just right. I cheated a bit at first, but soon had it all figured out. Now, I needed to make something move.
Moving the boat.
At this point, it had to rewrite the program. I needed to break things into routines. The original program just printed the drawing. This version needed to print parts of the program. After a bit of refactoring, I had things working as expected.
Moving the boat is just a simple variable that I add to the Y axis of each point. The variable is actually from origin, so it can be negative or positive. Sadly, it took me forever to figure out the code. I kept thinking the coordinates were words, when they were simple bytes.
Another problem was printing too low in the routine. I use the last line to basically clear the screen. This was easier to ensure I also grabbed the return character. The routine that copies the buffer to screen actually copies the entire buffer. If I plotted the line too low, it would copy it over the rest of the buffer. Not quite what I intended.
A little refinement.
The motion worked, but was too repetitive and fast. I had added a delay routine to slow down the animation. To add a bit more organic feel, I added in some randomness to the delay. The delay was still high enough that it didn’t jerk, but more gentle. To top it off, I also check if a key is pressed. You can break out of the program by pressing Q.
Obviously, this program isn’t meant to be a general drawing routine. It was pretty cool to see that Simeon was still working on his code. His was more generic and more interesting. I like what he was doing and I can see a lot of uses for a more generic drawing package.
However, the goal for my routine was to test double buffering. I think it worked extremely well. The animation is smooth and flicker free. I also found it to be pretty fast. The drawings aren’t too complex which helps. But it is good to see it works as expected.
As noted before, I’d really like to try to build a flight simulator of sorts. I think the line would make a great horizon. I’m working through some ideas on how it might look. Of course, a real simulator would require a lot of calculations. I’m thinking something much simpler.