#############################
#2d-sprite clipping tutorial#
#############################

Welcome to the programming-school by ChemiX. The 1st part.
In the programming-school I will talk about the simple graphic techniques
that's used to make small, simple games. You won't see any advanced stuff
and if you're a experienced game-programmer you can quit this immediatelly.
I expect some basic information on programming MCGA, 320*200*256.
If you know JACK about it visit:
ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/
and download all docs by Denthor of Asphyxia. They're really good.
In the school i'll present code in both C and Pascal, but they wont be
compilable, cause you don't have my units. But I'm sure you can write a good
one out of Denthors tutorials. Let's go.

Today we will talk about a very simple things, but yet so important.
Sprites and the clipping of them. Nowadays, when the world is filled with
3d texturemapped worlds with colored lightning and mip-mapping, it's easy
to forget to good ol'e games, like tetris, pacman and raptor. These games
are splendid examples of what you can do with sprites. You don't need a
100% assembler optimized 3d engine to write entertaining games. 
Sprites
The most basic thing in game-programming after Putting your first pixel,
virtual screen, fades and that stuff is SPRITES. If you are familiar with
arrays or matrixes, sprites will be very easy. Sprites are two dimensional
arrays of bytes.
Type Sprite=Array[1..32,1..32]of byte;
typedef char Sprite[32][32];
For those of you bozos who doesn't know what arrays are, read a book.
Now all you have to do is to fill that array with the right bytes.
One way is to make constanst, like this
Const Spritedata:Array[1..6,1..6]of byte=(
      (1,1,1,1,1,1),
      (1,1,1,1,1,1),
      (0,0,1,1,0,0),
      (0,0,1,1,0,0),
      (0,0,1,1,0,0),
      (0,0,1,1,0,0));
A you might figure, this method is very bad. When you have big sprites like
32x32 you can't use this method, and you shouldn't use it's for small sprites
either, it sucks. The best way is to draw the sprites in some kewl paint
program. But then you must have your own pcx- or bmp-loader.
Now, when you have filled the array with bytes you might want to draw it.
This is also very simple. Let's say we want to draw the very unkewl sprite
I made above.

Procedure DrawSprite(x,y:integer);
var i,j:integer;
begin
for i := 1 to 6 do
 for j := 1 to 6 do
  putpixel(i+x,j+y,Spritedata[i,j]);
end;

void DrawSprite(int x,int y)
{
 int i,j;
 for(i=1;i=6;i++)
  for(j=1;j=6;j++)
   putpixel(i+x,j+y,Spritedata[i][j]);
}

How difficult was that. Now you know how to draw sprites, but many times you
want to draw the sprites over a non-black background and then you'll notice
it will paint the sprite like a rectangle. You will see the black pixels too.
This is easily fixed, by just adding one more line into the sprite-drawer.

if Spritedata[i,j]<>0 then

if (Spritedata[i][j]!=0)

Now that problem is fixed, BTW it's called Masking. That's it.
Sprite clipping
As we learned above, we want to have array's  of byte for our sprites.
We use the exact same variables and so on. For our clipping we need four
variables, that we'll clip against. LeftClip,RightClip,TopClip and BottomClip.
I initially give these the values 0,319,0,199; the screen borders.
Now we can start clipping.

We need four more variables, two for the new width and height of the clipped
sprite(tw,th), and two for the new position to start drawing the sprite
from(gx,gy). When you clip, it really doesn't matter where you start clipping,
but I like to go Left-Right and the Top-Bottom. I've heard other people saying
you should clip Top-Bottom then Left-Right, but it really doesn't matter.
Ok! Clip left:

if (x < LeftClip) then     
        inc(gx,LeftClip-x);

/* if(x < LeftClip) gx+=(LeftClip-x); */

You just increment gx (the position from where to start drawing) with the
difference between the left clipping border and the x position. 

if ((x + SpriteWidth)>RightClip) then 
   dec(tw,(X + SpriteWidth) - RightClip);

/*if ((x+ SpriteWidth)>RightClip) tw -=(X+SpriteWidth) - RightClip;

When you clip the right side you just decrement the width, seems very logic,
doesn't it. It's rellay very simple.

if (y <  TopClip) then             
        inc(gy,TopClip-y);

if ((y + SpriteHeight)>BottomClip) then 
    dec(th,(Y + SpriteHeight) - BottomClip);

For the top and bottom you use the same calculations as L-R, but of course
you change the x values to y and so on.

That's it. Very, very ,very simple, but important. Next time we'll use this
clipping routine for TILE-BASED MAPS. Really heavy, cool stuff. C&C, look out.
So for next time: Happy coding!

Quote: Hey, something's wrong with this computer. It's just a black screen
       with a C on it.

MAIL: Tobias.Johansson@pemail.com
URL: members.tripod.com/~GeneralZoftware/ 
NAME: Tobias Johansson
ALIAS: ChemiX
AGE: 16
PROFFESION: Coder
LANGUAGE: Pascal,C and Swedish

