Enterprise Forever

:UK => Programming => Topic started by: JSP on 2019.May.20. 16:42:40

Title: Sprites and BASIC (with some help from ZZZIP)
Post by: JSP on 2019.May.20. 16:42:40
A month or two ago I asked myself the question - can you make a reasonable 'sprite' based game in BASIC and then compiled with ZZZIP. To produce a satisfying result some requirements needed to be satisfied:

- Flicker free.
- Pixel precise collision check.
- Ability to move in front of or behind objects on the background.
- A reasonable frame rate (+10 fps)

In other words, similar features to what you would expect from a MC program - except for the frame rate. This is after all BASIC even if speed enhanced by being run through a compiler.

I included some other feature, that might be of interest, even if they are not essential.

- Restart (RUN) the program in more than one resolution dynamically.
- Stop the program if the sprite reaches the right border zone. This was so I could test the frame rate speed, which clocked in at about 155 frames in 14 secondes, or 11 FPS with a standard 4 MHz EP128 machine.

The controls are laid out as follows:

Cursor keys: Increase or decrease speed in four directions. 4 speed levels.
<1> RUN program in graphics mode 5, colour mode 1.
<2> RUN program in graphics mode 1, colour mode 1.
<3> Fly behind other objects on the display.
<4> Collide with other objects on the display.
<5> Fly in front of other objects on the display.

When the ship reaches the border it stops in that direction - except for the right border, where the program stops, and running time is displayed.

I use a three-buffer display. Two buffers for alternating the graphics and a third for collision check. The advantage is that I can draw in any of the four colours on the two first displays and yet be sure that if pixels of the ship overlaps the mask on the third display, it will trigger a collision, because the mask is all ones (made with colour 3), so BAND'ing the ship with the mask returns a value different from zero, if there is any overlap. Another advantage of this approach is that since I repaint foreground and background directly for any changes and do not use a generic CLEAR channel command, I can maintain a complex background.

Just load the demo image and START the program.

As you can see all of the targets listed, are fulfilled at about 11 FPS. So for some types of games you could use BASIC. Some kind of game, where you don't need 50 FPS. like a submarine simulator at the same level as the first Silent Service game from Microprose.

Unfortunately there are some limitations about BASIC that limits the number of frames, I can generate.

First of all I have to do a lot of extra calculations because each of the three video pages may have addresses crossing a 16 Kb border, and since I use SPOKE extensively, I need to calculate the addresses as well as the page for each byte I poke. In fact, it takes about three seconds per frame in BASIC without ZZZIP. Fortunately ZZZIP can speed calculation and SPOKES up by at least a factor 50, since the operations are close to their MC code equivalents. I am sure a way can be found to make sure that memory used for each video page all stays within a 16 Kb page, and this would save a lot of calculations. Some other day perhaps....Suggestions are welcome.

BASIC only supports 2-dimensional arrays. This is a problem, because if I want to write routines, that can handle multiple objects flying around, I really need 3 dimensions, because I have to include the objects number as one of the parameters. It is possible to 'flatten' two or more dimensions into one dimension, but it quickly gets rather complicated, when you have to maintain meta-data about how data is stored to be able to work with the data. This also makes it hard to create standard routines, that can be used as a library for others wanting to create games using the routines as a backbone.

A third issue is the limitations causes by an integer compiler like ZZZIP, where addresses are limited in scope to 15 bit and where you only have integers available.

Still, I think the result proves, that it is possible to make some simple animations at a reasonable speed including such features as collision-check and depth-sensitivity.

Title: Re: Sprites and BASIC (with some help from ZZZIP)
Post by: gflorez on 2019.May.20. 20:15:02

Can you release the listing to learn something?

Also to test in on the real gear.
Title: Re: Sprites and BASIC (with some help from ZZZIP)
Post by: geco on 2019.May.21. 08:45:41
looks cool :)
Title: Re: Sprites and BASIC (with some help from ZZZIP)
Post by: JSP on 2019.May.21. 09:01:02

Here is a snapshot with the BASIC code.

I forgot to mention, that the program stops, if you press <ESC>.

A brief explanation of one of the features... The ability to reRUN the  program from within the program in one of two graphic resolutions, is based on using one of the system variables as a flag. System variable 28 manages the BIAS value. But since this value has no meaning with only 4 colours active, it can be set to any value, and will retain that value between multiple RUNs of the program. Then it is a matter  of simply scaling values horizontally.

Some of the procedures, like the event_handler, are not required for this specific program, but are introduced, so I can add features later on, managed by the event.flag variable. I have also used procedures to group code like in 'init_arrays', 'init_vpages' and 'init_vars'. This adds readability and structure to the program. All variables are explicitly declared at the start of the program. This is a good idea, when you use ZZZIP, as otherwise you may have problems with variables, that are initialized inside procedures. To improve speed, all things, that can be precalculated, are precalculated. The size of the visible displays are managed by the three constants vpage.x (start of display), vpage.wid (display width) and vpage.hgt (number of scan line blocks). These can be found in the INIT_VARS procedure. The main sprite is made from 2 x 3 bytes put together in 4 patterns.

When you run the program - have patience. It takes several seconds in BASIC to initialize everything, and the ship only moves once every three seconds :) Without ZZZIP it would all be rather useless.