Figure 16.2: A list of sprite frames in one image, organized in one row and four columns
Surfaces are resources for static one-frame images. Sprites, however, are surfaces designed like a flip-book, or an array of surfaces. Sprites can hold numerous frames-a whole collection of static images-and will cycle through them showing one frame at a time, effectively playing an animation. Sprites most commonly achieve animation using a tile set. This means all the frames of an animation are loaded side by side onto one image file in columns and rows. Each frame has the same width and height, and the frames are arranged in tiles across the length and height of the image. The sprite class only needs to know the size of one image and, knowing this, it can iteratively cycle through all the tiles as frames, starting at the top-left corner of the image file (0,0). Sprites can be created much like surface resources, and for this reason, the next subject to examine is how they are defined in XML.
Sprite resources are defined in XML much like surfaces, except sprites have some additional options to control their animation properties.
<sprite name="my_sprite" > <image file="my tile set.bmp"> <grid pos="0,0" size="100,100"array="5,5"/> <image/> <animation speed="500" loop="yes" pingpong="yes" /> </sprite>
Each sprite has a name and ID, which are defined by the programmer in order to identify one sprite from another in terms of being a resource. Additionally, each sprite has an image file that contains its frames in the form of a grid, where each frame is tiled inside the image, and each frame is a specific number of pixels wide and high, arranged in columns and rows. The animation tag keeps track of how long one frame lasts; in this example, 500 milliseconds (half a second). Looping determines whether the animation is repeated continually, beginning at the first frame after each complete cycle of frames is done. And finally, the pingpong property determines how the repeat is to occur. If set to no, then the animation will repeat normally, back at the first frame. If pingpong is set to true, then the frames will cycle forward, from first to last, and then from last to first, and then first to last, in a backward and forward cycle.
Sprites that have been defined in XML can be created much like surfaces, though they must be loaded in conjunction with the resource manager, which in turn loads and processes all the properties in XML, including the sprite definitions. Earlier, we showed how a resource manager object can be created, and that a valid path to an XML file is passed to its constructor. In this section, we'll demonstrate how sprite objects are created from a resource manager that has been loaded with the relevant data from an XML file. Consider the following code:
CL_ResourceManager *m_Manager = new CL_ResourceManager("resources.xml"); CL_Sprite *Sprite = new CL_Sprite("my_sprite", m_Manager);
In the above two lines of code it is easy to see how a sprite is created. First, a resource manager is created, and then a sprite object is declared (CL_Sprite). Its constructor accepts two arguments: the name of the sprite object as defined in the XML and a pointer to a valid resource manager. The sprite object can then use the resource manager to look up the appropriate sprite with a matching name in the XML.
Given a pointer to a valid sprite object, how can the object be drawn to the screen? Again, in ClanLib this is simple and is just like drawing any ordinary surface using a draw method. The one difference, however, is that programmers must also call the update method of the sprite to ensure all the time, frame, and animation properties are updated. The code that follows demonstrates how a sprite can be drawn to the screen.