Using Sprites |
Top Previous Next |
Overview Sprites are figures or elements on the screen that have the capability of moving independently of one another. At the lowest level a sprite is simply a bitmap image that can be displayed on the screen. The 2D command set supports many drawing modes for displaying the sprite including transparent, alpha blending, animated, rotated and zoomed. Sprites can be used for displaying static images as well and will be the most used element in all of your 2D programs. Loading sprites Before a sprite can be used it must first be loaded either from a disk file or from your programs resources. The LOADSPRITE function handles loading the sprite and supports DIB and DDB bitmaps, RLE bitmaps, JPEG, as well as any image format supported by Internet Explorer. A screen must be opened before any sprites can be loaded and you must free all sprites with the FREESPRITE function before you close the screen. The loaded sprite can contain one or more image frames with each frame being the same width and height. Using frames allows for animation and also having multiple sprites in a single file. Using multiple sprites in one file will save on video card memory as each separate sprite file get allocated a DirectX buffer. The buffer can be located in either video ram or system ram. See the drawing mode table for information on when system ram should be used. The LOADSPRITE command returns a pointer, or handle, to the sprite. This pointer can be passed to any function that requires a sprite as an argument. It is not necessary to pre-define the variable used for the sprite. Example loading of a sprite: bug1 = LOADSPRITE(GETSTARTPATH + "mouth.bmp", 0, 0, 3) The above statement loads a sprite stored in the programs directory from the file mouth.bmp. The sprite containes 3 image frames. The width and height are specified as 0 to allow LOADSPRITE to calculate the width and height. If the file contains just a single image you can omit width, height and frames completely as in: bug2 = LOADSPRITE(GETSTARTPATH + "bug2.bmp") If you know the width and height but the number of frames may vary you can specify just the width and height and the number of frames will be calculated automatically. If your image consists of many rows and columns of frame images you must specify width, height and the number of frames. If the sprite cannot be loaded the sprite pointer will be equal to NULL (0). Moving the sprite Sprites can keep track of their position on the screen internally. To move a sprite use the MOVESPRITE command. A sprite can be moved outside of the screen space in which case it will simply be ignored when drawing. The coordinates given to the MOVESPRITE command specify the upper left hand corner of the sprite image. MOVESPRITE bug1, 0, 100 Rendering the sprite The sprite is drawn, or rendered, onto either buffer using either the DRAWSPRITE or DRAWSPRITEXY commands. DRAWSPRITE uses the internal position set by the MoveSprite command and DRAWSPRITEXY allows specifying the position directly. A sprite can be drawn on either the front or back buffers by using the optional buffer argument. Examples statements: DRAWSPRITE bug1 Note that when drawing onto the back buffer, which is default, you must use FLIP to actually see the sprite. This is true of anything drawn onto the back buffer. Drawing on the front buffer will show the sprite immediately but it has limited use since the illusion of animation requires flipping. DRAWSPRITEXY does not use or update the internally stored position and is most useful when a single sprite image needs to be displayed in multiple locations on the screen. Sprite drawing modes Sprites can be rendered to the buffer in a variety of ways. The default drawing mode is a straight copy from image to buffer. To change the drawing mode us the SPRITEDRAWMODE command. The following table lists the supported modes:
The most common drawing mode for a sprite will be @TRANS. Alpha blending and rotating sprites are done through software and will generally be slower than the rest of the modes which use the video cards hardware directly. If you're only scaling a sprite and not rotating, then it is better to use @SCALED or @TRANSCALED instead of the @(TRANS)ROTOZOOM modes. For the @TRANSSHADOW mode the shadow will draw faster if the sprite is located in system memory. However the sprite itself will draw faster if located in video memory. For the best tradeoff load the sprite twice, once in system and once in video. Sprite animation Animation of sprites is achieved by changing the image frame of a loaded sprite. A sprite can have any number of frames that make up an animation sequence but it is advised to keep the amount to a minimum as every frame will use some video card memory. Changing the currently displayed frame is done with the SPRITEFRAME command. Changing of the frames should be timed to the current FPS or otherwise controlled using a window timer. The following example shows a sprite with 3 image frames changing frames every 1/4 second. By using the FPS returned by the FLIP command you can control the speed of graphic elements easily. speed = 0
Creating and drawing on sprites Blank sprites are created with the CREATESPRITE command. The special SpriteBuffer buffer is used to draw onto a sprites surface by specifying which sprite to use with the SpriteToBuffer command. The CreateSprite function returns a pointer to a freshly created sprite of the width and height specified in either system or video memory. The frames parameter specifies how many image frames you plan on creating. Calculate this by using total width / frame width. It must work out to be evenly divisible. For example suppose we want frames that are 64 x 64 and a total of 5 frames. The total width would be 5 * 64 or 320 pixels newSprite = CREATESPRITE(320, 64, 5) Once the sprite is created use SpriteToBuffer in preparation of drawing on the sprite. SpriteToBuffer(newSprite) Then use any of the 2D or EBASIC drawing commands to draw on the sprite specifying SpriteBuffer as the buffer/window parameter. 'Color the whole sprite red When using WritePixelFast you must lock the SpriteBuffer in the same manner you would with the BackBuffer or FrontBuffer. You can also directly access a sprites image memory for advanced operations. See the topic Direct buffer/sprite writing for more details.
Copying sprites By using the SpriteToBuffer command to attach a newly created sprite to the SpriteBuffer you can copy another sprites imagery by using the DrawSprite or DrawSpriteXY commands. The sprite will be rendered to the new sprites buffer using the current drawing mode, scaling, rotation, alpha blending and frame setting of the sprite to copy. Copying a sprite in this manner has more advantages over a straight bit copy. For example rotation and scaling is normally a display only drawing mode done through a software algorithm and collision testing always uses the original sprites dimensions and rotation. By copying the sprite its easy to create a scaled rotated image that will properly collision test and allow for faster frame rates. For example lets say we wanted to copy a sprite rotated 90 degrees and use a different mask color for the new sprite. 'Load the source sprite and set the drawing mode, transparent color and display angle.
For a direct bit copy set the source sprites drawing mode to @BLOCKCOPY and copy the frames individually from source to destination. A complete example of copying sprites can be found in the sprite_copying.eba sample. |