Date: 02-16-2022
Return to Index
created by gbSnippets
'Now that I've taken an interest in using sprites in my PowerBASIC applications
'I decided to Write a tutorial On what I've learned (am learning). Like any
'tutorial, the goal is to be able to summarize the information in a useful
'way For other programmers. But it's also a way for Me to clarify my own
'understanding of the topic!
'This source code library has several snippets which demonstrate the topics
'covered below.
'This tutorial focusses on the use of DDT commands to implement sprite
'animation, but some API use is included as needed in the various snippets.
'Sprite Animation Flow
'The block diagram of a sprite animation application is pretty simple. When
'a program starts up it builds/loads all sprite images. Animation is a combination
'of a move (recalculation of the position of the sprite) AND displaying the
'repositioned sprite.
'Rather than using untimed Do Loops to repeat move/Display actions, timers
'are used to Create animation. For smooth animation, the Code that preforms
'movement/display must be fast enough to complete within a Timer interval.
'Speed and smoothness of animation is usually enhanced by drawing sprites
'to a non-visible buffer before being used to update a Visible canvas in a
'single draw operation.
' Initialize Timer Event(s)
'--------------------' '-----------------------------------'
' Create/Load Images '-----' Move - Test - Draw - Dipslay '
'--------------------' '-----------------------------------'
'Animation Strategy
'As shown in the following table, there are several elements to consider in
'developing a sprite animation strategy, including the source of the image,
'the use of frames, frame storage methods, multi-threading and choice of
'display canvas.
'Image Frames Frame Storage Threading Final Canvas
'----------------------- ------ ------------------- ----------- ------------
'Realtime draw 1 None (realtime draw) Inline Draw Graphic Control
'Single image per frame >1 Memory bitmap Thread Draw Graphic Window
'Composite image Bit String
' 1 frame/sprite Graphic Control
' n frames/sprite Graphic Window
'Performance factors such as frames per second and number/size of sprites are
'also key factors to consider selecting elements of an animation strategy.
'Sprite Structure (UDT)
'Typically sprites are defined as a UDT array. The members of a sprite UDT are fairly
'standard, such as this UDT example:
' .x x position (upper left corner)
' .y y position (upper left corner)
' .w width of sprite
' .h height of sprite
' .dx movement to be taken in x-direction
' .dy movement to be taken in y-direction
' .sx speed in x-direction
' .sy speed in y-direction
' .hnd image handle or array index to sprite image
' .frcur current frame #, the one to be displayed
' .frmax total number of available frames for the sprite
' .wcount current wait count (counts timer events)
' .wmax max wait count before changing frames
'The UDT contains all information about a sprite.
'Image Sources
'PowerBASIC provides native support for loading bitmaps (*.bmp) directly from
'files. To use icons, the images must first be placed in a resource file
'then added to an imagelist which PowerBASIC graphic statements can access.
'Using the GDI+ snippets found in this library, other file formats such as
'JPG/GIF/PNG can also be loaded and converted to the bitmap format natively
'supported by PowerBASIC.
'Frames
'With each move a sprite must be displayed in its new location. Instead of
'displaying the same image with each move, a series of images called frames may
'be used to display a new image with each move. Frame might contain something
'as simply as a rotation of previous frame or even a complete metamorphisis of
'the image into a completely new image.
'Successive frame display is typically cyclic. For example, displaying frames
'1-30 followed by starting over with frame 1. Variations, such as displaying
'frames 1-30 followed by 30-1, are also used by programmers to create special effects.
'Another variation often used is to display an image frame for more than one
'timer interval. This approach is particularly useful in varying the apparent
'speed at which a frame changes (not location, but visible image). This action
'can applied selectively to each sprite so that all sprites do not appear to be
'changing in unison.
'Frame Images
'For relatively simple shapes, such as combinations of drawing primitives, it
'is possible to create each frame image from scratch during each time interval.
'Sprite animation often uses images which are not easily recreated by code,
'such as photographic images or complex character drawings. In those cases
'pre-existing images are used. For speed reasons, pre-existing images are
'almost always read into memory. Reading images from files is way too slow
'for almost any animation requirements.
'There are three basic strategies for the type of in-memory images.
' 1. Single sprite, single frame image
' 2. Single sprite, multi-frame image (composite image)
' 3. Multi-Sprite, multi-frame image (composite image)
'Further there are two types of in-memory structures that can be used - the
'structure from which the frame image is copied to the buffer or visible canvas.
' 1. Memory Bitmap - generally simpler to understand, code, debug
' 2. Bitmap Strings - when used with pointers, provides fastest frame updates
'The use of pre-defined multi-sprite, multi-frame composite images coupled with
'in-memory bitmap strings is generally considered the optimum solution. However,
'the simplicity of creating an in-memory bitmap and storing the bitmap handle within
'the sprite UDT structure is also an excellent solution.
'Timers
'A timer is typically used to create animation. Within each timer event
'the next sprite position is calculated and the sprite displayed on the
'visible canvas at the new location (changes may first be placed on a buffer
'drawing surface, then sent to the visible canvas in one draw operation).
'The code within the timer event may also perform tests on the sprite
'at the new location, such as whether the sprite has reached the edge
'of the screen or whether two sprites have collided (overlapped in position).
'The SetTimer and timeSetEvent API are both capable of creating timers
'which execute blocks of code at specified intervals. Both are suitable
'for most sprite animation applications.
'Buffering
'Because displaying one updated sprite at a time is a somewhat slow process
'it is common to write all changes to a non-visible canvas or data structure - a
'buffer. When all updates are completed the buffer content is transferred to the
'visible canvas in one operation. This provides greater speed and smoother
'animation frame updates.
'Memory bitmaps and bitmap strings are often used for buffers because they
'allow signficantly faster draw operations than other, visible canvas options
'such as Graphic Controls or Graphic Windows.
'In PowerBASIC, the following commands are available to move buffer content
'to the visible canvas.
' 1. Graphic Set Bits - fastest (allows use of pointers)
' 2. Graphic Copy - fast
' 3. Graphic Set Pixel - slow
'Graphic Set Pixel is not normally used because it is much slower than the
'other two options.
'Speed
'Generally, calculating new positions (movement) is very fast, taking up only
'a small fraction of an animation cycle. Display of the sprites is typically
'the slowest operation and requires the most care to ensure that display of
'all sprite frames can be completed within an animation time interval.
'Animation of under one hundred sprites, of medium sizes (~100x100), can generally
'accomplished with any of the programming options discussed above. But as
'sprite size/number and animation frame rates rise the programmer may need
'to use stratgies such as assembly language (selected replacement of time-critical
'BASIC code) and multi-threading (parallel actions).
'Other Factors:
'1. Transparency
'2. Collision with other sprites
'3. Alphablending (opaqueness)
'4. Motion limits (vs wrap around motion)
'5. Add/delete (usually implemented as Show/Hide)
'6. Zorder Swapping
'7. Group actions (move/show/hide) - not usually critical
'8. Common manipulations in addition to frames: flip LR, flipUD, Rotate
'9. Sprite information retrieval
'10.Mouse click recognition
'Notes:
'0. A sprite is just an image. Sprite animation can consist not only of movement,
' but also of image changes which are usually handled by displaying pre-existing
' images, called frames, to simulate changes other than simple repositioning of
' the image.
'1. As an alternative to frames (pre-existing drawings), sprites also be drawn
' real-time according to program logic. This is less common because of the higher
' processing requirements (which usually means slower animation speeds).
'3. In PowerBASIC, a bmp resource can be used directly, whereas icon images must
' first be placed in an ImageList before than can be used with bufferes
'4. Buffers - Generally, Graphic Control/Window are not used as buffers. They
' can be, but offer no advantage over a visible canvas
'5. Visible Canvas - While API can be used to generate image content within most
' control windows, the technique is not normally employed. Rather, the PowerBASIC
' Graphic Control AND Graphic Window are typically used for displaying sprite animation.
'gbs_00467
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm