09-13-2025, 08:11 PM
As Easter is well behind us....Halloween is next so this is Isometric as requested, it just renders a basic map...i've no idea on rules, game premise, story etc...so we MUST set those first....ANYONE and EVERYONE is welcome to contribute, ideas, code, sprites, whatever....but as bplus came up with the premise, i'll leave it to him to decide the final product.
Unseen
Code: (Select All)
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// All Hallows (Working title for now) - A Halloween Project - v.01
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Built with QB64 PE and Unseen GDK
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Basic
CONST GDK_FALSE = 0
CONST GDK_TRUE = NOT GDK_FALSE
'// Direction (used for sprite/image flipping, etc.) \\
CONST GDK_ID_Right = 0
CONST GDK_ID_Down = 1
CONST GDK_ID_Left = 2
CONST GDK_ID_Up = 3
'// Angle helpers \\
CONST Two_Pi# = _PI * 2, Half_Pi# = _PI / 2, Quarter_Pi# = Half_Pi# / 2
'// Program flow \\
CONST GDK_ID_Start = 0
CONST GDK_ID_Loading = 1
CONST GDK_ID_Running = 2
CONST GDK_ID_Paused = 3
CONST GDK_ID_Saving = 4
CONST GDK_ID_Closing = 5
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
REM $DYNAMIC
DIM SHARED GDK_System AS GDK_System '// Used to control GDK things, load the project, etc..\\
DIM SHARED GDK_KB(1) AS GDK_KeyBoard_State
DIM SHARED GDK_Mouse(1) AS GDK_Mouse_State '// Global Input Handlers \\
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// DIM Stuff here
REDIM SHARED Level(0, 0) AS GDK_Tile, Level_Data AS GDK_Tile_Map, BCK& '// Need to add support for multiple layers eventually
DIM SHARED Fnt_Title AS LONG, Fnt_Small AS LONG, Fnt_Large AS LONG
DIM SHARED Moon AS LONG '// The Background image for the main menu
DIM SHARED SUB_State_Start AS _BYTE
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
GDK_System_New "All_Hallows\", 1024, 768, GDK_FALSE, "All Hallows" '// Set root, screen size, FS and title - initialises Screen, timer, input handling...
'///////////////////////////////////////// Main Loop ///////////////////////////////////////////////////
DO
GDK_System_Update '// Update input handlers, set _limit/fps and update global timer
CLS
'// Make each thing in its own sub/functions to maintain a clear structure and assist in debugging
SELECT CASE GDK_System.Game_State '// Main game state control - add other Flags to control sub states
CASE GDK_ID_Start '// Load ALL Game assets and launch main menu sub
IF SUB_State_Start = 0 THEN AH_Start ELSE Main_Menu
CASE GDK_ID_Loading '// Load level specific assets
AH_New_Game
CASE GDK_ID_Running '// The game is being played
AH_In_Game
CASE GDK_ID_Paused '// Game is paused
CASE GDK_ID_Saving '// Saving data
CASE GDK_ID_Closing '// Quit playing so free stuff and check if player wants to save
END SELECT
_DISPLAY
LOOP UNTIL GDK_KB(0).ESC
SYSTEM
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// DEV NOTE - A VERY SIMPLE Level Designer is probally a must have! Doing this with DATA SUCKS!!!
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Level DATA - Use restore and label to load the level
'// - NOTE MORE will be added, like origins, number of layers, etc...
Default_Level:
DATA "Resources\Tilesets\Earth_iso.png",39,39
DATA 13,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,6
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,10,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,3
DATA 7,5,5,9,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 7,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,3
DATA 4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB AH_Start
Fnt_Title = _LOADFONT("Resources\Fonts\youmurdererbb_reg.ttf", 140)
Fnt_Small = _LOADFONT("Resources\Fonts\youmurdererbb_reg.ttf", 24)
Fnt_Large = _LOADFONT("Resources\Fonts\youmurdererbb_reg.ttf", 52)
Moon = _LOADIMAGE("Resources\Backdrops\Moon.png", 32)
_CLEARCOLOR _RGB32(255, 0, 255), Moon
SUB_State_Start = 1
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB Main_Menu
STATIC FirstRun%, MainMenu AS GDK_Menu, MenuSTR(4) AS STRING * 32
IF FirstRun% = 0 THEN '// Draw the main menu with everything thats static, we store this image for faster rendering next time
FOR i% = 0 TO 250 '// Random stars
PSET (RND * 1024, RND * 768), _RGBA32(240, 240, 240, (RND * 135) + 120)
NEXT
_PUTIMAGE (120, 100)-(360, 320), Moon
_DISPLAY
BCK& = _COPYIMAGE(0)
MenuSTR(0) = "New Game"
MenuSTR(1) = "Load Game"
MenuSTR(2) = "Options"
MenuSTR(3) = "About"
MenuSTR(4) = "Quit"
GDK_Menu_New MainMenu, 512, 250, 5, 0, Fnt_Large, _RGB32(255, 0, 0), _RGB32(0, 0, 255), 5
FirstRun% = 1
ELSE
_PUTIMAGE , BCK&
_FONT Fnt_Title
COLOR _RGB32(240, 20, 30), _RGBA32(0, 0, 0, 0)
_PRINTSTRING (250, 80), "ALL HALLOWS"
GDK_Menu_Update MainMenu
GDK_Menu_Render MainMenu, MenuSTR()
IF GDK_KB(0).ENTER THEN
SELECT CASE MainMenu.Ref
CASE 0 '// new game
GDK_System.Game_State = GDK_ID_Loading '// This method is just for initial dev, ideally we should use the GDK_ID_Loading case
CASE 1 '// Load
CASE 2 '// options
CASE 3 '// about
CASE 4 '// exit
SYSTEM '// for now just exit
END SELECT
END IF
END IF
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB AH_New_Game
STATIC FirstRun%
RESTORE Default_Level
READ TSet$, Level_Data.Num_Col, Level_Data.Num_Row '// get the tileset file, columns and rows for this layer
REDIM Level(Level_Data.Num_Col, Level_Data.Num_Row) AS GDK_Tile
GDK_TileSet_New Level_Data.Tileset, TSet$, 7, 2, _RGB32(0, 255, 0)
GDK_TileMap_Load Level(), Level_Data.Num_Col, Level_Data.Num_Row
GDK_System.Game_State = GDK_ID_Running
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB AH_In_Game
_PUTIMAGE (504, -10)-(624, 90), Moon
GDK_Tile_DrawISO Level_Data.Tileset, Level(), 0, 200, 0, 0, Level_Data.Num_Col, Level_Data.Num_Row
'// To simulate darkness
LINE (0, 0)-(1024, 768), _RGBA32(0, 0, 0, 220), BF '// Ill add a effect i had back in the day to simulate lighting in 2d if we need it....
'// Here wil be a Select case for handling stuff dependant on current actions....
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// BELOW IS GAME ENGINE - DO NOT MODIFY UNLESS YOURE SURE!!! \\\
'///////////////////////////////////////// GDK Basic ////////////////////////////////////////////////////////
SUB GDK_Types
TYPE GDK_Mouse_State
X AS INTEGER
Y AS INTEGER
L AS _BYTE
R AS _BYTE
M AS _BYTE
W AS _BYTE
END TYPE
TYPE GDK_KeyBoard_State
Left AS LONG
Right AS LONG
Down AS LONG
Up AS LONG
CTRL AS LONG
SHIFT AS LONG
ALT AS LONG
SPACE AS LONG
ENTER AS LONG
ESC AS LONG
Num1 AS LONG
Num2 AS LONG
Num3 AS LONG
Num4 AS LONG
Num5 AS LONG
Num6 AS LONG
Num7 AS LONG
Num8 AS LONG
Num9 AS LONG
Num0 AS LONG
PLUS AS LONG
MINUS AS LONG
BACKSPACE AS LONG
TAB AS LONG
A AS LONG
B AS LONG
C AS LONG
D AS LONG
E AS LONG
F AS LONG
G AS LONG
H AS LONG
I AS LONG
J AS LONG
K AS LONG
L AS LONG
M AS LONG
N AS LONG
O AS LONG
P AS LONG
Q AS LONG
R AS LONG
S AS LONG
T AS LONG
U AS LONG
V AS LONG
W AS LONG
X AS LONG
Y AS LONG
Z AS LONG
END TYPE
TYPE GDK_Vector
X AS SINGLE
Y AS SINGLE
END TYPE
TYPE GDK_Sprite
File AS LONG
Width AS INTEGER
Height AS INTEGER
Alpha AS _UNSIGNED LONG
RotationX AS SINGLE
RotationY AS SINGLE
Scale AS SINGLE
IsVisible AS _BYTE
XFrameCount AS _BYTE
YFrameCount AS _BYTE
TotalFrameCount AS INTEGER
FrameWidth AS INTEGER
FrameHeight AS INTEGER
END TYPE
TYPE GDK_Tileset
Sheet AS GDK_Sprite
THeight AS INTEGER
TWidth AS INTEGER
END TYPE
TYPE GDK_Tile '// We can build this out as needed
Tile AS INTEGER
END TYPE
TYPE GDK_Tile_Map
Num_Col AS INTEGER
Num_Row AS INTEGER
Start_Col AS INTEGER
Start_Row AS INTEGER
Vis_Col AS INTEGER
Vis_Row AS INTEGER
Position AS GDK_Vector
Map_Type AS _BYTE '// 0 = normal 1 = ISO
Tileset AS GDK_Tileset '// The tilesheet
END TYPE
TYPE GDK_Animation '// Animation data.
Frame AS INTEGER '// The current frame - When data is loaded/set...this defaults to StartFrame - Is the index in the Frame array
StartFrame AS INTEGER '// 1st frame in sequence
ResetFrame AS INTEGER '// Last frame in sequence
Time AS DOUBLE '// Time between frame changes
Timer AS DOUBLE '// The last animation update
END TYPE
TYPE GDK_Game_Object
Sprite AS GDK_Sprite
Vector AS GDK_Vector
Rotation AS SINGLE
Speed AS SINGLE
'Rect AS GDK_Box
Exists AS _BYTE
Animation AS GDK_Animation
Last_Vector AS GDK_Vector
Action_Point AS GDK_Vector
END TYPE
TYPE GDK_System
Root AS STRING * 64 '// Root directory - all assets should be built relative to this directory \\
Title AS STRING * 32 '// Screen title
Fullscreen AS _BYTE '// GDK_TRUE or GDK_FALSE
XY AS GDK_Vector '// Screen position X, Y (Z unused for screen position)
WH AS GDK_Vector '// Screen width, height (Z unused for screen dimensions)
FPS AS _BYTE '// Max frames per second \\
Screen_Image AS LONG '// Handle for the screen buffer (might be less relevant with pure OpenGL rendering) \\
Game_State AS _BYTE '// GDK_ID_Loading, GDK_ID_Running, GDK_ID_Paused etc \\
GT AS DOUBLE '// Global Timer \\ Updated every loop so all assets use the same time for animation updates \\
Last_GT AS DOUBLE
DT AS DOUBLE '// Delta time
END TYPE
TYPE GDK_Menu
Position AS GDK_Vector
XY_Step AS GDK_Vector '// Movement on x/y each time \\\
Fnt AS LONG
OFF_CLR AS _UNSIGNED LONG
ON_CLR AS _UNSIGNED LONG
Entries AS _UNSIGNED _BYTE
Ref AS _UNSIGNED _BYTE '// Highlighted as its the current one \\ counted from 0
Min_Ref AS _UNSIGNED _BYTE '// First one to be displayed \\
Max_Ref AS _UNSIGNED _BYTE '// Max that can be displayed \\
Alignment AS _BYTE '// 0 is center, -1 is left \\
END TYPE
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// sprite stuff - For universal spaced sprites sheets
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_New (Sprite AS GDK_Sprite, FileSource$, XFrameCount%, YFrameCount%, TotalFrameCount%, Alpha&)
Sprite.File = _LOADIMAGE(FileSource$, 32)
Sprite.Width = _WIDTH(Sprite.File)
Sprite.Height = _HEIGHT(Sprite.File)
Sprite.XFrameCount = XFrameCount%
Sprite.YFrameCount = YFrameCount%
Sprite.TotalFrameCount = TotalFrameCount%
Sprite.Scale = 1
Sprite.IsVisible = -1
Sprite.Alpha = Alpha&
Sprite.FrameWidth = Sprite.Width \ Sprite.XFrameCount
Sprite.FrameHeight = Sprite.Height \ Sprite.YFrameCount
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_SetRotationPoint (Sprite AS GDK_Sprite, X!, Y!)
Sprite.RotationX = X!
Sprite.RotationY = Y!
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_SetRotationAsCenter (Sprite AS GDK_Sprite)
GDK_Sprite_SetRotationPoint Sprite, Sprite.Width / (Sprite.XFrameCount * 2), Sprite.Height / (Sprite.YFrameCount * 2)
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB Rotate_Scale_AroundPoint (X AS LONG, Y AS LONG, Image AS LONG, Rotation AS SINGLE, ScaleX AS SINGLE, ScaleY AS SINGLE, PointX AS LONG, PointY AS LONG) '
DEFSNG A-Z
DIM pX(3) AS SINGLE: DIM pY(3) AS SINGLE
DIM W AS LONG, H AS LONG, I AS LONG, X2 AS LONG, Y2 AS LONG
W = _WIDTH(Image): H = _HEIGHT(Image)
pX(0) = -PointX: pY(0) = -PointY: pX(1) = -PointX: pY(1) = -PointY + H - 1: pX(2) = -PointX + W - 1: pY(2) = -PointY + H - 1: pX(3) = -PointX + W - 1: pY(3) = -PointY 'Set dest screen points
Radians = -Rotation / 57.29578: SINr = SIN(-Radians): COSr = COS(-Radians) 'Precalculate SIN & COS of angle
FOR I = 0 TO 3
pX(I) = pX(I) * ScaleX: pY(I) = pY(I) * ScaleY 'Scale
X2 = pX(I) * COSr + SINr * pY(I): pY(I) = pY(I) * COSr - pX(I) * SINr: pX(I) = X2 'Rotate Dest Points
pX(I) = pX(I) + X: pY(I) = pY(I) + Y 'Translate Dest Points
NEXT
_MAPTRIANGLE (0, 0)-(0, H - 1)-(W - 1, H - 1), Image TO(pX(0), pY(0))-(pX(1), pY(1))-(pX(2), pY(2))
_MAPTRIANGLE (0, 0)-(W - 1, 0)-(W - 1, H - 1), Image TO(pX(0), pY(0))-(pX(3), pY(3))-(pX(2), pY(2))
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_Draw (Sprite AS GDK_Sprite, DestVector AS GDK_Vector, Rotation AS SINGLE, Frame%)
IF Frame% = 0 THEN Frame% = 1
_CLEARCOLOR Sprite.Alpha, Sprite.File
IF Sprite.IsVisible THEN
FrameXStart% = ((INT((Frame% - 1) MOD Sprite.XFrameCount)) * Sprite.FrameWidth)
FrameYStart% = ((INT((Frame% - 1) / Sprite.XFrameCount)) * Sprite.FrameHeight)
TmpImage& = _NEWIMAGE(Sprite.FrameWidth - 1, Sprite.FrameHeight - 1, 32)
_PUTIMAGE (0, 0), Sprite.File, TmpImage&, (FrameXStart%, FrameYStart%)-(FrameXStart% + Sprite.FrameWidth, FrameYStart% + Sprite.FrameHeight)
Rotate_Scale_AroundPoint DestVector.X, DestVector.Y, TmpImage&, -GDK_RadianToDegree(Rotation), Sprite.Scale, Sprite.Scale, Sprite.RotationX, Sprite.RotationY
'Rotate_Scale_Source_Rect DestVector.X, DestVector.Y, Sprite.File, -GDK_RadianToDegree(Rotation), Sprite.Scale, FrameXStart%, FrameYStart%, Sprite.FrameWidth - 1, Sprite.FrameHeight - 1, Sprite.RotationX, Sprite.RotationY
_FREEIMAGE TmpImage&
END IF
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_SetVisibility (Sprite AS GDK_Sprite, OnOff AS _BYTE)
Sprite.IsVisible = OnOff
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Sprite_SetAlpha (Sprite AS GDK_Sprite, Alpha&)
Sprite.Alpha = Alpha&
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_GameObject_New (Handle AS GDK_Game_Object, File$, XframeCount%, YFrameCount%, X%, Y%, Speed!, Rotation!)
GDK_Sprite_New Handle.Sprite, File$, XframeCount%, YFrameCount%, XframeCount% * YFrameCount%, _RGB32(255, 0, 255)
GDK_Vector_New Handle.Vector, X%, Y%
Handle.Rotation = Rotation!
Handle.Speed = Speed
GDK_Sprite_SetVisibility Handle.Sprite, -1
GDK_Sprite_SetAlpha Handle.Sprite, _RGB32(255, 0, 255)
Handle.Exists = GDK_TRUE
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_GameObject_Draw (GameObject AS GDK_Game_Object, AnimationFrame%)
GDK_Sprite_Draw GameObject.Sprite, GameObject.Vector, GameObject.Rotation, AnimationFrame%
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_GameObject_Update (Handle AS GDK_Game_Object)
GDK_Vector_Update Handle.Vector, Handle.Rotation, Handle.Speed
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Vector_New (Vector AS GDK_Vector, X!, Y!)
Vector.X = X!
Vector.Y = Y!
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Vector_Update (Vector AS GDK_Vector, Rot, Speed)
Vector.X = Vector.X + COS(Rot) * Speed
Vector.Y = Vector.Y + SIN(Rot) * Speed
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Simple math functions
FUNCTION GDK_Distance! (X%, Y%, XX%, YY%)
xd% = XX% - X%
yd% = YY% - Y%
GDK_Distance! = SQR((xd% * xd%) + (yd% * yd%))
END FUNCTION
FUNCTION GDK_RadianToDegree! (Radians!)
GDK_RadianToDegree! = Radians! * (180 / _PI)
END FUNCTION
FUNCTION GDK_DegreeToRadian! (Degrees!)
GDK_DegreeToRadian! = Degrees! * (_PI / 180)
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_ANIMATION_NEW (Anim AS GDK_Animation, Frame%, StartFrame%, ResetFrame%, AnimTime#, AnimTimer#)
Anim.Frame = Frame%
Anim.StartFrame = StartFrame%
Anim.ResetFrame = ResetFrame%
Anim.Time = AnimTime#
Anim.Timer = AnimTimer#
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_ANIMATION_UPDATE (Anim AS GDK_Animation)
IF gt# - Anim.Timer >= Anim.Time THEN
IF Anim.Frame = Anim.ResetFrame THEN
Anim.Frame = Anim.StartFrame
ELSE
Anim.Frame = Anim.Frame + 1
END IF
Anim.Timer = gt#
END IF
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'##########################################################################################################################
'// Tile engine
'##########################################################################################################################
SUB GDK_Tile_DrawISO (TileRef AS GDK_Tileset, Level() AS GDK_Tile, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
DIM TmpVect AS GDK_Vector
sx% = _WIDTH(0)
sy% = _HEIGHT(0)
Tx% = X% + (sx% / 2) - (TileRef.TWidth / 2)
Ty% = Y%
YCntr% = 0
FOR j% = YCnt% TO YMax%
FOR i% = XCnt% TO XMax%
TmpVect.X = Tx%
TmpVect.Y = Ty%
IF Tx% < sx% AND Ty% < sy% THEN
IF Level(i%, j%).Tile > 0 THEN
GDK_Sprite_Draw TileRef.Sheet, TmpVect, 0, Level(i%, j%).Tile
END IF
ELSE
EXIT FOR
END IF
Tx% = Tx% + (TileRef.TWidth / 2)
Ty% = Ty% + (TileRef.THeight% / 4)
NEXT
YCntr% = YCntr% + 1
Ty% = Y% + YCntr% * (TileRef.THeight% / 4)
Tx% = X% + ((sx% / 2) - (TileRef.TWidth / 2)) - (YCntr% * (TileRef.TWidth / 2))
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GetColRow (TileRef AS GDK_Tileset, Col%, Row%, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
sx% = _WIDTH(0)
sy% = _HEIGHT(0)
Tx% = X% + (sx% / 2)
Ty% = Y%
YCntr% = 0
FOR j% = YCnt% TO YMax%
FOR i% = XCnt% TO XMax%
IF Tx% < sx% AND Ty% < sy% THEN
IF Mouse.Mx >= Tx% AND Mouse.Mx <= Tx% + TileRef.TWidth THEN
IF Mouse.My >= Ty% AND Mouse.My <= Ty% + TileRef.THeight / 4 THEN
Col% = Tx%
Row% = Ty%
EXIT SUB
END IF
END IF
Tx% = Tx% + (TileRef.TWidth / 2)
Ty% = Ty% + (TileRef.THeight% / 4)
ELSE
EXIT FOR
END IF
NEXT
YCntr% = YCntr% + 1
Ty% = Y% + YCntr% * (TileRef.THeight% / 4)
Tx% = X% + ((sx% / 2) - (TileRef.TWidth / 2)) - (YCntr% * (TileRef.TWidth / 2))
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_TileSet_New (TileRef AS GDK_Tileset, File$, XTiles%, YTiles%, Alpha&)
GDK_Sprite_New TileRef.Sheet, File$, XTiles%, YTiles%, XTiles% * YTiles%, Alpha&
TileRef.TWidth = (TileRef.Sheet.Width \ XTiles%)
TileRef.THeight = (TileRef.Sheet.Height \ YTiles%)
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_TileMap_Load (Level() AS GDK_Tile, XTiles%, YTiles%)
FOR j% = 0 TO YTiles%
FOR i% = 0 TO XTiles%
READ tile%
Level(i%, j%).Tile = tile%
NEXT
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_TileMap_Draw (TileRef AS GDK_Tileset, Level() AS GDK_Tile, X%, Y%, XCnt%, YCnt%, XMax%, YMax%)
Tx% = X%
Ty% = Y%
sx% = _WIDTH(_DEST)
sy% = _HEIGHT(_DEST)
FOR j% = YCnt% TO YMax% - 1
FOR i% = XCnt% TO XMax% - 1
IF Tx% < sx% THEN
IF Level(i%, j%).Tile > 0 THEN
'GDK_Sprite_DrawXY TileRef.Sheet, Tx%, Ty%, 0, Level(i%, j%).Tile
END IF
Tx% = Tx% + (TileRef.TWidth * TileRef.Sheet.Scale)
ELSE
EXIT FOR
END IF
NEXT
Tx% = X%
IF Ty% < sy% THEN Ty% = Ty% + (TileRef.THeight * TileRef.Sheet.Scale) ELSE EXIT FOR
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_TileMap_Load_FromFile (GameFile$, Level() AS GDK_Tile, YTiles%)
X& = FREEFILE
OPEN GameFile$ FOR INPUT AS #X&
FOR i% = 0 TO YTiles% - 1
LINE INPUT #X&, DataLine$
Cnt% = 0
FOR j% = 0 TO LEN(DataLine$)
IF INSTR(j%, DataLine$, ",") > 0 THEN
Level(Cnt%, i%).Tile = VAL(MID$(DataLine$, j%, INSTR(j%, DataLine$, ",") - j%))
j% = INSTR(j%, DataLine$, ",")
Cnt% = Cnt% + 1
ELSE
Level(Cnt%, i%).Tile = VAL(MID$(DataLine$, j%))
END IF
NEXT
NEXT
CLOSE #X&
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Tileset_SetScale (TileRef AS GDK_Tileset, Scale!)
TileRef.Sheet.Scale = Scale!
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// ################################# \\ SYSTEM // ########################################### \\
SUB GDK_System_Update
_LIMIT GDK_System.FPS
_FPS GDK_System.FPS
GDK_System.Last_GT = GDK_System.GT '// store last timer
GDK_KB(1) = GDK_KB(0)
GDK_Mouse(1) = GDK_Mouse(0)
GDK_Mouse_Get_State
GDK_Keyboard_Get_State
GDK_System.GT = TIMER(.001)
GDK_System.DT = GDK_System.GT - GDK_System.Last_GT '// Delta time
END SUB
'///////////////////////////////\\\\\\\\\\/\\\\\\\\\\/////////\///////////////////////////
SUB GDK_System_New (Root$, ScrnW%, ScrnH%, FullScreen%, Title$)
GDK_System.Root = Root$ '// Root Directory
GDK_System.WH.X = ScrnW%
GDK_System.WH.Y = ScrnH%
GDK_System.Title = Title$
GDK_System.Fullscreen = FullScreen%
GDK_System.Screen_Image = _NEWIMAGE(GDK_System.WH.X, GDK_System.WH.Y, 32)
SCREEN GDK_System.Screen_Image
_DELAY 1
IF GDK_System.Fullscreen = GDK_TRUE THEN _FULLSCREEN
CHDIR RTRIM$(LTRIM$(GDK_System.Root)) '// Set the Root directory \\
_TITLE GDK_System.Title
GDK_System.FPS = 60
GDK_System.GT = TIMER(.001)
GDK_System.Last_GT = GDK_System.GT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Keyboard_Get_State
FOR x% = 1 TO 88 'read each key scancode from array
IF x% = 1 THEN GDK_KB(0).ESC = ScanKey%(x%)
IF x% = 2 THEN GDK_KB(0).Num1 = ScanKey%(x%)
IF x% = 3 THEN GDK_KB(0).Num2 = ScanKey%(x%)
IF x% = 4 THEN GDK_KB(0).Num3 = ScanKey%(x%)
IF x% = 5 THEN GDK_KB(0).Num4 = ScanKey%(x%)
IF x% = 6 THEN GDK_KB(0).Num5 = ScanKey%(x%)
IF x% = 7 THEN GDK_KB(0).Num6 = ScanKey%(x%)
IF x% = 8 THEN GDK_KB(0).Num7 = ScanKey%(x%)
IF x% = 9 THEN GDK_KB(0).Num8 = ScanKey%(x%)
IF x% = 10 THEN GDK_KB(0).Num9 = ScanKey%(x%)
IF x% = 11 THEN GDK_KB(0).Num0 = ScanKey%(x%)
IF x% = 12 THEN GDK_KB(0).MINUS = ScanKey%(x%)
IF x% = 13 THEN GDK_KB(0).PLUS = ScanKey%(x%)
IF x% = 14 THEN GDK_KB(0).BACKSPACE = ScanKey%(x%)
IF x% = 15 THEN GDK_KB(0).TAB = ScanKey%(x%)
IF x% = 30 THEN GDK_KB(0).A = ScanKey%(x%)
IF x% = 48 THEN GDK_KB(0).B = ScanKey%(x%)
IF x% = 46 THEN GDK_KB(0).C = ScanKey%(x%)
IF x% = 32 THEN GDK_KB(0).D = ScanKey%(x%)
IF x% = 18 THEN GDK_KB(0).E = ScanKey%(x%)
IF x% = 33 THEN GDK_KB(0).F = ScanKey%(x%)
IF x% = 34 THEN GDK_KB(0).G = ScanKey%(x%)
IF x% = 35 THEN GDK_KB(0).H = ScanKey%(x%)
IF x% = 23 THEN GDK_KB(0).I = ScanKey%(x%)
IF x% = 36 THEN GDK_KB(0).J = ScanKey%(x%)
IF x% = 37 THEN GDK_KB(0).K = ScanKey%(x%)
IF x% = 38 THEN GDK_KB(0).L = ScanKey%(x%)
IF x% = 50 THEN GDK_KB(0).M = ScanKey%(x%)
IF x% = 49 THEN GDK_KB(0).N = ScanKey%(x%)
IF x% = 24 THEN GDK_KB(0).O = ScanKey%(x%)
IF x% = 25 THEN GDK_KB(0).P = ScanKey%(x%)
IF x% = 16 THEN GDK_KB(0).Q = ScanKey%(x%)
IF x% = 19 THEN GDK_KB(0).R = ScanKey%(x%)
IF x% = 31 THEN GDK_KB(0).S = ScanKey%(x%)
IF x% = 20 THEN GDK_KB(0).T = ScanKey%(x%)
IF x% = 22 THEN GDK_KB(0).U = ScanKey%(x%)
IF x% = 47 THEN GDK_KB(0).V = ScanKey%(x%)
IF x% = 17 THEN GDK_KB(0).W = ScanKey%(x%)
IF x% = 45 THEN GDK_KB(0).X = ScanKey%(x%)
IF x% = 21 THEN GDK_KB(0).Y = ScanKey%(x%)
IF x% = 44 THEN GDK_KB(0).Z = ScanKey%(x%)
IF x% = 72 THEN GDK_KB(0).Up = ScanKey%(x%)
IF x% = 75 THEN GDK_KB(0).Left = ScanKey%(x%)
IF x% = 77 THEN GDK_KB(0).Right = ScanKey%(x%)
IF x% = 80 THEN GDK_KB(0).Down = ScanKey%(x%)
IF x% = 28 THEN GDK_KB(0).ENTER = ScanKey%(x%)
IF x% = 57 THEN GDK_KB(0).SPACE = ScanKey%(x%)
IF x% = 29 THEN GDK_KB(0).CTRL = ScanKey%(x%)
IF x% = 56 THEN GDK_KB(0).ALT = ScanKey%(x%)
IF x% = 42 THEN GDK_KB(0).SHIFT = ScanKey%(x%)
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTION ScanKey% (scancode%)
STATIC Ready%, keyflags%() 'retain values on procedure exit
IF NOT Ready% THEN REDIM keyflags%(0 TO 127): Ready% = -1 'create array on first use
i% = INP(&H60) 'read keyboard states
IF (i% AND 128) THEN keyflags%(i% XOR 128) = 0
IF (i% AND 128) = 0 THEN keyflags%(i%) = -1
K$ = INKEY$ 'clears key buffer to prevent beeps
ScanKey% = keyflags%(scancode%)
IF scancode% = 0 THEN Ready% = 0 'allows program to reset all values to 0 with a REDIM
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Mouse_Get_State
DO: LOOP WHILE _MOUSEINPUT
GDK_Mouse(0).X = _MOUSEX
GDK_Mouse(0).Y = _MOUSEY
GDK_Mouse(0).L = _MOUSEBUTTON(1)
GDK_Mouse(0).R = _MOUSEBUTTON(2)
GDK_Mouse(0).M = _MOUSEBUTTON(3)
GDK_Mouse(0).W = _MOUSEWHEEL
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Menu_New (Menu AS GDK_Menu, x%, y%, Entries~%%, Alignment%%, Fnt&, Clr_On~&, Clr_Off~&, Max~%%)
Menu.Position.X = x%
Menu.Position.Y = y%
Menu.Entries = Entries~%%
Menu.Alignment = Alignment%%
Menu.Ref = 0
Menu.Min_Ref = 0
Menu.Max_Ref = Max~%%
Menu.OFF_CLR = Clr_Off~&
Menu.ON_CLR = Clr_On~&
Menu.Fnt = Fnt&
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Need to add mouse to this - I have it working somewhere but need to merge in to GDK
SUB GDK_Menu_Update (Menu AS GDK_Menu)
IF GDK_KB(0).Up AND NOT GDK_KB(1).Up THEN
IF Menu.Ref > 0 THEN Menu.Ref = Menu.Ref - 1 ELSE Menu.Ref = Menu.Entries - 1
IF Menu.Ref < Menu.Min_Ref THEN Menu.Min_Ref = Menu.Min_Ref - 1
ELSEIF GDK_KB(0).Down AND NOT GDK_KB(1).Down THEN
IF Menu.Ref < Menu.Entries - 1 THEN Menu.Ref = Menu.Ref + 1 ELSE Menu.Ref = 0
IF Menu.Ref > Menu.Min_Ref + Menu.Max_Ref THEN
IF Menu.Min_Ref + Menu.Max_Ref < Menu.Entries - 1 THEN Menu.Min_Ref = Menu.Min_Ref + 1
END IF
END IF
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_Menu_Render (Menu AS GDK_Menu, Strings() AS STRING * 32)
_FONT Menu.Fnt
y% = Menu.Position.Y
FOR Mnu% = Menu.Min_Ref TO Menu.Min_Ref + Menu.Max_Ref - 1
IF Mnu% = Menu.Ref THEN
COLOR Menu.ON_CLR, _RGBA32(0, 0, 0, 0)
ELSE
COLOR Menu.OFF_CLR, _RGBA32(0, 0, 0, 0)
END IF
IF Menu.Alignment = 0 THEN
_PRINTSTRING (Menu.Position.X - (_PRINTWIDTH(LTRIM$(RTRIM$(Strings(Mnu%)))) / 2), y%), Strings(Mnu%)
ELSEIF Menu.Alignment = -1 THEN
_PRINTSTRING (Menu.Position.X, y%), Strings(Mnu%)
ELSEIF Menu.Alignment = 1 THEN
END IF
y% = y% + _FONTHEIGHT(Menu.Fnt) + 4
NEXT
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Unseen


