_ATTACHED SPRITES_ by Diana Gruber Listing One /******************** sprite declarations *************************/ int nsprites; typedef struct _sprite { char *bitmap; int width; int height; int xoffset; int yoffset; } SPRITE; SPRITE *sprite[40]; /* forward declarations */ struct OBJstruct; typedef struct OBJstruct OBJ, near *OBJp; /* pointer to object action function */ typedef void near ACTION (OBJp objp); typedef ACTION *ACTIONp; /* data structure for objects */ typedef struct OBJstruct { OBJp next; OBJp prev; int x; int y; int xspeed; int max_xspeed; int yspeed; int direction; int frame; int tile_xmin; int tile_xmax; int tile_ymin; int tile_ymax; SPRITE *image; ACTIONp action; OBJp attached_sprite; }; SPRITE *explosion[11]; /**********************************************************************/ void near start_explosion(OBJp objp) { OBJp node; /* allocate space for the object */ node = (OBJp)malloc(sizeof(OBJ)); if (node == (OBJp)NULL) return; /* assign values to the structure members */ /* after the plane has been killed, the explosion moves at a slower speed because smoke drifts slower than metal */ node->xspeed = objp->xspeed/2; node->yspeed = objp->yspeed/2; /* tile extents */ node->tile_xmin = 2; node->tile_xmax = 21; node->tile_ymin = 0; node->tile_ymax = 14; /* the sprite will be the first frame explosion bitmap */ node->image = explosion[0]; node->x = objp->x+16; node->y = objp->y-4; node->frame = -1; /* insert at the top of the linked list */ node->prev = top_node; node->prev->next = node; top_node = node; node->next = (OBJp)NULL; /* set up the links between the explosion and the enemy plane */ node->attached_sprite = objp; objp->attached_sprite = node; /* assign the action function */ node->action = do_explosion; } /**********************************************************************/ void near do_explosion(OBJp objp) { /* If the explosion has reached the frame 3 state, at which point the bitmap is bigger than the airplane, it is time to kill the airplane. */ if (objp->frame > 3) { /* if the attached sprite is NULL that means the airplane was already killed */ if (objp->attached_sprite != (OBJp)NULL) objp->attached_sprite->action = &kill_enemy; objp->x += objp->xspeed; objp->y += objp->yspeed; } else { /* The position of the explosion depends on the position of the airplane */ if (objp->attached_sprite != (OBJp)NULL) { objp->x = objp->attached_sprite->x+16; objp->y = objp->attached_sprite->y-4; } /* it is possible for the explosion to be at less than frame 3 but there is no attached sprite. That happens when the enemy plane has drifted off the edge of the screen. */ else { objp->x += objp->xspeed; objp->y += objp->yspeed; } } /* Increment the explosion frame */ objp->frame++; /* define which sprite will be displayed this frame */ objp->image = explosion[objp->frame]; /* We have 10 frames for the explosion */ if (objp->frame > 10) { objp->image = explosion[10]; objp->action = kill_explosion; } } Example 1: typedef struct OBJstruct { OBJp next; OBJp prev; int x; int y; int xspeed; int max_xspeed; int yspeed; int direction; int frame; int tile_xmin; int tile_xmax; int tile_ymin; int tile_ymax; SPRITE *image; ACTIONp action; OBJp attached_sprite; }; Example 2: typedef struct _sprite { char *bitmap; int width; int height; int xoffset; int yoffset; } SPRITE; Example 3: /* set up the links between the explosion and the enemy plane */ node->attached_sprite = objp; objp->attached_sprite = node; Example 4: if (objp->attached_sprite != (OBJp)NULL) objp->attached_sprite->action = &kill_enemy; Example 5: /* The position of the explosion depends on the position of the airplane */ if (objp->attached_sprite != (OBJp)NULL) { objp->x = objp->attached_sprite->x+16; objp->y = objp->attached_sprite->y-4; }