Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Space Invaders knock off to show simple collisions
#1
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...

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


Attached Files
.7z   Tutorials.7z (Size: 2.98 KB / Downloads: 44)
Reply


Messages In This Thread
Space Invaders knock off to show simple collisions - by Unseen Machine - 09-08-2025, 08:10 PM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Tiny Space Invaders bplus 15 1,610 09-11-2025, 04:39 PM
Last Post: Pete
  Rectangle Collisions Demo using SAT Unseen Machine 10 1,168 09-08-2025, 07:12 PM
Last Post: Pete
  Simple finance tracker program Delsus 0 516 06-15-2025, 08:02 AM
Last Post: Delsus
  Simple Numbers Magic Trick With MessageBox SierraKen 0 489 05-12-2025, 09:45 PM
Last Post: SierraKen
  Space Pongy bplus 3 827 11-29-2024, 11:18 PM
Last Post: SierraKen

Forum Jump:


Users browsing this thread: 1 Guest(s)