Click here if you are stuck in someone else's frames.

If this page looks like garbage then you need one of these browsers...

Microsoft Internet Explorer

Netscape Navigator

Please sign my programmer's page guestbook.

Please sign my guestbook

View my guestbook entries

Sprites, the main focus of games.

Most of the video games you will write will consist of bitmaps moving around over some type of background. This background can consist of just a single color, as in a black background, it can be a picture or anything else for that matter. Our main topic for now will be that of sprites.

So what exactly are sprites?

In its simplest form, sprites consist of a rectangular shaped bitmapped image. In fact, most sprites do not have much more information than that. The bitmap can be an image of a car, a boat, a ball, a person, or anything else that you can imagine. These images can be moved around the screen and animated. In this section, we will look into ways of moving and animating sprites and how not to destroy complex background images that they're moving on.

This picture illustrates the basic characteristics of a sprite and its relationship with the background, or screen, itself. The rectangular border around the image is known as its bounding box. You cannot actually see this bounding box on an actual sprite, however you can make where the borders are by using the coordinates of the upper left corner of the bitmap (X,Y) and adding the values of both the width and the height of the image. This is basically all the information you need to store a sprite but generally most sprites also contain other types of information such as its status, other images for animation, etc..

Of course now we're leading up to the actual code that we need to write to make our sprites. First off, we need to figure out what kind of data that we need to store for each sprite. We can put all of the data pertaining to a sprite into a data structure and acheive some sort of encapsulation. For C programmer's such as ourselves, we will use the C's struct keyword to accomplish this. So let's look at the data that we will put into a sprite.

struct Sprite {
    int startXoff, startYoff; /* Offset copying position */
    int lenXcopy, lenYcopy;   /* Actual dimensions to copy */
    char far *displayMem;     /* Buffer sprite is modifying */

    int X, Y;              /* Sprite's current location */
    int lastX, lastY;      /* Sprite's last location */
    int width, height;     /* Sprite's dimensions */

    int minX, minY;        /* Minimum limits */
    int maxX, maxY;        /* Maximum limits */

    int currFrame;         /* current frame in animation */
    int noOfFrames;        /* total number of frames in animation */
    char far **frames;     /* array of sprite images for animation */
    char far *background;  /* background stored for dirty rectangle */
    int imgDynamic;        /* flags if images are static or dynamic */

    int visible;           /* flags if Sprite is or isn't visible */
    int backTransparent;   /* opaque or transparent background */

    int status;            /* Sprite status, varies by game rules */
    int animThreshold;     /* animation threshold, varies */
    int moveThreshold;     /* move threshold, varies */
    int clock;             /* sprite's clock */

    void far *otherData;   /* Extra data */
};
    

Wow! I beleive that is quite a bit of information for a sprite. Is all of this information really necessary? Well, yes and no, the best answer to that depends on what exactly we need the sprite to do in our particular video game. I feel that for most games this struct will be more than sufficient, besides, in the world of programming games it is better sometimes to have more than is needed that to come up short and make programming the game even tougher. Now let's examine what each field does and then write some functions that will complete our sprite engine.

First off, let's examine each and every element one by one to see why they exist.

  • The variables int startXoff, startYoff are used for clipping the sprite's image on the screen.

  • The variables int lenXcopy, lenYcopy are also used for clipping. They determine how much of the sprite's image is to be copied onto the screen.

  • The variable char far *displayMem contains the address to the buffer that the sprite's image will be written to and background is to be read and written to. Normally, it is assigned the value of the public variable videoMem, meaning that the sprite's images will be written directly to video memory. Later we will learn how to use a cache area of memory to help eliminate flicker.

  • The variables, int X, Y contain the X and Y screen coordinates to the upper left corner of the sprite's image.

  • The variables, int lastX, lastY contain the last coordinate of the sprite before it was moved. This can come in handy for us at times.

  • The variables, int width, height hold the width and height of the sprite's image in pixels. It is used for computing the memory requirements of the images.

  • The variables, int minX, minY and the variables int maxX, maxY set the limits on the screen that the sprite's image can be shown. This is useful for clipping a sprite's image beyond its limits of visibility.

  • The variable, int currFrame contains an index to the current image frame that the sprite will show. Changing this variable makes sprite animation possible.

  • The variable, int noOfFrames contains the number of images that the sprite is currently using.

  • The variable, char far **frames is a near pointer that points to an array of far pointers that each point to a reserved heap of memory that contains an image used by the sprite.

  • The variable, char far *background is a far pointer that points to a reserved heap of memory that holds the original background under a sprite so that the background can be restored when the sprite is moved.

  • The variable, int imgDynamic is used to determine if the far pointers in the frames array are pointing to memory allocated from the heap at run time (dynamic) or at compile time (static).

  • The variable, int visible flags whether or not the sprite's image is currently being shown on the screen.

  • The variable, int backTransparent flags whether or the sprite's image will use transparency in bit blitting.

  • The variable, int status can be used to store some kind of status of a particular sprite. You can use it in anyway you want.

  • The variable, int animThreshold can be used to control animation of the sprite. However how you actually use this variable is up to you.

  • The variable, int moveThreshold is similar to animThreshold except you can use it to control the moving of the sprite.

  • The final variable, int clock can be used in conjunction with moveThreshold and animThreshold to control timing of it's movements and animation.


Writing the code for our Sprite Engine

Of course, now we've kind of gotten to a point where there is a kind of fork in our path to writing our sprite engine. Many of you who are reading this have a C++ compiler. I myself use a C++ compiler to do all of these programming examples (Turbo C++ 3.0). It allows us to compile C and C++ programs, this presents us with two opportunities. One is that we can continue to use the struct that we have just written and write a library of C functions that kind of encapsulate the functionality of a sprite. On the other hand, we could acheive total encapsulation by binding the data and functions altogether and creating a single class (or object) that has all of the functionality.

The choice here is yours, some people do not like to use C++ at all and stick with just C code. If you are not very familiar with the C language itself, then it will not be to your best interest to jump into the C++ arena and try to encapsulate everything into a single object. For now, we will just continue using C and not use any C++ while working on a sprite. After we get it working, we will see how by just making a few modifications we will have learned C++, if you don't know it already, and managed to create a true object at the same time. Of course, for you diehard C fans, you can just keep the functions as they are and use you sprite library and just skip over the section where we go into creating a sprite object. So without any further hesitation, let's build our functions and get our sprite to work.


The choice is yours on which path to take.

Send your questions, comments, or ideas here.

This page hosted by GeoCities Get your own Free Home Page
Back

1