had originaly planned to write a 2d tutorial as tutorial #2, but as I was
writing it, I realized there were still several important aspects of sprite editing
that weren't covered yet are essential to making a decent 2d engine. So consider
this the second, more advanced counterpart to tutorial #1.
O.k. So you now have your picture in memory, which you did using the GET
statement, and your predefined array to hold it in. That array however, is eniffecient
and memory wasting. Why should you worry about memory you ask? Because Qbasic's memory
limits are rather low, and if you try to use too many arrays you'll get an OUT OF
MEMORY
error. When I first started Marconian Dreams, I used the previous method,
declaring a 20x20 array to hold each tile. Being as I have over 40 tiles, this quickly
gets gobbles up memory. Hmm, we need a better way. After some investigating and a lot of
postings on alt.lang.basic, I discovered BLOAD
and BSAVE
. These
handy fuctions save both array space and frustration. You don't have to use DATA
statements to load and save the picture, and you don't have to worry about writing a jumble
of number coded colors to a data file. So here's how they work.
As in the tutorial before, you first need to draw a picture on the screen, either using
DATA
statements or otherwise. Then again as before, you have to GET
the picture with the GET
statement. Now here's where the difference come in.
Instead of writing the colors to a data file, and then reading them into an array, do this...
DEF SEG = VARSEG (TileName(0))
BSAVE FileName$, VARPRT (TileName(0)), 404
What was all that? Well basically what it does, is figures out where the variable is
stored in the computers memory, points to that spot, and saves what's there for however many
bytes specifies. Of course, you replace TileName with the name of the tile you assigned with
the GET
statement, and FileName$ you replace with the name of the file. The
404
part at the end of the BSAVE
statement is the amount o Bytes
to save. Basically, the rule of thumb for that number is to use a large number, and if you
start running into memory problems, make it smaller (be aware though that if the number is too
small, you won't save the whole picture). 404 is about twice the space needed to save a 20
x20 tile, so you can judge how much space your tile or picture needs from there. So lets
look at another example now. Say your TileName is RedCross, you want to save the picture to
a file named RedCross.bsv (bsv because it's a bsv file, although the extension can be anything
you want) and the tile is a 40x40 tile (which is about 4 times as big as a 20x20 tile). Here's
the code you would use...
DEF SEG = VARSEG (RedCross(0))
BSAVE "RedCross.bsv", VARPRT (RedCross(0)), 1212
Again, this first points to the beginning of the variable RedCross
with
the DEF SEG = VARSEG line, and then writes the first 1212 bytes of RedCross to the file
RedCross.bsv. Ok? Everything clear? Good.
Now that we've saved our cross to a file, how do we load it up again? We use BSAVE
's
counterpart, BLOAD
to load the file, using the same procedure before. First
we point to the beginning of RedCross using DEF SEG = VARSEG (RedCross(0))
then we load the file by using the BLOAD
statement...BLOAD
"RedCross.bsv", VARPRT (RedCross(0))
except this time we don't use the trailing number
because we've already defined how big the array was when we declared it. Confused? It'll
all be clear once you see the example.
'Program to load RedCross
'
'
DIM RedCross(1212) AS INTEGER 'Here we are setting up the array for RedCross
DEF SEG = VARSEG (RedCross(0)) 'Point to the beginning of RedCross
BLOAD "RedCross.bsv", VARPRT (RedCross(0)) 'Load RedCross into memory
See it's actually pretty easy. Now what if you want to put the tile somewhere now that
you've got it into memory? You go back and read the first Tutorial!! Or for those of you
who are lazy or have slow modems, you use the PUT
statement to put it somewhere.
This example loads RedCross into memory, then PUT
s it on the center of the
screen.
'Program to load RedCross and PUT it on the center of the screen
'
'
SCREEN 13 'We can't do graphics in SCREEN 0!
DIM RedCross(1212) AS INTEGER 'Make an array for RedCross
DEF SEG = VARSEG (RedCross(0)) 'Point to the beginning of the array
BLOAD "RedCross.bsv", VARPRT (RedCross(0)) ' Load RedCross into memory
'
'Now we put it on the screen...
PUT (170,100), RedCross, PSET 'Put RedCross at coords (170, 100) and overwrite
'anything else on the screen (that's what PSET does)
Voila!! Only one more thing you need to know about Sprite editing, the important
subject of masks. Try this. Draw a tile, (it doesn't matter what size it is) and then
draw a character the same size as the tile
(it can be any character, the more detailed the better, but if you
aren't creative a stick figure will do.) Now that you have a character, and a tile,
use the PUT
statement to PUT the tile on the screen, and then use another
PUT
statment to put the character on the screen. What happened? If you
used PSET at the end of the PUT
statment, then your character overwrote the
tile, which isn't good of you're trying to make a game (you can't erase a tile every time
you take a step!) and if you didn't use PSET, the colors of your character got all messed
up. The solution to this annoying and often asked about problem? Create a mask.
Masks use a neutral palette color so when you put your character on the tile, he doesn't
overwrite it, and the colors don't get messed up. It simply and perfectly puts your character
on top of the tile. So how do we make a mask? There are several methods but the one I
find easiest and most effecient involoves using the POINT
statement. The POINT
statment returns the color of a pixel at a specified coordinate. So if you have a blue
dot in the middle of the screen and you did this,
x = POINT (170,100)
PRINT x
x would = 32 (the qb color for blue). What you want to do is get rid of all that black around
your character, so it doesn't show up when you put him or her or it (sorry, gotta be
p.c.) on the tile. So when the POINT
returns 0 (black,) PSET
255. If POINT
returns anything else, PSET
0. This
will create a mask for your character. If you notice, using the method above any black
in your picture is erased, so if you intentionally want black, use color 16 instead of 0
(they're the same thing.) That way the black will stay in your picture. As usual it will
all make more sense after you see an example.
'Program to make a mask for an already drawn character
'
'
SCREEN 13
'
DIM Character(202) 'lets assume a 20x20 character
DIM CharacterMask(202) 'An array for the mask of Character
'
DEF SEG = VARSEG(Character(0)) 'points to the beginning of Character
BLOAD "charactr.bsv", VARPRT(Character(0)) ' loads Character into memory
'
'Now we put Character in the upper left hand corner, so we can alter it for a mask
'
PUT (0,0), Character, PSET 'make sure Character overwrites anything else
'
'Now here's where POINT and PSET come into play
'
FOR y = 0 TO 19 'The tile's length is 20
FOR x = 0 TO 19 'The tile's width is 20
IF POINT (x, y) = 0 THEN 'Checks to see if the pixel is black
PSET (x, y), 255 'makes all black turn to 255
ELSE PSET (0) 'If it isn't black, make it black
END IF
NEXT X
NEXT Y
'
'Now that the Character has been altered to a mask, we have to save the altered version,
'but first we have to get it into memory. We will save it as Charactr.msk (dos only allows
'a max of 8 letters, + extension)
'
GET (0,0)-(19,19), CharacterMask 'Get the Mask into memory
DEF SEG = VARSEG (CharacterMask(0)) 'point to the beginning of CharacterMask
BSAVE "charactr.msk, VARPRT (CharacterMask(0)), 202
'
END
There. Now we have the mask all ready to go. Now we need to know how to put the mask
on top of the character so it doesn't mess up the colors of the tile underneath. It's
easy just do this (assuming you've loaded all the necessary tiles into memory)
PUT (0,0), RedCross, PSET
PUT (0,0), CharacterMask, AND
PUT (0,0), Character, XOR
And there ya go. Now that you're a master of Sprite editing, try writing
a program that makes the shole process similar. A good sprite editor should have
- An easy to use interface
The color palette on screen so the user can see the different colors and decide which
one cest fits his or hers or its =) needs
- The user should be able to pick from those colors with relative ease (don't just
have the user type in what color # he wants!)
- There should be a magnification of the actual picture, as well as a prevue of what
the picture looks like
-
- The program should be able to save and load files
If you can do all that, you'll be able to make sprites effeciently and easily. Or you
could just download my editor, which has all the above features and more. I'll have it up
sometime, I swear!!
Apester can be contacted at Apester000@aol.com.