For what it’s worth: Programming Clarity - PhilOfPerth - 07-26-2024
As someone close to the bottom of the “programming chain”, I just want to make a few comments on what makes programmes understandable, at least for me. I know some members won’t agree with some of these things, and some seem pretty obvious, but I find they help me to understand someone else’s programming.
Comments: A few words at the end of, or before, a line that introduces new elements or features can be a great help, not only to other readers, but to the author when editing or reviewing later. They don’t greatly increase the programme size, and are not included in the compiled programme, so why not use them?.
Variable Names: These should give an indication of what they represent. An abbreviated form, maybe with vowels removed, is often ok, but a full word is even better: “TopScore” is clearer than “TpScr”, and won’t be confused with say a “TopOfScreen”, but either one is better than “scmx%”. Some names will necessarily be a bit obscure, especially with advanced trig or system items, so may need a comment to give some indication of their purpose, when first introduced.
Labels: When a new section of a unit starts – whether in the Main or a Sub or Function – it helps if that section is spaced out, and given a meaningful label, telling the reader what the section does, e.g. “CheckBoundary:”. Although spaces are not allowed in labels, CapitalLetters or Under_Scores can be used instead.
Subs and Functions: should have a meaningful name that describes their purpose, and if necessary a comment explaining this.
Programme Names: These should give enough information to tell readers what they can expect to find in the programme. An Introductory page or paragraph that can be seen on opening can also be useful.
Many writers do these things as a matter of course, but occasionally they become so involved in making the programme smaller, or work or run faster, that these are overlooked, leaving readers like me mystified about the purpose of that section, or of the whole programme !
RE: For what it’s worth: Programming Clarity - Pete - 07-26-2024
You would have hated me back in the day...
Single letter variables.
Code in all caps.
No commenting anywhere.
No indentation.
No spacing between lines.
That's right:
Code: (Select All)
A$ = "HELLO WORLD!"
PRINT A$
Well, that and a few thousand more lines, usually.
Pete
RE: For what it’s worth: Programming Clarity - TerryRitchie - 07-26-2024
I hear you loud and clear Phil. As someone who does all the things you like to see in code I also like to see code that has been constructed well.
It all boils down to habit and discipline. If you force yourself to write self documenting code (variable names that have meaning) and take the time to comment the code sections you'll get into the habit of doing so. Then it takes discipline to keep that habit constant.
It takes work and planning to do this but the payoff is huge in the end. As an example, here is a small section of code I am currently working on right now. I'm not saying others need to go to the extremes I do when commenting but some commenting and organization would be nice. Like you I've looked at code with non-descript variable names and zero comments and been mystified at the things I have seen. It's not just new programmers that get confused by spaghetti code.
Code: (Select All)
' Notes to remember:
'
' CREATE ACTIONS (animation, movement, and sound at same time)
' CREATE GUIDED MOTION (sort of like DRAW command)
OPTION _EXPLICIT
'$INCLUDE:'.\lib\common\lib_type_spoint.bi'
'$INCLUDE:'.\lib\common\lib_type_rect.bi'
'$INCLUDE:'.\lib\image\lib_img_flip.bi' ' IMG_Flip subroutine
'$INCLUDE:'.\lib\image\lib_img_introtate.bi' IMG_INTRotate subroutine
' ==============================================================================================================================================
' // \\
' // USER DATA TYPE DECLARATIONS \\
'// \\
'====================================================================================================================================================
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| SPRITE SHEETS |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_SHEETDB ' SPRITE SHEET DATABSE PROPERTIES
inUse AS INTEGER ' index in use (0 FALSE, -1 TRUE)
Image AS LONG ' image of sprite sheet
Width AS INTEGER ' width of sprite sheet
Height AS INTEGER ' height of sprite sheet
GridWidth AS INTEGER ' width of each grid cell
GridHeight AS INTEGER ' height of each grid cell
Columns AS INTEGER ' number of colums on sprite sheet
Rows AS INTEGER ' number of rows on sprite sheet
END TYPE
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| STILL IMAGES |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_IMAGEDB ' STILL IMAGE DATABASE PROPERTIES
inUse AS INTEGER ' index in use (0 FALSE, -1 TRUE)
Original AS LONG ' original still image (use to restore image)
Image AS LONG ' working still image
END TYPE
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| ANIMATIONS |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_ANIMATIONCLIPDB ' ANIMATION CLIP PROPERTIES
inUse AS INTEGER ' index in use (0 FALSE, -1 TRUE)
Strip AS LONG ' image of film strip cells
Cells AS INTEGER ' numer of image cells
Width AS INTEGER ' width of each image cell
Height AS INTEGER ' height of image cells
Direction AS INTEGER ' play direction of film strip
Mode AS INTEGER ' play mode of film strip (0 play once, -1 loop) (use this to set SpriteDB().Mode after playback)
FPS AS INTEGER ' film strip frames per second
END TYPE
TYPE TYPE_ANIMATION ' ANIMATION PROPERIES
hClp AS INTEGER ' animation clip database index pointer
phClp AS INTEGER ' previous animation clip database index pointer
Cell AS INTEGER ' current film strip cell displayed
Frame AS INTEGER ' current frame number within FPS
Auto AS INTEGER ' auto animation enabled (t/f) (when off SPRITE_NextCell must be manually used)
Clip AS TYPE_ANIMATIONCLIPDB ' animation clip properties
END TYPE
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| MOTION |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_MOTION ' MOTION PROPERTIES
xVec AS SINGLE ' normalized x vector (0 to 1)
yVec AS SINGLE ' normalized y vector (0 to 1)
xMag AS SINGLE ' x vector multiplier (speed)
yMag AS SINGLE ' y vector multiplier (speed)
xDir AS INTEGER ' x direction of travel (-1 or 1)
yDir AS INTEGER ' y direction of travel (-1 or 1)
Degree AS SINGLE ' degree direction of travel (0 to 360)
END TYPE
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| COLLISIONS |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_COLLISION ' COLLISION PROPERTIES
Method AS INTEGER ' Method of collision detection to use
With AS INTEGER ' sprite that collision occurred with
Point AS TYPE_SPOINT ' point of collision (circle, line, pixel)
Rect AS TYPE_RECT ' area of collision (box)
Radius AS SINGLE ' radius of circle collision
END TYPE
' --------------------------------------------------------------------------------------------------------------------------------------------------
'| SPRITES |
' --------------------------------------------------------------------------------------------------------------------------------------------------
TYPE TYPE_SPRITEDB
inUse AS INTEGER ' index in use (0 FALSE, -1 TRUE)
Animation AS TYPE_ANIMATION ' animation properties
Still AS LONG ' still image (points back to image database)
Mode AS INTEGER ' Still image or animation (0 Still, -1 Animation)
AutoMove AS INTEGER ' auto motion enabled (t/f) (when off SPRITE_Move must manually be used)
Image AS LONG ' working sprite image (copied from animation cell or still image)
Width AS INTEGER ' width of working sprite image (always recalculate since still image can change)
Height AS INTEGER ' height of working sprite image (always recalculate since still image can change)
Rect AS TYPE_RECT ' working sprite image screen coordinates
Collision AS TYPE_COLLISION ' collision properties
Motion AS TYPE_MOTION ' motion properties
Location AS TYPE_SPOINT ' x,y location of sprite
Justify AS INTEGER ' working sprite image justification (0 to 9)
Joffset AS TYPE_SPOINT ' custom justification x,y offsets
Flip AS INTEGER ' working sprite image flip orientation (0 to 3)
Rotate AS SINGLE ' working sprite image rotation (0 to 359.999)
Zoom AS SINGLE ' working sprite image zoom level (.1 or higher)
Visible AS INTEGER ' working sprite image visible on screen (0 FALSE, -1 TRUE)
Moved AS INTEGER ' sprite location or justification has changed (0 FALSE, -1 TRUE)
Collided AS INTEGER ' sprite was involved in a collision (0 FALSE, -1 TRUE)
Update AS INTEGER ' working sprite image needs updating (0 FALSE, -1 TRUE)
Status AS INTEGER ' sprite status (0 IGNORE (dead), 1 NORMAL (alive), 2 PAUSE (no updates))
END TYPE
' ==============================================================================================================================================
' // \\
' // VARIABLE DECLARATIONS \\
'// \\
'====================================================================================================================================================
REDIM Sheetdb(0) AS TYPE_SHEETDB ' sprite sheet database
REDIM SpriteDB(0) AS TYPE_SPRITEDB ' sprite database
REDIM ImageDB(0) AS TYPE_IMAGEDB ' still image database
REDIM ClipDB(0) AS TYPE_ANIMATIONCLIPDB ' animation database
DIM Sheet AS INTEGER
DIM Standing AS INTEGER
DIM Background AS INTEGER
Sheet = SHEET_Load(".\lib\sprite\dkong.png", 64, 64)
Standing = IMAGE_Make(Sheet, 1, 1)
Background = IMAGE_Load(".\lib\sprite\backg.png")
SHEET_Delete Sheet
IMAGE_Rotate Standing, 60
SCREEN _NEWIMAGE(800, 600, 32)
IMAGE_Put Background, 0, 0
IMAGE_Put Standing, 100, 100
PRINT IMAGE_Width(Standing); IMAGE_Height(Standing)
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
' V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
' ==============================================================================================================================================
' // \\
' // SPRITE SHEET SUBS AND FUNCTIONS \\
'// \\
'====================================================================================================================================================
' ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET__NextIndex% () ' SHEET__NextIndex% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| INTERNAL USE ONLY |
'| |
'| Get the next available index in the sprite sheet database. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
DIM Index AS INTEGER ' index counter
Index = -1 ' reset index counter
DO ' begin database search loop
Index = Index + 1 ' increment index counter
LOOP UNTIL Sheetdb(Index).inUse = 0 OR Index = UBOUND(Sheetdb) ' leave when free index found or end of database
IF Sheetdb(Index).inUse <> 0 THEN ' was a free index found?
Index = Index + 1 ' no, increment the index counter
REDIM _PRESERVE Sheetdb(Index) AS TYPE_SHEETDB ' increase the size of the database
END IF
Sheetdb(Index).inUse = -1 ' record index in use (TRUE)
SHEET__NextIndex% = Index ' return index value
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_Exists% (hSht AS INTEGER) ' SHEET_Exists% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the existence of a sprite sheet 0 (SPRITE_FALSE) or -1 (SPRITE_TRUE) |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: IsExisting% = SHEET_Exists%(MarioSheet%) ' test if the sprite sheet exists in the sprite sheet database |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
IF hSht < 0 OR hSht > UBOUND(Sheetdb) THEN ' handle out of array bounds?
SHEET_Exists% = 0 ' yes, sprite sheet does not exist (FALSE)
ELSE ' no, within bounds
SHEET_Exists% = Sheetdb(hSht).inUse ' return in use status (-1 TRUE or 0 FALSE)
END IF
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_Load% (Filename AS STRING, GridWidth AS INTEGER, GridHeight AS INTEGER) ' SHEET_Load% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Load a sprite sheet into the sprite sheet database. |
'| |
'| Filename - name of image file to load |
'| GridWidth - width of each grid cell |
'| GridHeight - height of each grid cell |
'| |
'| Example: MarioSheet% = SHEET_Load%("MarioSheet.png", 64, 64) ' load sprite sheet with a 64 pixel by 64 pixel cell grid applied |
'| |
'| Note: The grid width and height can be modified later with the use of SHEET_GridSize. This will allow different sized sprites to be |
'| contained within the same sprite sheet. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_Load%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
DIM Index AS INTEGER ' index counter
' \\\\\
IF GridWidth < 1 THEN SPRITE__Error FUNCNAME, "The grid width must be greater than zero"
IF GridHeight < 1 THEN SPRITE__Error FUNCNAME, "The grid height must be greater than zero"
IF _FILEEXISTS(Filename) = 0 THEN SPRITE__Error FUNCNAME, "The requested image file does not exist"
' /////
Index = SHEET__NextIndex% ' get the next available index
Sheetdb(Index).Image = _LOADIMAGE(Filename, 32) ' load the sprite sheet image
' \\\\\
IF Sheetdb(Index).Image = -1 THEN SPRITE__Error FUNCNAME, "There was an error loading the sprite sheet image file"
' /////
Sheetdb(Index).Width = _WIDTH(Sheetdb(Index).Image) ' record sprite sheet width
Sheetdb(Index).Height = _HEIGHT(Sheetdb(Index).Image) ' record sprite sheet height
' \\\\\
IF GridWidth > Sheetdb(Index).Width THEN SPRITE__Error FUNCNAME, "The grid width can't exceed the sprite sheet width"
IF GridHeight > Sheetdb(Index).Height THEN SPRITE__Error FUNCNAME, "The grid height can't exceed the sprite sheet height"
' /////
Sheetdb(Index).GridWidth = GridWidth ' record grid cell width
Sheetdb(Index).GridHeight = GridHeight ' record grid cell height
Sheetdb(Index).Columns = Sheetdb(Index).Width \ GridWidth ' record number of columns
Sheetdb(Index).Rows = Sheetdb(Index).Height \ GridHeight ' record number of rows
Sheetdb(Index).inUse = -1 ' record this index in use
SHEET_Load% = Index ' return sheet handle
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB SHEET_Delete (hSht AS INTEGER) ' SHEET_Delete |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Removes a sprite sheet from the sprite sheet database. The sprite sheet handle variable used to call this subroutine is set to -1. |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: SHEET_Delete MarioSheet% ' delete the mario sprite sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "SHEET_Delete" ' subroutine name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error SUBNAME, "The requested sprite sheet does not exist"
' /////
IF Sheetdb(hSht).Image < -1 THEN _FREEIMAGE Sheetdb(hSht).Image ' remove the sprite sheet image from RAM
Sheetdb(hSht).inUse = 0 ' database index no longer in use (FALSE)
hSht = -1 ' set calling variable to -1
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_ClearColor~& (hSht AS INTEGER) ' SHEET_ClearColor~& |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the transparent color of a sprite sheet. |
'| |
'| hSht - sprite sheet handle |
'| |
'| Example: TransparentColor~& = SHEET_ClearColor~&(MarioSheet%) ' get transparent color of sprite sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_ClearColor~&" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
' /////
SHEET_ClearColor~& = _CLEARCOLOR(Sheetdb(hSht).Image) ' return sprite sheet transparent color
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB SHEET_ClearColor (hSht AS INTEGER, cColor AS _UNSIGNED LONG) ' SHEET_ClearColor |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Sets the transparent color of a sprite sheet' |
'| |
'| hSht - sprite sheet handle |
'| cColor - the color defined as transparent |
'| |
'| Example: SHEET_ClearColor MarioSheet%, _RGB32(255, 0, 255) ' set bright magenta as the transparent color |
'| |
'| Note: The sprite library will ultilize transparent colors contained within .PNG image files. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "SHEET_ClearColor" ' subroutine name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error SUBNAME, "The requested sprite sheet does not exist"
' /////
_CLEARCOLOR cColor, Sheetdb(hSht).Image ' set sprite sheet transparent color
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB SHEET_GridSize (hSht AS INTEGER, GridWidth AS INTEGER, GridHeight AS INTEGER) ' SHEET_GridSize |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Define the grid cell dimensions of a sprite sheet to allow for multiple sized images within a sprite sheet. |
'| |
'| hSht - sprite sheet handle |
'| GridWidth - width of each grid cell |
'| GridHeight - height of each grid cell |
'| |
'| Example: SHEET_GridSize MarioSheet%, 32, 32 ' define a 32x32 grid on the sprite sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "SHEET_GridSize" ' subroutine name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error SUBNAME, "The requested sprite sheet does not exist"
IF GridWidth < 1 THEN SPRITE__Error SUBNAME, "The grid width must be greater than zero"
IF GridHeight < 1 THEN SPRITE__Error SUBNAME, "The grid height must be greater than zero"
IF GridWidth > Sheetdb(hSht).GridWidth THEN SPRITE__Error SUBNAME, "The grid width can't exceed the sprite sheet width"
IF GridHeight > Sheetdb(hSht).GridHeight THEN SPRITE__Error SUBNAME, "The grid height can't exceed the sprite sheet height"
' /////
Sheetdb(hSht).GridWidth = GridWidth ' record grid cell width
Sheetdb(hSht).GridHeight = GridHeight ' record grid cell height
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_Width% (hSht AS INTEGER) ' SHEET_Width% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the width of a sprite sheet. |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: Swidth% = SHEET_Width%(MarioSheet%) ' get the width of the sprite sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_Width%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
' /////
SHEET_Width% = Sheetdb(hSht).Width ' return width of sprite sheet
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_Height% (hSht AS INTEGER) ' SHEET_Height% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the height of a sprite sheet. |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: Sheight% = SHEET_Height%(MarioSheet%) ' get the height of the sprite sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_Height%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
' /////
SHEET_Height% = Sheetdb(hSht).Height ' return height of sprite sheet
END FUNCTION
'+--------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_GridWidth% (hSht AS INTEGER) ' SHEET_GridWidth% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the width of the grid cells on a sprite sheet. |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: GridWidth% = SHEET_GridWidth%(MarioSheet%) ' get the width of the grid on sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_GridWidth%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
' /////
SHEET_GridWidth% = Sheetdb(hSht).GridWidth ' return width of grid on sheet
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SHEET_GridHeight% (hSht AS INTEGER) ' SHEET_GridHeight% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the height of the grid cells on a sprite sheet. |
'| |
'| hSht - the sprite sheet handle |
'| |
'| Example: GridHeight% = SHEET_GridHeight%(MarioSheet%) ' get the height of the grid on the sheet |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "SHEET_GridHeight%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet handle does not exist"
' /////
SHEET_GridHeight% = Sheetdb(hSht).GridHeight ' return the height of grid on sheet
END FUNCTION
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
' V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
' ==============================================================================================================================================
' // \\
' // STILL IMAGE SUBS AND FUNCTIONS \\
'// \\
'====================================================================================================================================================
' ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE__NextIndex% () ' IMAGE__NextIndex% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| INTERNAL USE ONLY |
'| |
'| Get the next available index in the still image database. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
DIM Index AS INTEGER ' index counter
Index = -1 ' reset index counter
DO ' begin database search loop
Index = Index + 1 ' increment index counter
LOOP UNTIL ImageDB(Index).inUse = 0 OR Index = UBOUND(ImageDB) ' leave when free index found or end of database
IF ImageDB(Index).inUse <> 0 THEN ' was a free index found?
Index = Index + 1 ' no, increment the index counter
REDIM _PRESERVE ImageDB(Index) AS TYPE_IMAGEDB ' increase the size of the database
END IF
ImageDB(Index).inUse = -1 ' record index in use (TRUE)
IMAGE__NextIndex% = Index ' return index value
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_Exists% (hImg AS INTEGER) ' IMAGE_Exists% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the existence of a still image 0 (SPRITE_FALSE) or -1 (SPRITE_TRUE) |
'| |
'| hImg - the still image handle |
'| |
'| Example: IsExisting% = IMAGE_Exists%(MarioStand%) ' test if the still image exists |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
IF hImg < 0 OR hImg > UBOUND(ImageDB) THEN ' handle out of array bounds?
IMAGE_Exists% = 0 ' yes, still image does not exist (FALSE)
ELSE ' no, within bounds
IMAGE_Exists% = ImageDB(hImg).inUse ' return in use status (-1 TRUE or 0 FALSE)
END IF
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_Make% (hSht AS INTEGER, Column AS INTEGER, Row AS INTEGER) ' IMAGE_Make% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Creates a still image from an individual sprite sheet image. |
'| |
'| hSht - the sprite sheet handle |
'| Column - the sprite sheet column |
'| Row - the sprite sheet row |
'| |
'| Example: MarioStanding% = IMAGE_Make%(MarioSheet%, 1, 1) ' get the mario standing still image |
'| |
'| Note: Column and Row are based on the current grid size setting of the sprite sheet. |
'| Use SHEET_GridSize to change the grid sizing to meet your needs. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "IMAGE_Make%" ' function name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
DIM Index AS INTEGER ' next available image database index
DIM x1 AS INTEGER ' location of image on sprite sheet
DIM y1 AS INTEGER ' (x1, y1) - (x2, y2)
DIM x2 AS INTEGER
DIM y2 AS INTEGER
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
IF Column < 1 THEN SPRITE__Error FUNCNAME, "Column must be greater than 0"
IF Row < 1 THEN SPRITE__Error FUNCNAME, "Row must be greater than 0"
IF Column > Sheetdb(hSht).Columns THEN SPRITE__Error FUNCNAME, "Column exceeds the number of columns on the sprite sheet"
IF Row > Sheetdb(hSht).Rows THEN SPRITE__Error FUNCNAME, "Row exceeds the number of rows on the sprite sheet"
' /////
Index = IMAGE__NextIndex% ' get next available index
ImageDB(Index).Original = _NEWIMAGE(Sheetdb(hSht).GridWidth, Sheetdb(hSht).GridHeight, 32) ' create image canvas
x1 = Sheetdb(hSht).GridWidth * (Column - 1) ' calculate image location on sheet
y1 = Sheetdb(hSht).GridHeight * (Row - 1)
x2 = x1 + Sheetdb(hSht).GridWidth - 1
y2 = y1 + Sheetdb(hSht).GridHeight - 1
_PUTIMAGE , Sheetdb(hSht).Image, ImageDB(Index).Original, (x1, y1)-(x2, y2) ' clip image from sprite sheet
ImageDB(Index).Image = _COPYIMAGE(ImageDB(Index).Original) ' copy the working image
IMAGE_Make% = Index ' return still image handle
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_Load% (FileName AS STRING) ' IMAGE_Load% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Creates a still image from an image file. |
'| |
'| FileName - the image file name |
'| |
'| Example: MarioStanding% = IMAGE_Load%("MarioStanding.PNG") ' load the mario standing still image |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "IMAGE_Load%" ' function name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
DIM Index AS INTEGER ' next available image database index
' \\\\\
IF _FILEEXISTS(FileName) = 0 THEN SPRITE__Error FUNCNAME, "The requested image file does not exist"
' /////
Index = IMAGE__NextIndex% ' get next available index
ImageDB(Index).Original = _LOADIMAGE(FileName, 32) ' load the image file
' \\\\\
IF ImageDB(Index).Original = -1 THEN SPRITE__Error FUNCNAME, "There was an error loading the image file"
' /////
ImageDB(Index).Image = _COPYIMAGE(ImageDB(Index).Original) ' copy the working image
IMAGE_Load% = Index ' return still image handle
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Delete (hImg AS INTEGER) ' IMAGE_Delete |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Removes a still image from the still image database and RAM. |
'| |
'| hImg - the still image handle |
'| |
'| Example: IMAGE_Delete MarioStanding% ' remove the mario standing still image |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Load%" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
' /////
IF ImageDB(hImg).Original < -1 THEN _FREEIMAGE ImageDB(hImg).Original ' remove the original still image from RAM
IF ImageDB(hImg).Image < -1 THEN _FREEIMAGE ImageDB(hImg).Image ' remove the working still image from RAM
ImageDB(hImg).inUse = 0 ' record database index not in use (FALSE)
hImg = -1 ' set calling handle to -1
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Apply (hImg AS INTEGER, hSpr AS INTEGER) ' IMAGE_Apply |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Applies a still image to a sprite. |
'| |
'| hImg - the still image handle |
'| hSpr - the sprite handle |
'| |
'| Example: IMAGE_Apply MarioCrouching%, Mario% ' change mario still image to crouching |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Apply" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
SHARED SpriteDB() AS TYPE_SPRITEDB ' need access to sprite database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
IF SPRITE_Exists(hSpr) = 0 THEN SPRITE__Error SUBNAME, "The requested sprite does not exist"
' /////
SpriteDB(hSpr).Still = ImageDB(hImg).Image ' apply the working still image to the sprite
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_ClearColor (hImg AS INTEGER, cColor AS _UNSIGNED LONG) ' IMAGE_ClearColor |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Sets the transparent color of a still image. |
'| |
'| hImg - the still image handle |
'| cColor - the color defined as transparent |
'| |
'| Example: IMAGE_ClearColor MarioStanding%, _RGB32(255, 0, 255) ' set bright magenta as the transparent color |
'| |
'| Note: The sprite library will ultilize transparent colors contained within .PNG image files. |
'| The transparent color will get applied to both the original and working still images. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_ClearColor" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
' /////
_CLEARCOLOR cColor, ImageDB(hImg).Original ' set original image transparent color
_CLEARCOLOR cColor, ImageDB(hImg).Image ' set working still image transparent color
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_ClearColor~& (hImg AS INTEGER) ' IMAGE_ClearColor~& |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the transparent color of a still image. |
'| |
'| hImg - the still image handle |
'| |
'| Example: TransparentColor~& = IMAGE_ClearColor~&(MarioStanding%) ' get transparent color of still image |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "IMAGE_ClearColor~&" ' function name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error FUNCNAME, "The requested still image does not exist"
' /////
IMAGE_ClearColor~& = _CLEARCOLOR(ImageDB(hImg).Original) ' return original still image transparent color
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Restore (hImg AS INTEGER) ' IMAGE_Restore |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Restores the working still image to the original image. |
'| |
'| hImg - the still image handle |
'| |
'| Example: IMAGE_Restore MarioStanding% ' restore the standing image |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Restore" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
' /////
IF ImageDB(hImg).Image < -1 THEN _FREEIMAGE ImageDB(hImg).Image ' remove the working still image from RAM
ImageDB(hImg).Image = _COPYIMAGE(ImageDB(hImg).Original) ' copy the original still image to the working still image
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Flip (hImg AS INTEGER, Flip AS INTEGER) ' IMAGE_Flip |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Flips the working still image. |
'| |
'| hImg - the still image handle |
'| Flip - the flip direction |
'| |
'| Example: IMAGE_Flip MarioStanding%, 1 ' flip the standing image horizontally |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Flip" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
IF Flip < 0 OR Flip > 3 THEN SPRITE__Error SUBNAME, "Flip must be 0 (FLIP_NONE), 1 (FLIP_HORIZONTAL), 2 (FLIP_VERTICAL), or 3 (FLIP_BOTH)"
' /////
IMG_Flip ImageDB(hImg).Image, Flip ' flip the working still image
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Zoom (hImg AS INTEGER, Zoom AS SINGLE) ' IMAGE_Zoom |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Zooms the working still image. |
'| |
'| hImg - the still image handle |
'| Zoom - the zoom amount |
'| |
'| Example: IMAGE_Zoom MarioStanding%, 1.5 ' zoom the standing image 150% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Zoom" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
IF Zoom <= 0 THEN SPRITE__Error SUBNAME, "Zoom level must be greater than zero"
' /////
IF Zoom <> 1 THEN IMG_Zoom ImageDB(hImg).Image, Zoom ' zoom the working still image if not 100%
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Rotate (hImg AS INTEGER, Degree AS SINGLE) ' IMAGE_Rotate |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Rotates the working still image to the degree specified. |
'| |
'| hImg - the still image handle |
'| Degree - the degree of rotation |
'| |
'| Example: IMAGE_Rotate MarioStanding%, 45 ' rotate the standing image to 45 degrees |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Rotate" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
' /////
IMG_INTRotate ImageDB(hImg).Image, Degree ' rotate the working still image
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB IMAGE_Put (hImg AS INTEGER, x AS INTEGER, y AS INTEGER) ' IMAGE_Put |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Draws the working still image to the screen at coordinates x,y. |
'| |
'| hImg - the still image handle |
'| x - the screen x coordinate |
'| y - the screen y coordinate |
'| |
'| Example: IMAGE_Put Statue%, 100, 150 ' draw an image of the statue to the screen |
'| |
'| Note: The image is drawn to the current destination surface which may not be the screen. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "IMAGE_Put" ' subroutine name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error SUBNAME, "The requested still image does not exist"
' /////
_PUTIMAGE (x, y), ImageDB(hImg).Image ' draw image onto current destination surface
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_Width% (hImg AS INTEGER) ' IMAGE_Width% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Return the width of the working still image. |
'| |
'| hImg - the still image handle |
'| |
'| Example: iw% = IMAGE_Width%(MarioStanding%) ' return the still image width |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "IMAGE_Width%" ' function name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error FUNCNAME, "The requested still image does not exist"
' /////
IMAGE_Width% = _WIDTH(ImageDB(hImg).Image) ' return width of working still image
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION IMAGE_Height% (hImg AS INTEGER) ' IMAGE_Height% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Return the height of the working still image. |
'| |
'| hImg - the still image handle |
'| |
'| Example ih% = IMAGE_Height%(MarioStanding%) ' return the still image height |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "IMAGE_Height%" ' function name for error reporting
SHARED ImageDB() AS TYPE_IMAGEDB ' need access to still image database
' \\\\\
IF IMAGE_Exists(hImg) = 0 THEN SPRITE__Error FUNCNAME, "The requested still image does not exist"
' /////
IMAGE_Height% = _HEIGHT(ImageDB(hImg).Image) ' return height of working still image
END FUNCTION
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
' V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
' ==============================================================================================================================================
' // \\
' // ANIMATION SUBS AND FUNCTIONS \\
'// \\
'====================================================================================================================================================
' ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP__NextIndex% () ' CLIP__NextIndex% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| INTERNAL USE ONLY |
'| |
'| Get the next available index in the animation clip database. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
DIM Index AS INTEGER ' index counter
Index = -1 ' reset index counter
DO ' begin database search loop
Index = Index + 1 ' increment index counter
LOOP UNTIL ClipDB(Index).inUse = 0 OR Index = UBOUND(ClipDB) ' leave when free index found or end of database
IF ClipDB(Index).inUse <> 0 THEN ' was a free index found?
Index = Index + 1 ' no, increment the index counter
REDIM _PRESERVE ClipDB(Index) AS TYPE_ANIMATIONCLIPDB ' increase the size of the database
END IF
ClipDB(Index).inUse = -1 ' record index in use (TRUE)
CLIP__NextIndex% = Index ' return index value
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_Exists% (hClp AS INTEGER) ' CLIP_Exists% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the existence of an animation clip 0 (SPRITE_FALSE) or -1 (SPRITE_TRUE) |
'| |
'| hClp - the animation clip handle |
'| |
'| Example: IsExisting% = CLIP_Exists%(MarioRunning%) ' test if the animation clip exists |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
IF hClp < 0 OR hClp > UBOUND(ClipDB) THEN ' handle out of array bounds?
CLIP_Exists% = 0 ' yes, animation clip does not exist (FALSE)
ELSE ' no, within bounds
CLIP_Exists% = ClipDB(hClp).inUse ' return in use status (-1 TRUE or 0 FALSE)
END IF
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_Make% (hSht AS INTEGER, c AS INTEGER, r AS INTEGER, Cells AS INTEGER, Dir AS INTEGER, Mode AS INTEGER, FPS AS INTEGER) ' CLIP_Make% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Creates an animation clip from image cells on a sprite sheet. |
'| |
'| hSht - the sprite sheet handle |
'| c - the sprite sheet column |
'| r - the sprite sheet row |
'| Cells - the number of cells contained in the film strip |
'| Dir - the animation play direction 1 (CLIP_FORWARD) or -1 (CLIP_BACKWARD) |
'| Mode - the animation play mode -1 (CLIP_LOOP) or 0 (CLIP_PLAYONCE) |
'| FPS - the animation frames per second |
'| |
'| Example: MarioWalking% = CLIP_Make%(MarioSheet%, 2, 1, 2, 1, 0, 10) ' create the mario walking animaton sequence |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "CLIP_Make%" ' function name for error reporting
SHARED Sheetdb() AS TYPE_SHEETDB ' need access to sprite sheet database
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
DIM Index AS INTEGER ' next available animation clip database index
DIM x1 AS INTEGER ' location of animation clip on sprite sheet
DIM y1 AS INTEGER ' (x1, y1) - (x2, y2)
DIM x2 AS INTEGER
DIM y2 AS INTEGER
' \\\\\
IF SHEET_Exists(hSht) = 0 THEN SPRITE__Error FUNCNAME, "The requested sprite sheet does not exist"
IF c < 1 THEN SPRITE__Error FUNCNAME, "Column must be greater than 0"
IF r < 1 THEN SPRITE__Error FUNCNAME, "Row must be greater than 0"
IF c > Sheetdb(hSht).Columns THEN SPRITE__Error FUNCNAME, "Column exceeds the number of columns on the sprite sheet"
IF r > Sheetdb(hSht).Rows THEN SPRITE__Error FUNCNAME, "Row exceeds the number of rows on the sprite sheet"
IF Cells < 2 THEN SPRITE__Error FUNCNAME, "An animation clip must contain at least two cells"
IF ABS(Dir) <> 1 THEN SPRITE__Error FUNCNAME, "The direction must be 1 (CLIP_FORWARD) or -1 (CLIP_BACKWARD)"
IF Mode < 0 OR Mode > 1 THEN SPRITE__Error FUNCNAME, "Mode must either be -1 (CLIP_LOOP) or 0 (CLIP_PLAYONCE)"
IF FPS < 1 THEN SPRITE__Error FUNCNAME, "FPS must be greater than zero"
' /////
Index = CLIP__NextIndex% ' get next available index in database
ClipDB(Index).Cells = Cells ' record number of film strip cells
ClipDB(Index).Width = Sheetdb(hSht).GridWidth ' record each cell width
ClipDB(Index).Height = Sheetdb(hSht).GridHeight ' record each cell height
ClipDB(Index).Direction = Dir ' record animation direction
ClipDB(Index).Mode = Mode ' record animation play mode
ClipDB(Index).FPS = FPS ' record animation frames per second
x1 = Sheetdb(hSht).GridWidth * (c - 1) ' calculate animation clip location on sheet
y1 = Sheetdb(hSht).GridHeight * (r - 1)
x2 = x1 + Sheetdb(hSht).GridWidth * Cells - 1
y2 = y1 + Sheetdb(hSht).GridHeight - 1
ClipDB(Index).Strip = _NEWIMAGE(Sheetdb(hSht).GridWidth * Cells, Sheetdb(hSht).GridHeight, 32) ' create film strip image
_PUTIMAGE , Sheetdb(hSht).Image, ClipDB(Index).Strip, (x1, y1)-(x2, y2) ' clip animation clip from sprite sheet
CLIP_Make% = Index ' return animation clip handle
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_Load% (FileName AS STRING, cw AS INTEGER, Dir AS INTEGER, Mode AS INTEGER, FPS AS INTEGER) ' CLIP_Load% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Creates an animation clip from an image file. |
'| |
'| FileName - the name of the image file |
'| cw - the width of each animation strip cell |
'| Dir - the animation play direction 1 (CLIP_FORWARD) or -1 (CLIP_BACKWARD) |
'| Mode - the animation play mode -1 (CLIP_LOOP) or 0 (CLIP_PLAYONCE) |
'| FPS - the animation frames per second |
'| |
'| Example: MarioWalking% = CLIP_Load%("MarioWalking.PNG", 64, 1, 0, 10) ' load the Mario walking animation sequence |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "CLIP_Load%" ' function name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
DIM Index AS INTEGER ' next available animation clip database index
' \\\\\
IF _FILEEXISTS(FileName) = 0 THEN SPRITE__Error FUNCNAME, "The requested animation clip image file does not exist"
' /////
Index = CLIP__NextIndex% ' get next available index in database
ClipDB(Index).Strip = _LOADIMAGE(FileName, 32) ' load film strip image
' \\\\\
IF ClipDB(Index).Strip = -1 THEN SPRITE__Error FUNCNAME, "There was an error loading the animation clip image file"
IF _WIDTH(ClipDB(Index).Strip) / cw <> INT(_WIDTH(ClipDB(Index).Strip) / cw) THEN
SPRITE__Error FUNCNAME, "The animation clip image is not evenly divisible by the cell width provided"
END IF
' /////
ClipDB(Index).Cells = _WIDTH(ClipDB(Index).Strip) \ cw ' calculate number of film strip cells
ClipDB(Index).Width = cw ' record each cell width
ClipDB(Index).Height = _HEIGHT(ClipDB(Index).Strip) ' record each cell height
ClipDB(Index).Direction = Dir ' record animation direction
ClipDB(Index).Mode = Mode ' record animation play mode
ClipDB(Index).FPS = FPS ' record animation frames per second
CLIP_Load% = Index ' return animation clip handle
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB CLIP_Delete (hClp AS INTEGER) ' CLIP_Delete |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Deletes an animation clip. |
'| |
'| hClp - the animation clip handle |
'| |
'| Example: CLIP_Delete SmallExplosion% ' remove the animation clip |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "CLIP_Delete" ' subroutine name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
' \\\\\
IF CLIP_Exists(hClp) = 0 THEN SPRITE__Error SUBNAME, "The requested animation clip does not exist"
' /////
IF ClipDB(hClp).Strip < -1 THEN _FREEIMAGE ClipDB(hClp).Strip ' remove animation film strip from RAM
ClipDB(hClp).inUse = 0 ' database index not used (FALSE)
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
SUB CLIP_ClearColor (hClp AS INTEGER, cColor AS _UNSIGNED LONG) ' CLIP_ClearColor |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Sets the transparent color of an animation clip. |
'| |
'| hClp - the animation clip handle |
'| cColor - the color defined as transparent |
'| |
'| Example: CLIP_ClearColor MarioRunning%, _RGB32(255, 0, 255) ' set bright magenta as the transparent color |
'| |
'| Note: The sprite library will ultilize transparent colors contained within .PNG image files. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST SUBNAME = "CLIP_ClearColor" ' subroutine name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
' \\\\\
IF CLIP_Exists(hClp) = 0 THEN SPRITE__Error SUBNAME, "The requested animation clip does not exist"
' /////
_CLEARCOLOR cColor, ClipDB(hClp).Strip ' set film strip image transparent color
END SUB
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_ClearColor~& (hClp AS INTEGER) ' CLIP_ClearColor~& |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the transparent color of an animation clip. |
'| |
'| hClp - the animation clip handle |
'| |
'| Example: TransparentColor~& = CLIP_ClearColor~&(MarioRunning%) ' get transparent color of animation clip |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "CLIP_ClearColor~&" ' function name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
' \\\\\
IF CLIP_Exists(hClp) = 0 THEN SPRITE__Error FUNCNAME, "The requested animation clip does not exist"
' /////
CLIP_ClearColor~& = _CLEARCOLOR(ClipDB(hClp).Strip) ' return film strip image transparent color
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_CellWidth% (hClp AS INTEGER) ' CLIP_CellWidth% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Return the width of each cell within an animation clip. |
'| |
'| hClp - the animation clip handle |
'| |
'| Example: cw% = CLIP_CellWidth%(MarioRunning%) ' get the cell width of the animation clip |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "CLIP_CellWidth%" ' function name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
' \\\\\
IF CLIP_Exists(hClp) = 0 THEN SPRITE__Error FUNCNAME, "The requested animation clip does not exist"
' /////
CLIP_CellWidth% = ClipDB(hClp).Width ' return cell width
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION CLIP_CellHeight% (hClp AS INTEGER) ' CLIP_CellHeight% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Return the height of each cell within an animation clip. |
'| |
'| hClp - the animation clip handle |
'| |
'| Example: ch% = CLIP_CellHeight%(MarioRunning%) ' get the cell height of the animation clip |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
CONST FUNCNAME = "CLIP_CellHeight%" ' function name for error reporting
SHARED ClipDB() AS TYPE_ANIMATIONCLIPDB ' need access to animation clip database
' \\\\\
IF CLIP_Exists(hClp) = 0 THEN SPRITE__Error FUNCNAME, "The requested animation clip does not exist"
' /////
CLIP_CellHeight% = ClipDB(hClp).Height ' return cell height
END FUNCTION
'---------------------------------------------------------------------------------------------------------------------------------------------------+
FUNCTION SPRITE_Exists% (hSpr AS INTEGER) ' SPRITE_Exists% |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
'| Returns the existence of a sprite 0 (SPRITE_FALSE) or -1 (SPRITE_TRUE) |
'| |
'| hSpr - the sprite handle |
'| |
'| Example: IsExisting% = SPRITE_Exists%(Mario%) ' test if the sprite exists in the sprite database |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SHARED SpriteDB() AS TYPE_SPRITEDB ' need access to sprite database
IF hSpr < 0 OR hSpr > UBOUND(SpriteDB) THEN ' handle out of array bounds?
SPRITE_Exists% = 0 ' yes, still image does not exist (FALSE)
ELSE ' no, within bounds
SPRITE_Exists% = SpriteDB(hSpr).inUse ' return in use status (-1 TRUE or 0 FALSE)
END IF
END FUNCTION
'-----------------------------------------------------------------------------------------------------------------------------------+---------------+
SUB SPRITE__Error (SubFunc AS STRING, Report AS STRING) ' | SPRITE__Error |
'+------------------------------------------------------------------------------------------------------------------------------+---------------+
'| INTERNAL USE ONLY |
'| |
'| Reports errors found to programmer. |
'+----------------------------------------------------------------------------------------------------------------------------------------------+
SCREEN 0, 0, 0, 0 ' pure text (Pete) screen
SOUND 440, 1: SOUND 880, 1 ' play alert sound
PRINT
PRINT " ERROR reported by: "; SubFunc ' report subroutine or function error occurred in
PRINT
PRINT " "; Report ' report the error that occurred
PRINT
PRINT " Press ESC to close this window and return to the IDE." ' display directions
DO ' begin wait loop
_LIMIT 10 ' 10 FPS (don't hog CPU)
LOOP UNTIL _KEYDOWN(27) ' leave when ESC key pressed
SYSTEM ' return to operating system (IDE)
END SUB
'$INCLUDE:'.\lib\image\lib_img_flip.bm' IMG_Flip subroutine
'$INCLUDE:'.\lib\image\lib_img_zoom.bm' IMG_Zoom subroutine
'$INCLUDE:'.\lib\image\lib_img_introtate.bm' IMG_INTRotate subroutine
RE: For what it’s worth: Programming Clarity - aurel - 07-26-2024
Good point IF:
you want make transparent programs that anyone can understand
BUT
I have my own coding style which is good for me
and i don't have time to "explain everything "
IN general there are no rules
RE: For what it’s worth: Programming Clarity - CharlieJV - 07-26-2024
(07-26-2024, 09:11 AM)aurel Wrote: Good point IF:
you want make transparent programs that anyone can understand
BUT
I have my own coding style which is good for me
and i don't have time to "explain everything "
IN general there are no rules
And that is totally fine until you need help to troubleshoot some code that is not working.
It isn't about rules. It is about describing a program just enough so that others can understand it in order to help troubleshoot problems, so hopefully it doesn't require explaining everything.
In a way, this reminds me of the saying "make time for health, or be prepared to make time for sickness." A little bit of time up front in order to avoid a preventable larger amount of time later.
RE: For what it’s worth: Programming Clarity - bplus - 07-26-2024
Yeah self documenting code is really good but sometimes you just want to see something work and maybe not so helpful to self and others with comnments and descriptive names... one really has no idea how another or yourself will see the code now or in future.
But This Is a Forum! where you can ask anything publically or private PM.
Pretty sure most of us here would be happy to clear up some code for you. Who doesn't like talking about their code creations?
RE: For what it’s worth: Programming Clarity - Dimster - 07-26-2024
About comments, a while back, someone, could have been on that other forum, gave the tip that, should you have multiple lines of code and you are heading out on vacation or even done for the night, a simple comment like "Here's Where I Left OFF" is easy to search for when you get back at it. I use this tip a lot but have it down to just "***..."
RE: For what it’s worth: Programming Clarity - Pete - 07-26-2024
(07-26-2024, 07:10 PM)Dimster Wrote: About comments, a while back, someone, could have been on that other forum, gave the tip that, should you have multiple lines of code and you are heading out on vacation or even done for the night, a simple comment like "Here's Where I Left OFF" is easy to search for when you get back at it. I use this tip a lot but have it down to just "***..." Not me. My mind is like a steel trap. Once it slams shut, nothing gets in!
Pete
RE: For what it’s worth: Programming Clarity - PhilOfPerth - 07-26-2024
@ diimster Yes, I do a similar thing while developing a programme. I get it "sort of" working, then go through it from the top, stopping it after each section and ensuring that the section works, and insert a line ' ***** ok to here *** and move to the next section. Works for me.
RE: For what it’s worth: Programming Clarity - mdijkens - 07-27-2024
Funny, since a long time I include '@@someRemark everywhere in my code that still needs attention.
It's finished when Alt-S-F @@ doesn't find anything anymore
|