The stuff floating around on your computer screen has to come from somewhere. The best source is from a drawing program, such as MSPaint (for relatively cheap pictures) or Adobe Photoshop (for top-quality pictures). For Nibbler, I used the obscure IFF format from an Amiga-based drawing program, Deluxe Paint II. It can't so much as touch SVGA modes, but it is menu-driven and very flexible in 320x200x256 mode.
Suppose, say, I draw the floor tiles of this game for level one. It's
a nice image. But...how to get from point A, the drawn graphic, to
point B, a whole bunch of individual sprites?
I developed an application, GET.CPP, to handle the task.
This program works with graphics files to churn out and organize
sprites from a single image. There are two important features: naming
the sprites and grabbing them.
Sprites aren't compiled immediately. Rather, they
need to be "pointed out" by the user. After loading the file FLOOR.LBM
as shown above, the sprites are, sure enough, right there. For
convenience, I have drawn them in nice neat blue "frames". Naming a
sprite is simple: add a new one (or edit an old one), click on its
name field, and type in a name. The only restrictions are that they
begin with a letter and follow the general format of programming
variables. You can change the name at any time. The maximum is
sixteen characters per sprite.
Now the fun part. After naming, click on the boundary tab, and you can draw a box around the desired location with the mouse. The transparent box does include the pixels under the box, something to keep in mind. Getting a grabbed sprite exactly right, pixel to pixel, is something that requires some precision and practice. It is to the artist's advantage to draw those "frames" around the sprites to make the job easier. It is to the artist's disadvantage to have arthritis, palsy, or other jitter-causing afflictions.
One more thing--that transparency switch will select between two sprite formats, transparent and opaque. Opaque sprites are just lumped onto the screen as a rectangular block. Transparent sprites are drawn in a similar way, but the background color will be thrown away, leaving that area undrawn when the sprite is placed.
After a list of names is created, we can simplify things greatly. The list is just names and rectangular selections, remember--it hasn't done anything to interface with the graphics file. Now we can compile a header file from the names, ignoring for now the sprite selection boundaries. Select a name, for example, sample.h, and hit the compile switch. What happens:
becomes |
... #define TRIGGEROFF 300 #define TRIGGERON 301 #define EXITSIGN 302 #define THRUSIGN 303 #define CANNON 304 #define SPRING 306 |
This is perfect for accounting for the sprites in any utility that uses them. The header file is acceptable in C and C++. The defines match the names exactly, with the numbers starting at 0 and counting upward. There is one exception--some numbers are missing, such as the cannon. This is because some closely related sprites, such those that are tied to directional displays, are associated enough with each other that only one name is appropriate. It only makes sense to name the first sprite, CANNON, rather than saying CANNONUP, CANNONRIGHT, etc. To "leave out" a define, just don't name it anything. The sprite selection will still appear in the sprite compilation.
Now for the big job. To generate actual sprites, name
an ART file and compile it. The file will "collect" all selections,
in the order you specified them in the list, and in the correct
sprite format. This may take a bit of time if hundreds of sprites
are compiled, especially if they appear in different graphics files.
The end result: an ART file, or a collection of sprites to be loaded
at run-time. See below for a summary of the
file format.
Of all game-building tasks, this certainly seems like the easiest. Now here's some more info on how to use the program. In all cases, regardless of which menus are open, <Left click> activates a menu and <Right click> cancels or goes back a menu (the Escape key is equivalent to < Right click>). All menus are mobile--moving them by dragging the title bar is a standard window programming pratice. The menus are organized this way so that they don't get in the way of other work, such as viewing and selecting sprites in various corners of the screen.
Main Menu: File, Pict, Edit, Compile.
Investigate as needed.
File Menu: Load and save GTR files. The GTR files are just
selections--they aren't associated with graphics files themselves;
these must be loaded separately from the Pict menu. You can also
use Append to tack one file of selections onto the end of another
loaded one--handy when creating large compilations.
Pict Menu: Load graphics files. (Sorry if you want to use
anything but LBM files, or IFF if you can rename the extension. The
only reason I have for supporting only LBM files is that I'm cheap.)
You can also save and load palettes of previously loaded graphics
files. It's a good idea to save a default palette--it's just 256
entries that will likely be the same from file to file. The palette
is not saved in the ART file--it must be loaded separately when
loading an ART file.
Finally, the background color can be polled from any pixel on the
currently loaded image. I nearly always keep it at 255 (white), its
default value. This value, don't forget, defines what parts of
transparent sprites are transparent.
Block Menu: The block editor is used the bulk of the time
when in GET.EXE. Every block in the list has a 0-16 character name,
a transparency flag, and a definable boundary. New inserts a
new entry, Delete kicks it out, Move moves it, and
Edit edits it. The list, which is always present regardless
of the current menu, can be selected with the mouse to influence
which entry to apply the function.
The fileblock switch is kind of important--read carefully. I said
there's no relationship between graphics files and sprite selections.
So how the heck does the compiler know where to pull the sprites from?
The answer: fileblocks. The first entry of every list must be a
fileblock. Quite simply, it provides direction. For our floor
tile example, we would name it "FLOOR". The fileblock tab appends an
LBM extension. Any resemblance to a sprite definition is
destroyed. Multiple fileblocks can be useful because the compilation
process may pull from four or five different graphics files before it's
done. (This might be fun to watch since it screws up the palette colors
occasionally.) Note that fileblocks are NOT included as a number
in the header file (if created), even though empty names are included.
This is MY format--any other file format with an
ART extension is coincidental.
short numpicts;
struct arthead[numpicts];
where the structure is:
{
long fpos;
char trans;
unsigned short length;
}
After the last entry in arthead, the individual sprite data begins.
The fpos member of each sprite defines an offset relative to the
byte immediately following the arthead structures. Thus the first
entry's fpos will always be zero. One may choose to skip over sprites
before loading others. To see how sprites are stored, see the next page.