09-08-2025, 08:10 PM
Im nearly done with pixel perfect but its a little headache so in the meantime...here's a simple demo on how using reduced collision rectangles can give an approximated result...
Unseen
Code: (Select All)
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Unseen's Game Dev Tutorials pt.1 - Collisions \\
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
CONST GDK_Vector_Size = 8, GDK_TRUE = -1, GDK_FALSE = 0
'///////////////////////////////////// System Initialisation ////////////////////////////////////////////////
CHDIR "Tutorials\" '// The root path for the files we will use
SCREEN _NEWIMAGE(800, 600, 32)
_SCREENMOVE 0, 0
_DELAY 1
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Game objects - All sprites in GDK (and in general should be right orientated as 0 debrees rotation)
DIM Ship AS GDK_Game_Object, Bullet(19) AS GDK_Game_Object, Max_Bullets&, Enemy(39) AS GDK_Game_Object, EnemyAnim AS GDK_Animation
Max_Bullets& = 20
'// Now we load the game objects (sprites)
GDK_GameObject_New Ship, "Hunter_Red.png", 1, 1, 400, 530, 0, 2 * ATN(1)
GDK_Sprite_SetRotationAsCenter Ship.Sprite
Ship.Sprite.Scale = .8
'// This is NOT the way to do it, ideally you only use one instance of the bullet image and the enemy image but for now...this works
ex% = 60: ey% = 80
FOR i% = 0 TO 39
GDK_GameObject_New Enemy(i%), "Invader.png", 4, 1, ex%, ey%, 0, 0
GDK_Sprite_SetRotationAsCenter Enemy(i%).Sprite
IF (i% + 1) MOD 10 = 0 THEN
ey% = ey% + 90
ex% = 60
ELSE
ex% = ex% + 60
END IF
NEXT
'// The enemy is animated so we make a singular animation variable to handle it
GDK_ANIMATION_NEW EnemyAnim, 1, 1, 4, .1, 0
FOR i% = 0 TO Max_Bullets& - 1
GDK_GameObject_New Bullet(i%), "Bullet_Blue.png", 1, 1, 0, 0, 0, 0
Bullet(i%).Exists = GDK_FALSE '// Reset default auto existance
GDK_Sprite_SetRotationAsCenter Bullet(i%).Sprite
NEXT
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Control and movement limits
DIM Enemy_Left AS _BYTE, Enemy_Move AS _BYTE
DIM Shoot_Time AS DOUBLE, Shoot_Timer AS DOUBLE
DIM Player_MinX AS INTEGER, Player_MaxX AS INTEGER
Shoot_Time = .33 '// Fire 3 bullets every one second
Player_MinX = 40 '// X axis limits
Player_MaxX = 760
'// Intersection box for pixel perfect collisions
DIM ISecBox AS GDK_Box
PRINT "Unseen machines little collisions demo..."
PRINT "Space = Shoot, Left/Right arrows move ship."
_DISPLAY
_DELAY 2
'//////////////////////////////////////// Main Loop ////////////////////////////////////////////////////////////
DO
CLS
_LIMIT 60
'// Logic
GDK_ANIMATION_UPDATE EnemyAnim '// Enemy animation update
'// Bullets movement and collisions checks - destroy bullets when they leave the screen
FOR i% = 0 TO Max_Bullets& - 1
IF Bullet(i%).Exists THEN
GDK_Vector_Update Bullet(i%).Vector, Bullet(i%).Rotation, Bullet(i%).Speed
IF Bullet(i%).Vector.Y < 0 THEN
Bullet(i%).Exists = GDK_FALSE '// off screen so destroy
ELSE '// check for enemy collisions
FOR j% = 0 TO 39
IF Enemy(j%).Exists = GDK_TRUE THEN
Enemy(j%).Sprite.Scale = .8 '// This will reduce the collision box to 80%
IF GDK_CheckCollision(Bullet(i%), Enemy(j%)) THEN '// Bullet has hit an enemy
Bullet(i%).Exists = GDK_FALSE
Enemy(j%).Exists = GDK_FALSE
'IF GDK_GetIntersectionAABB(Bullet(i%).Rect, Enemy(j%).Rect, ISecBox) THEN
'// actual coordiantes for the collision are are now stored in isecbox? Steve to do his magic with that!
'// This will be for pixel perfect collisions that analyse exact positions of pixels in an image and also account for scaling
'END IF
EXIT FOR
END IF
Enemy(j%).Sprite.Scale = 1 '// Restore the scale for rendering
END IF
NEXT
END IF
END IF
NEXT
'// Enemy movement
IF Enemy_Left = GDK_TRUE THEN
IF Enemy_Move > 0 THEN Enemy_Move = Enemy_Move - 1 ELSE Enemy_Left = GDK_FALSE
ELSE
IF Enemy_Move < 120 THEN Enemy_Move = Enemy_Move + 1 ELSE Enemy_Left = GDK_TRUE
END IF
FOR i% = 0 TO 39
IF Enemy_Left = GDK_TRUE THEN Enemy(i%).Vector.X = Enemy(i%).Vector.X - 1 ELSE Enemy(i%).Vector.X = Enemy(i%).Vector.X + 1
NEXT
'// INPUT
'// Space bar shoots
IF _KEYDOWN(32) THEN
IF TIMER(.001) - Shoot_Timer >= Shoot_Time THEN
FOR i% = 0 TO Max_Bullets& - 1
IF NOT Bullet(i%).Exists THEN
Bullet(i%).Exists = GDK_TRUE
GDK_Vector_New Bullet(i%).Vector, Ship.Vector.X, Ship.Vector.Y
Bullet(i%).Speed = 5
Bullet(i%).Rotation = 6 * ATN(1)
EXIT FOR
END IF
NEXT
Shoot_Timer = TIMER(.001)
END IF
END IF
'// Ship left and right movement
IF _KEYDOWN(19200) THEN '// left
IF Ship.Vector.X > Player_MinX THEN Ship.Vector.X = Ship.Vector.X - 1
ELSEIF _KEYDOWN(19712) THEN '// right
IF Ship.Vector.X < Player_MaxX THEN Ship.Vector.X = Ship.Vector.X + 1
END IF
'// Render
'// Enemy
FOR i% = 0 TO 39
IF Enemy(i%).Exists = GDK_TRUE THEN GDK_GameObject_Draw Enemy(i%), EnemyAnim.Frame
NEXT
'// Bullets
FOR i% = 0 TO Max_Bullets& - 1
IF Bullet(i%).Exists THEN GDK_GameObject_Draw Bullet(i%), 1
NEXT
'// Player
GDK_GameObject_Draw Ship, 1
_DISPLAY
LOOP UNTIL INKEY$ = CHR$(27)
SYSTEM
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// THIS IS ALL FROM A VERY OLD GDK as such is only for demostration purposes
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
TYPE GDK_Vector
X AS SINGLE
Y AS SINGLE
END TYPE
TYPE GDK_Box
Position AS GDK_Vector
WidthHeight AS GDK_Vector
Rotation AS SINGLE
RotationPointOffset AS GDK_Vector
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_Game_Object
Sprite AS GDK_Sprite
Vector AS GDK_Vector
Rotation AS SINGLE
Speed AS SINGLE
Rect AS GDK_Box
Exists AS _BYTE
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_Collision_Area
Num_Pixels AS LONG
Pixel_Data AS _MEM '//
END TYPE
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_DrawBox (Box AS GDK_Box, bcolor AS LONG)
DIM Corners(3) AS GDK_Vector
CALL GDK_GetBoxCorners(Box, Corners())
LINE (Corners(0).X, Corners(0).Y)-(Corners(1).X, Corners(1).Y), bcolor
LINE (Corners(1).X, Corners(1).Y)-(Corners(2).X, Corners(2).Y), bcolor
LINE (Corners(2).X, Corners(2).Y)-(Corners(3).X, Corners(3).Y), bcolor
LINE (Corners(3).X, Corners(3).Y)-(Corners(0).X, Corners(0).Y), bcolor
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_RotatePoint (Result AS GDK_Vector, p AS GDK_Vector, pivot AS GDK_Vector, angle AS SINGLE)
DIM temp_x AS SINGLE, temp_y AS SINGLE
temp_x = p.X - pivot.X
temp_y = p.Y - pivot.Y
Result.X = temp_x * COS(angle) - temp_y * SIN(angle)
Result.Y = temp_x * SIN(angle) + temp_y * COS(angle)
Result.X = Result.X + pivot.X
Result.Y = Result.Y + pivot.Y
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB GDK_GetBoxCorners (Box AS GDK_Box, Corners() AS GDK_Vector)
DIM HalfW AS SINGLE, HalfH AS SINGLE
DIM UnrotatedCorner AS GDK_Vector
DIM Center AS GDK_Vector
HalfW = Box.WidthHeight.X / 2
HalfH = Box.WidthHeight.Y / 2
Center = Box.Position
UnrotatedCorner.X = Center.X - HalfW
UnrotatedCorner.Y = Center.Y - HalfH
CALL GDK_RotatePoint(Corners(0), UnrotatedCorner, Center, Box.Rotation)
UnrotatedCorner.X = Center.X + HalfW
UnrotatedCorner.Y = Center.Y - HalfH
CALL GDK_RotatePoint(Corners(1), UnrotatedCorner, Center, Box.Rotation)
UnrotatedCorner.X = Center.X + HalfW
UnrotatedCorner.Y = Center.Y + HalfH
CALL GDK_RotatePoint(Corners(2), UnrotatedCorner, Center, Box.Rotation)
UnrotatedCorner.X = Center.X - HalfW
UnrotatedCorner.Y = Center.Y + HalfH
CALL GDK_RotatePoint(Corners(3), UnrotatedCorner, Center, Box.Rotation)
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTION GDK_Overlap_On_Axis (Corners1() AS GDK_Vector, Corners2() AS GDK_Vector, Axis AS GDK_Vector)
DIM Min1 AS SINGLE, Max1 AS SINGLE, Min2 AS SINGLE, Max2 AS SINGLE
DIM Projection AS SINGLE, I AS LONG
Min1 = 9999999!: Max1 = -9999999!
Min2 = 9999999!: Max2 = -9999999!
FOR I = 0 TO 3
Projection = Corners1(I).X * Axis.X + Corners1(I).Y * Axis.Y
IF Projection < Min1 THEN Min1 = Projection
IF Projection > Max1 THEN Max1 = Projection
NEXT I
FOR I = 0 TO 3
Projection = Corners2(I).X * Axis.X + Corners2(I).Y * Axis.Y
IF Projection < Min2 THEN Min2 = Projection
IF Projection > Max2 THEN Max2 = Projection
NEXT I
IF Max1 >= Min2 AND Max2 >= Min1 THEN GDK_Overlap_On_Axis = -1 ELSE GDK_Overlap_On_Axis = 0
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// SAT Function
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTION GDK_Box_Intersect (Box1 AS GDK_Box, Box2 AS GDK_Box)
DIM Box1_Corners(3) AS GDK_Vector, Box2_Corners(3) AS GDK_Vector
DIM Axis(3) AS GDK_Vector, length AS SINGLE, I AS LONG
CALL GDK_GetBoxCorners(Box1, Box1_Corners())
CALL GDK_GetBoxCorners(Box2, Box2_Corners())
Axis(0).X = -(Box1_Corners(1).Y - Box1_Corners(0).Y): Axis(0).Y = Box1_Corners(1).X - Box1_Corners(0).X
Axis(1).X = -(Box1_Corners(0).Y - Box1_Corners(3).Y): Axis(1).Y = Box1_Corners(0).X - Box1_Corners(3).X
FOR I = 0 TO 1
length = SQR(Axis(I).X * Axis(I).X + Axis(I).Y * Axis(I).Y)
IF length > 0 THEN Axis(I).X = Axis(I).X / length: Axis(I).Y = Axis(I).Y / length
IF NOT GDK_Overlap_On_Axis(Box1_Corners(), Box2_Corners(), Axis(I)) THEN GDK_Box_Intersect = 0: EXIT FUNCTION
NEXT I
Axis(2).X = -(Box2_Corners(1).Y - Box2_Corners(0).Y): Axis(2).Y = Box2_Corners(1).X - Box2_Corners(0).X
Axis(3).X = -(Box2_Corners(0).Y - Box2_Corners(3).Y): Axis(3).Y = Box2_Corners(0).X - Box2_Corners(3).X
FOR I = 2 TO 3
length = SQR(Axis(I).X * Axis(I).X + Axis(I).Y * Axis(I).Y)
IF length > 0 THEN Axis(I).X = Axis(I).X / length: Axis(I).Y = Axis(I).Y / length
IF NOT GDK_Overlap_On_Axis(Box1_Corners(), Box2_Corners(), Axis(I)) THEN GDK_Box_Intersect = 0: EXIT FUNCTION
NEXT I
'// Temp to draw collision boxes
GDK_DrawBox Box1, _RGB32(255, 0, 0)
GDK_DrawBox Box2, _RGB32(255, 0, 0)
GDK_Box_Intersect = -1
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Simple 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
_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 / (4 * ATN(1)))
END FUNCTION
FUNCTION GDK_DegreeToRadian! (Degrees!)
GDK_DegreeToRadian! = Degrees! * ((4 * ATN(1)) / 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 TIMER(.001) - 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 = TIMER(.001)
END IF
END SUB
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTION GDK_CheckCollision (object1 AS GDK_Game_Object, object2 AS GDK_Game_Object)
DIM box1 AS GDK_Box
DIM box2 AS GDK_Box
' Create the bounding box data for object1 using its Rect and Sprite
box1.Position.X = object1.Vector.X
box1.Position.Y = object1.Vector.Y
box1.WidthHeight.X = object1.Sprite.FrameWidth * (object1.Sprite.Scale)
box1.WidthHeight.Y = object1.Sprite.FrameHeight * (object1.Sprite.Scale)
box1.Rotation = object1.Rotation
box1.RotationPointOffset.X = object1.Rect.RotationPointOffset.X * (object1.Sprite.Scale)
box1.RotationPointOffset.Y = object1.Rect.RotationPointOffset.Y * (object1.Sprite.Scale)
' Create the bounding box data for object2 using its Rect and Sprite
box2.Position.X = object2.Vector.X
box2.Position.Y = object2.Vector.Y
box2.WidthHeight.X = object2.Sprite.FrameWidth * (object2.Sprite.Scale)
box2.WidthHeight.Y = object2.Sprite.FrameHeight * (object2.Sprite.Scale)
box2.Rotation = object2.Rotation
box2.RotationPointOffset.X = object2.Rect.RotationPointOffset.X * (object2.Sprite.Scale)
box2.RotationPointOffset.Y = object2.Rect.RotationPointOffset.Y * (object2.Sprite.Scale)
' Check for collision using the GDK_Box_Intersect function
' NOTE: Your GDK_Box_Intersect must support rotated boxes for this to work correctly.
IF GDK_Box_Intersect(box1, box2) THEN GDK_CheckCollision = GDK_TRUE
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
FUNCTION GDK_GetIntersectionAABB (box1 AS GDK_Box, box2 AS GDK_Box, intersection AS GDK_Box)
DIM box1_corners(3) AS GDK_Vector, box2_corners(3) AS GDK_Vector
DIM minX AS SINGLE, maxX AS SINGLE, minY AS SINGLE, maxY AS SINGLE
DIM i AS INTEGER
CALL GDK_GetBoxCorners(box1, box1_corners())
CALL GDK_GetBoxCorners(box2, box2_corners())
' Find the AABB of the first box
minX = box1_corners(0).X: maxX = box1_corners(0).X
minY = box1_corners(0).Y: maxY = box1_corners(0).Y
FOR i = 1 TO 3
IF box1_corners(i).X < minX THEN minX = box1_corners(i).X
IF box1_corners(i).X > maxX THEN maxX = box1_corners(i).X
IF box1_corners(i).Y < minY THEN minY = box1_corners(i).Y
IF box1_corners(i).Y > maxY THEN maxY = box1_corners(i).Y
NEXT i
DIM box1_minX AS SINGLE, box1_maxX AS SINGLE, box1_minY AS SINGLE, box1_maxY AS SINGLE
box1_minX = minX: box1_maxX = maxX: box1_minY = minY: box1_maxY = maxY
' Find the AABB of the second box
minX = box2_corners(0).X: maxX = box2_corners(0).X
minY = box2_corners(0).Y: maxY = box2_corners(0).Y
FOR i = 1 TO 3
IF box2_corners(i).X < minX THEN minX = box2_corners(i).X
IF box2_corners(i).X > maxX THEN maxX = box2_corners(i).X
IF box2_corners(i).Y < minY THEN minY = box2_corners(i).Y
IF box2_corners(i).Y > maxY THEN maxY = box2_corners(i).Y
NEXT i
DIM box2_minX AS SINGLE, box2_maxX AS SINGLE, box2_minY AS SINGLE, box2_maxY AS SINGLE
box2_minX = minX: box2_maxX = maxX: box2_minY = minY: box2_maxY = maxY
' Calculate the intersection AABB
intersection.Position.X = _MAX(box1_minX, box2_minX)
intersection.Position.Y = _MAX(box1_minY, box2_minY)
intersection.WidthHeight.X = _MIN(box1_maxX, box2_maxX) - intersection.Position.X
intersection.WidthHeight.Y = _MIN(box1_maxY, box2_maxY) - intersection.Position.Y
IF intersection.WidthHeight.X > 0 AND intersection.WidthHeight.Y > 0 THEN
GDK_GetIntersectionAABB = -1 ' Returns true if there is an intersection
ELSE
GDK_GetIntersectionAABB = 0 ' Returns false otherwise
END IF
END FUNCTION
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Unseen

