PS2 Linux Programming


2D Sprite Movement and Animation




This tutorial will show how to draw and manipulate 2D sprites. A textured 2D sprites will be drawn using the sprite primitive. Simple sprite movement and animation will be performed.



Sprite Structure


The structure PS2Sprite_t, shown below, is defined in PS2Types.h to hold relevant information relating to the drawing, movement and animation of the sprite.


typedef struct


        int x, y;                             // Position on screen (top left)

        int z;                                 // z depth (big = near)

        int w, h;                            // Width and height

        int u, v;                             // Offset from texture top left

        unsigned char r, g, b, a;       // Colour and alpha

        int dx;                               // Direction for x

        int dy;                               // Direction for y

        int FCountMax;                   // Counter max value

        int FCount;                         // Frame Counter

        int NFrames;                      // Number of animation frames

} PS2Sprite_t;


The parameters of the structure are as follows. (x,y) is the position of the top left hand corner of the sprite on screen and z is the z depth used for z ordering. w and h are the width and height of the sprite. u and v are the offset into the texture, from the top left hand corner of the texture area to be used for the sprite. r, g, b and a are the colour and alpha value for the sprite. The other parameters are added to the structure to aid with the game logic. dx and dy are used to store the direction that the sprite is moving in the x and y directions respectively. NFrames is the number of animation frames that are used to define an animation sequence and FCount and FCountMax are used for timing of the animation sequence.


The texture that is used in this example is shown in the diagram below. The first row of the texture consists of some tiles that can be used to draw a background and the next three rows consist of animation sequences, two of characters with walking/running animations and one explosion sequence. All of the sections within the texture are based on a square grid of 32 x 32 pixels. Notice that only half of the 256 x 256 texture is used, the right hand half of the texture is filled with black and can be filled with image data at a later time.





Sprite Texture



The main Program


Much of the initialisation that is performed in main.cpp has been described in previous tutorials and this will not be repeated here. Before the render loop is entered, the sprite structures are initialised with appropriate information. Within the render loop there is a function to move the sprite across the screen, MoveSprite(), and a function to animate the Sprite, AnimateSprite(). The GS packets are constructed using the BuildSprite2D() function. BuildSprite2D takes is a pointer to the structure describing the sprite to be drawn as a parameter.



The BuildSprite2D() function


The prototype for this function is:



int BuildSprite2D(PS2Sprite_t * pSprite)



The PRIM field of the GIFtag is set up to draw a sprite primitive and texture mapping is enabled. The register data that following the GIFtag is the primitive colour and the UV and XYZ value for the two vertices. Notice that the UV and XYZ data for the registers are constructed from the current information that is contained within the sprite structure passed to this function this means that every frame the new position, animation data, etc. for the sprite will be written into the GS Packet.


On running the program, two sprites are drawn on screen, one is static i.e. a background tile, the other is an animated character which walks back and forward across the screen.





In this tutorial 2D sprites have been drawn using the sprite primitive. This primitive is sufficient for generating background images and some very simple movement/animation but it has many limitations. Two major limitations of the sprite primitive are (1) that the z depth over the complete surface of the sprite must be the same and (2) it is not possible to rotate the sprite. Considerably more functionality and control is obtained if a triangle strip primitive is used to draw a sprite and this will be introduced in the next tutorial.




Dr Henry S Fortuna

University of Abertay Dundee