i hope this helps get you started:
// Project: Carrom
// Created: 2020-11-14
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "Carrom" )
SetWindowSize( 1080, 720, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1080, 720 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 ) // since version 2.0.22 we can use nicer default fonts
SetPhysicsScale(0.1)
SetPhysicsGravity(0,0)
GLOBAL Board as Integer
Board = CreateSprite(0) : SetSpriteSize(Board, 480,480) : SetSpritePositionByOffset(Board, 540,360) : SetSpriteVisible(Board,0)
SetSpritePhysicsOn(Board,1)
SetSpritePhysicsFriction(Board, 0.01)
SetSpritePhysicsRestitution(Board,0.5)
SetSpriteShapeChain( Board, 4, 0, 0, -240,-240, 0 )
SetSpriteShapeChain( Board, 4, 1, 0, 240,-240, 0 )
SetSpriteShapeChain( Board, 4, 2, 0, 240, 240, 0 )
SetSpriteShapeChain( Board, 4, 3, 1, -240, 240, 0 )
GLOBAL Pockets as Integer []
ThisPocket = CreateSprite(0) : SetSpriteSize(ThisPocket, 20.0,20.0) : SetSpriteShapeCircle(ThisPocket, 0,0, 10.0)
SetSpritePositionByOffset(ThisPocket, 540-225, 360-225) : Pockets.Insert(ThisPocket)
ThisPocket = CloneSprite(ThisPocket) : SetSpritePositionByOffset(ThisPocket, 540+225, 360-225) : Pockets.Insert(ThisPocket)
ThisPocket = CloneSprite(ThisPocket) : SetSpritePositionByOffset(ThisPocket, 540+225, 360+225) : Pockets.Insert(ThisPocket)
ThisPocket = CloneSprite(ThisPocket) : SetSpritePositionByOffset(ThisPocket, 540-225, 360+225) : Pockets.Insert(ThisPocket)
GLOBAL Men as Integer []
For x = 1 to 10
ThisMan = CreateSprite(0) : SetSpriteSize(ThisMan,16,16) : SetSpriteShapeCircle(ThisMan, 0,0,8)
SetSpritePhysicsOn(ThisMan,2) : SetSpritePhysicsCanRotate(ThisMan,0) : SetSpritePhysicsDamping(ThisMan,0.5) : SetSpritePhysicsFriction(ThisMan, 0.02)
PlaceMan(ThisMan) : Men.Insert(ThisMan)
Next x
GLOBAL Striker as Integer
GLOBAL Threshhold# as Float : Threshhold# = 3.0
SetPhysicsDebugOn()
MaxPower# = 200.0
Red = MakeColor(255,0,0)
do
If AllStopped() = 1
If GetPointerState() = 1
StartX# = GetPointerX() : StartY# = GetPointerY()
Power# = 0.0
If StrikerValid(StartX#, StartY#) = 1
Repeat
MX# = GetPointerX() : MY# = GetPointerY()
If Power# < MaxPower# then Power# = Power# + 2.0
DrawLine(StartX#,StartY#,MX#,MY#, Red, Red)
Angle# = ATanFull(StartX#-MX#, StartY#-MY#)
Print(STR(Angle#) + " @ " + STR(Power#) )
Sync()
Until GetPointerState() = 0
SetSpritePhysicsVelocity(Striker, SIN(Angle#)*Power#*20.0, -COS(Angle#)*Power#*20.0 )
Else
EndIf
EndIf
Else
For x = 0 to Men.Length `for each man
ThisMan = Men[x]
ThisX# = GetSpriteXByOffset(ThisMan) : ThisY# = GetSpriteYByOffset(ThisMan)
for y = 0 to 3 `check each pocket
ThisPocket = Pockets[y]
If GetSpriteHitTest(ThisPocket,ThisX#,ThisY#)
PlaceMan(ThisMan)
SetSpritePhysicsVelocity(ThisMan,0.0,0.0)
Endif
Next y
Next x
Endif
Print( AllStopped() )
Print (Power#)
Sync()
loop
Function AllStopped()
Stopped = 1
//CheckStriker
If GetSpriteExists(Striker)
ThisVX# = ABS(GetSpritePhysicsVelocityX(Striker)) : ThisVY# = ABS(GetSpritePhysicsVelocityY(Striker))
If ThisVX# < Threshhold# and ThisVY# < Threshhold#
SetSpritePhysicsVelocity(Striker,0.0,0.0)
Else
Stopped = 0
ExitFunction Stopped
Endif
Endif
//Check Men
For x = 0 to Men.Length
ThisMan = Men[x]
ThisVX# = ABS(GetSpritePhysicsVelocityX(ThisMan)) : ThisVY# = ABS(GetSpritePhysicsVelocityY(ThisMan))
`Print( STR(ThisVX#,1) + "|" + STR(ThisVY#,1) )
If ThisVX# < Threshhold# and ThisVY# < Threshhold# then SetSpritePhysicsVelocity(ThisMan,0.0,0.0)
If ThisVX# > 0.0 or ThisVY# > 0.0
Stopped = 0
ExitFunction Stopped
Endif
Next x
EndFunction Stopped
Function PlaceMan(ThisMan)
TotalMen = Men.Length
Placed = 0
ThisX# = Random(340,740) : ThisY# = Random(160,560)
SetSpritePositionByOffset(ThisMan, ThisX#, ThisY#)
Repeat
TotalHits = 0
For x = 0 to TotalMen
ThatMan = Men[x]
If ThisMan <> ThatMan
If GetSpriteCollision(ThisMan, ThatMan) = 1 then INC TotalHits
Endif
Next x
If TotalHits = 0
Placed = 1
Else
ThisX# = Random(340,740) : ThisY# = Random(160,560)
SetSpritePositionByOffset(ThisMan, ThisX#, ThisY#)
Endif
Until Placed = 1 or TotalMen = 0
EndFunction
Function StrikerValid(X#,Y#)
TotalHits = 0
If GetSpriteExists(Striker) then DeleteSprite(Striker)
Striker = CreateSprite(0) : SetSpriteSize(Striker,24.0,24.0) : SetSpriteShapeCircle(Striker,0,0,12.0)
SetSpritePositionByOffset(Striker, X#,Y#)
TotalHits = TotalHits + CheckPockets(Striker)
TotalHits = TotalHits + CheckMen(Striker)
If TotalHits > 0
Result = 0
DeleteSprite(Striker)
Else
Result = 1
SetSpritePhysicsOn(Striker,2) : SetSpritePhysicsCanRotate(Striker,0) : SetSpritePhysicsDamping(Striker,0.5)
Endif
EndFunction Result
Function CheckPockets(ThisSpr)
InPocket = 0
For x = 0 to 3
InPocket = InPocket + GetSpriteCollision(ThisSpr, Pockets[x])
If InPocket = 1 then Exit
Next x
EndFunction InPocket
Function CheckMen(ThisMan)
HitMen = 0
TotalMen = Men.Length
If TotalMen > 0
for x = 0 to TotalMen
ThatMan = Men[x]
HitMen = HitMen + GetSpriteCollision(ThisMan, ThatMan)
next x
Endif
If HitMen > 0 then Result = 1 else Result = 0
EndFunction Result
not my best work, and i was going to add more like checks to make sure the striker was on the table before shooting, apply rules, etc, but i gotta leave something for you, right?
there's a lot of trial and error when playing with box2d. if i was going to do this seriously, i would pull real-world characteristics into it and scale everything correctly, for starters. IE, board @ 74cm, men @ 3cm, etc. that's what i'd suggest you do. then play with friction, dampening, restitution, etc., and remember, if you're going to manually set Mass, do it after all other manual adjustments.
good luck!
oh, some controls/instructions might be helpful (incase its not obvious in the code):
you can't place the striker while men are moving. there's a check in there to make sure you're not colliding with men when you attempt to place the striker.
once placed, hold the pointer down to increase power and drag to determine angle. release to, well,
strike (my first time looking at
Carrom so i don't know ALL the terms (yet))