Try this code. Sorry about the confusion.
// Project: 3DPool
// Created: 2015-12-29
// set window properties
SetWindowTitle( "3DPool" ) : SetClearColor( 0, 0, 0 )
Type tBalls
X#
Z#
Obj
Img
EndType
Dim Balls[ 15 ] as tBalls
Baize = LoadImage( "./textures/baize.png" )
Create3DPhysicsWorld()
Set3DPhysicsGravity( 0.0, -10.0, 0.0 )
Table = CreateObjectPlane( 25.0, 16.5 )
SetObjectPosition( Table, 0.0, 0.0, 0.0 )
SetObjectImage( Table, Baize, 0 )
SetObjectRotation( Table, 90.0, 0.0, 0.0 )
Create3DPhysicsStaticBody( Table )
X# = 4.0
CreateBall( -6.0, 0.0, "./textures/00.png" )
CreateBall( X#, 0.0, "./textures/09.png" )
X# = X# + 0.9
CreateBall( X#, 0.5, "./textures/02.png" )
CreateBall( X#, -0.5, "./textures/15.png" )
X# = X# + 0.9
CreateBall( X#, 1.0, "./textures/03.png" )
CreateBall( X#, 0.0, "./textures/08.png" )
CreateBall( X#, -1.0, "./textures/04.png" )
X# = X# + 0.9
CreateBall( X#, 1.5, "./textures/07.png" )
CreateBall( X#, 0.5, "./textures/01.png" )
CreateBall( X#, -0.5, "./textures/13.png" )
CreateBall( X#, -1.5, "./textures/10.png" )
X# = X# + 0.9
CreateBall( X#, 2.0, "./textures/05.png" )
CreateBall( X#, 1.0, "./textures/11.png" )
CreateBall( X#, 0.0, "./textures/14.png" )
CreateBall( X#, -1.0, "./textures/06.png" )
CreateBall( X#, -2.0, "./textures/12.png" )
ResetBalls( -1 )
SetCameraPosition( 1, 0.0, 21.0, 0.0 )
SetCameraLookAt( 1, 0.0, 0.0, 0.0, 0.0 )
Repeat
BallScreenX# = GetScreenXFrom3D( GetObjectX( Balls[ 0 ].Obj ), 0.0, GetObjectZ( Balls[ 0 ].Obj ) )
BallScreenY# = GetScreenYFrom3D( GetObjectX( Balls[ 0 ].Obj ), 0.0, GetObjectZ( Balls[ 0 ].Obj ) )
If GetPointerState() = 0 And Abs( Strength# ) > 1.0
XVec# = 1.0 * Sin( Ang# )
ZVec# = 1.0 * Cos( Ang# )
SetObject3DPhysicsCanSleep( Balls[ 0 ].Obj,0 )
SetObject3DPhysicsLinearVelocity( Balls[ 0 ].Obj, XVec#, 0.0, ZVec#, Strength# * 5.0 )
Strength# = 0.0
SetObject3DPhysicsCanSleep( Balls[ 0 ].Obj, 1 )
EndIf
If GetPointerState() = 1
Strength# = GetDist#( BallScreenX#, BallScreenY#, GetPointerX(), GetPointerY() )
Ang# = ATanFull( GetPointerX() - BallScreenX#, GetPointerY() - BallScreenY# )
EndIf
For Id = 0 to 15
BallY# = GetObjectY( Balls[ Id ].Obj )
Alpha# = ( ( 10.0 - BallY# ) / 10.0 ) * 255.0
SetObjectColor( Balls[ Id ].Obj, Alpha#, Alpha#, Alpha#, Alpha# )
//If BallY# < -10 Then ResetBalls( Id )
Next Id
If GetRawKeyPressed( 32 ) Then ResetBalls( -1 ) ` Spacebar
Sync2D( 0 )
Step3DPhysicsWorld()
Sync3D()
Sync2D( 1 )
Until GetRawKeyPressed( 27 )
End
`===============================================================================================
`===============================================================================================
`===============================================================================================
Function ResetBalls( Id )
StartId = 0
EndId = 15
//Remarked these lines to stop crash array out of bounds
//If Id -1
//StartId = Id
//EndId = Id
//EndIf
For Id = StartId To EndId
Delete3DPhysicsBody( Balls[ Id ].Obj )
SetObjectPosition( Balls[ Id ].Obj, Balls[ Id ].X#, 10.0, Balls[ Id ].Z# )
SetObjectRotation( Balls[ Id ].Obj, 90.0, 0.0, 0.0 )
SetObjectTransparency( Balls[ Id ].Obj, 1 )
Create3DPhysicsDynamicBody( Balls[ Id ].Obj )
SetObjectShapeSphere( Balls[ Id ].Obj )
SetObject3DPhysicsRestitution( Balls[ Id ].Obj, 0.4 )
Next Id
EndFunction
`===============================================================================================
`===============================================================================================
`===============================================================================================
Function CreateBall( X#, Z#, Texture$ )
SphereObj = CreateObjectSphere( 10.0, 14, 32 )
SetObjectPosition( SphereObj, X#, 0.5, Z# )
Img = LoadImage( Texture$ )
SetObjectImage( SphereObj, Img, 0 )
SetObjectScale( SphereObj, 0.1, 0.1, 0.1 )
//Fixed these 2 lines caused crash object did not exist
//SetObjectRotation( Balls[ Id ].Obj, 90.0, 0.0, 0.0 )
//SetObjectTransparency( Balls[ Id ].Obj, 1 )
SetObjectRotation( SphereObj, 90.0, 0.0, 0.0 )
SetObjectTransparency( SphereObj, 1 )
Id = Val( Mid( Texture$, 12, 2 ) )
Balls[ Id ].X# = X#
Balls[ Id ].Z# = Z#
Balls[ Id ].Obj = SphereObj
Balls[ Id ].Img = Img
EndFunction SphereObj
`===============================================================================================
`===============================================================================================
`Insanity Engine function which manually updates all 2D onto the screen.
`===============================================================================================
Function Sync2D( Stage )
If Stage = 0
Update2D( GetFrameTime() )
Render2DBack()
Else
Render2DFront()
Swap()
EndIf
EndFunction
`===============================================================================================
`===============================================================================================
`Insanity Engine function which manually updates all 3D onto the screen.
`===============================================================================================
Function Sync3D()
Update3D( GetFrameTime() )
Render3D()
EndFunction
`===============================================================================================
`===============================================================================================
`===============================================================================================
Function GetDist#( X1#, Y1#, X2#, Y2# )
Dist_X# = X1# - X2#
Dist_Y# = Y1# - Y2#
Distance# = Sqrt( Dist_X# * Dist_X# + Dist_Y# * Dist_Y# )
EndFunction Distance#
When I originally wrote the velocity commands I was waking the object from sleep mode before applying the force.
I had forgot that I changed it to allow the user more control. In the code above I wake up the Q ball before applying the velocity.
You do not need to wake up the other balls as they will automatically become active once the moving Q ball gets close enough.
The coffee is lovely dark and deep,and I have code to write before I sleep.