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

Erasing sprites

Okay, now that we've learned how to draw sprite's, let's learn how to erase them also. To erase a sprite's image on the screen is simple, you just simply restore the background that the sprite was drawn on back on top of the sprite's image. In the SpriteShow function, we copied the original background into a buffer first before copying the sprite's image onto the screen, so in order to erase it, we just take what was in the background buffer and copy it back onto the screen in the same place. Easy, yes? Then let's get right to it.

void SpriteHide(struct Sprite *thisSpr)
{
    int i;
    char far *src, far *dest;

    /* If sprite is not visible, quit */
    if (!thisSpr->visible) return;

    /* If there is no background buffer, skip */
    if (thisSpr->background != NULL && thisSpr->width && thisSpr->height) {
        /* Start the copying */
        src  = thisSpr->background;
        dest = &thisSpr->displayMem[(thisSpr->Y<<8)+(thisSpr->Y<<6)+thisSpr->X];
        for (i=0; i<thisSpr->height; i++) {
            _fmemcpy(dest, src, thisSpr->width);
            src  += thisSpr->width;
            dest += ScreenWidth;
        }
    }
    /* Flag sprite as not visible */
    thisSpr->visible = 0;
}
    

...and our brief rundown.

The function first tests to see if the sprite is already flagged as being invisible. If it is, the function aborts. Otherwise it checks for a background buffer and for non-zero width and height and copies the contents of the background buffer back onto the screen. Then it finally flags the sprite as being invisible before it exits.


Assigning images to sprites

Well now we can initialize, destroy, show and hide sprites. Are we missing anything? Well consider this, when we go to show an image of a sprite on the screen where does that image come from? If you said that it came from one of images of the frames array, you're right. But how did the image get there? Ummmmmm...we're waiting.... Well, currently there isn't a way yet,so we need to define a way.

In order to do that, we need to understand how images are stored in sprites. Well, since these sprites are to be designed for use in screen mode 13h we know that the number of pixels stored in a sprite's image has a one to one ratio with the amount of memory used by the sprite's image. In other words, each pixel uses one byte of memory allocated to the sprite's image. Well, DUH, this part should not be of any news to you since we had already learned before that a pixel uses a byte of the video memory back when we were writing functions to set pixels and draw lines.

So since the images themselves are width x height pixels in size all we need to do is allocate width x height bytes for each frame. That's pretty simple and in fact that is exactly what the InitSprite() function does as illustrated from this code snippet below:

  int InitSprite(struct Sprite *thisSpr, int w, int h,
                 int numFrames, int dynamic, int drtyRect)
  {
      .
      .
      .
      for (i=0; i<numFrames; i++)
        if (dynamic && w > 0 && h > 0) {
          thisSpr->frames[i]=(char far *)farmalloc(w*h*sizeof(char));
          if (thisSpr->frames[i] == NULL) retVal = 0;
        } else
          thisSpr->frames[i] = NULL;
      .
      .
      .
  }
    

So to assign an image to a bitmap, we can just copy the memory that the bitmap uses to the memory for the sprite. Sounds pretty simple so let's write a function that does this.

  void SpriteSetImage(struct Sprite *thisSpr, void far *bitmap, int fraNum)
  {
      if (fraNum < 0) fraNum = thisSpr->currFrame;
      else fraNum %= thisSpr->noOfFrames;

      if (thisSpr->imgDynamic) {
          if (thisSpr->frames[fraNum] != NULL)
              _fmemcpy(thisSpr->frames[fraNum], bitmap,
                       thisSpr->width * thisSpr->height);
      } else
          thisSpr->frames[fraNum] = (char far *)bitmap;

      if (thisSpr->visible && thisSpr->currFrame == fraNum) {
          SpriteHide(thisSpr);
          SpriteShow(thisSpr);
      }
  }
    

...and our brief rundown.

This function takes a pointer to the sprite, a pointer to the bitmap image and the frame number that you wish to assign the bitmap to. The first if statement checks the fraNum parameter to insure that it is within the number of frames currently allocated to the sprite. Then it determines (via the second if statement) whether the images are dynamic. If they are, then it checks to see if the frame you chose for the bitmap has the memory allocated to it (via if (thisSpr->frames[fraNum] != NULL)). If so, then the following _fmemcpy statement copies the memory from the bitmap to the frame's image area.

The statement following the else executes if the images were not dynamic. In this case, the image is assigned directly to the value of the bitmap pointer.

The final if statement just checks to see if the sprite is visible and if it is currently showing the image you're assigning. If so, the function erases and redraws the sprite to reflect the new image assigned.


Send your questions, comments, or ideas to: wilkeg@gamewood.net

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