Pool Example
And here's a pool sim with media and balls getting pocketed. Its pretty well commented as well, Im thinking now that Ill write a tutorial on how to make a complete pool game from start to finish. "My First Pool Game"
, eat your heart out Chris K. (Joking)
Here's the code;
SYNC ON:SYNC RATE 0:AUTOCAM OFF:COLOR BACKDROP RGB(255,255,255):INK RGB(000,000,000),RGB(000,000,000)
`Randomize the Rand Seed to the current Time
RANDOMIZE TIMER()
`Set the cam's starting position
POSITION CAMERA 0,200,-500
`Using a loop going from 10 to 25, load in the pool ball object, rotate
`it randomly, set it up for Sparky's dll into group 1, and then move it forward
`to give it a unique position other than 0,0,0
FOR X = 1 TO 16
LOAD OBJECT "Media/PoolBall.X",X
YROTATE OBJECT X,RND(360)
SC_setupObject X,1,0
MOVE OBJECT X,10
LOAD IMAGE "Media/Ball"+STR$(X)+".bmp",X
TEXTURE OBJECT X,X
SET SHADOW SHADING ON X
NEXT X
`Find the pool ball model's x size and divide it by 2, this will
`be our radius for the collision system.
Rad# = OBJECT SIZE X(1)/2
`Load in the pool table model, move it down so that the pool balls will sit ontop of it
`(this just moves it down by half of the pool ball's size, logically that means that
`the pool ball will sit right ontop of the table surface. Though this also depends
`on the table model, when I modelled it I made sure the surface of the table is at 0,0,0
`for this to work.)
`After the tables oriented, set it up into group 1 for Sparkys dll.
LOAD OBJECT "Media/PoolTable.X",999
MOVE OBJECT DOWN 999,OBJECT SIZE X(1)/2
SC_setupObject 999,1,0
`Finally, load in the pockets model. This is how we figure out if a pool ball has gone into a pocket.
`Basically this model is 6 plains, 1 plain at each pocket of the table. In the collision code, we check
`to see if any ball hits this pocket model, if it does we move the ball down and stop checking for collision
`with the pocketed ball. We also set this model up into group 1 for Sparky's dll,
`and then we hide it since we dont want to see the 6 plains.
`Take out the HIDE OBJECT 2 part to see the plains.
LOAD OBJECT "Media/Pockets.X",1000
SC_setupObject 1000,1,0
`Orient the main light
HIDE OBJECT 1000
POSITION LIGHT 0,-100,500,0
`Main loop.
DO
`Use a for/next loop to go through each pool ball.
FOR X = 1 TO 16
`This checks if the current Ball's collision status is set to 1. Later on in the program, when we
`detect that a ball collides with the pocket object, we'll set the balls's collision status to 0,
`making it ignore/skip the movement and collision code for that ball.
IF SC_CollisionStatus(X) = 1
`This should look similar, basically storing the needed variables for the
`collision and then moving each ball forward .1 units.
OX# = OBJECT POSITION X(X)
OY# = OBJECT POSITION Y(X)
OZ# = OBJECT POSITION Z(X)
MOVE OBJECT X,1
X# = OBJECT POSITION X(X)
Y# = OBJECT POSITION Y(X)
Z# = OBJECT POSITION Z(X)
`We update the current ball after it's moved since this program will not only bounce each ball
`off of the pool table's walls, it'll also bounce each ball off of every other ball. In order for that
`to work, Sparky's dll requires that any object's setup for collision that move need to be Updated after
`the move.
SC_UpdateObject X
`And finally we call the function. It's got 2 new parameters added to it since the first
`code snippet demonstrating basic sliding collision. The first new one is the Exlude param,
`this tells Sparky's dll to skip checking collision for whatever object we put into
`this parameter. This is only useful since we're using group collision, if we switched to
`non-group collision it wouldn't apply.
`The second new param is the Pocket parameter, this is the object we're using for
`pocket collision, right now since we loaded the pocket model into object 2 in
`the beginning, we're using 2 here.
PoolCollision(OX#,OY#,OZ#,X#,Y#,Z#,Rad#,X,1,X,1000)
ENDIF
NEXT X
`Just some basic camera stuff. It shouldnt be too hard to understand, try running through
`what it does in your head;
`First it points the camera to coordinate 0,0,0.
`Then it turns it right 90 degrees, moves it forward .5 units, and then turns it left 90 degrees.
`This is a simple way to simulate camera straffing, since there's no MOVE CAMERA LEFT command.
`When this code runs through, it'll make the camera circle around point 0,0,0. Earlier on we positioned the
`camera at 3d coordinates 0,200,-500. So the camera will circle around the pool table 200 units above, and -500
`units backwards, from the table.
POINT CAMERA 0,0,0
TURN CAMERA RIGHT 90
MOVE CAMERA 1
TURN CAMERA LEFT 90
TEXT 0,0,"FPS: "+STR$(SCREEN FPS())
`Refresh the screen.
SYNC
LOOP
FUNCTION PoolCollision(X1#,Y1#,Z1#,X2#,Y2#,Z2#,Radius#,Dyn,Group,Exclude,Pocket)
`X1#-Z1# : The starting XYZ position of the intersection ray
`X2#-Z2# : The ending XYZ position of the intersection ray
`Radius# : The radius of the sliding collision sphere, usually you'd set this
` to the player's object's z sixe divided by 2. Our cube is 20 units thick,
` so we use 10 in the example.
`Dyn : The player object
`Obj : The map object that we want the player object to slide on
`Call the sc_SphereSlide command, using our variables.
`This command will create a mathematical intersection "Ray",
`this basically means that it'll make a 3D line starting from X1#,Y1#,Z1#,
`and ending at X2#,Y2#,Z2#. It'll then check if any of the polygons on the
`map object are inbetween these 2 points, if there is then it'll return a 1,
`if not, it'll return 0.
`What Sparky has done for us however is added in a few handy functions
`that are carried out inside of the SphereSlide command. Basically,
`once it detects an intersection, it'll get the angle the intersection
`occured at and using trigonometry (sin, cos and tan), it'll determine
`the logical position for an object to be if it were to "slide" along
`the polygon it hit. To make the system even more accurate however,
`Sparky's dll goes one step further by doing another intersection check on the
`new mathematical coordinates it just obtained, and checks that there wont be
`a collision there either. `It'll keep doing this until it reaches it's max
`iteration or until it finds a free, empty 3d location where the player's object
`can go. All this for free, sheesh!
C = SC_SphereSlideGroup(Group,X1#,Y1#,Z1#,X2#,Y2#,Z2#,Radius#,Exclude)
`If C > 0 then an intersection must have occured.
IF C > 0
`Sparky's dll returns the object collided with when using the SC_SphereSlideGroup command.
`We put this object number in C.
`This checks of the object the ball collided with is equal to Pocket, we defined Pocket
`as 2 when we called the function earlier in the main loop, so basically
`this checks if the current ball being checked hit the pocket object.
IF C = Pocket
`If the current ball DID hit the pocket object, first it sets the ball's collision status to 0, making
`it disregard any collision checking or movement anymore in the game.
SC_setObjectCollisionOff Dyn
`After that, we move the ball down, I just used 30 units here as a guess, just to show that the
`ball fell in the pocket.
MOVE OBJECT DOWN Dyn,20
ELSE
`Now we obtain the position of the intersection using sc_getStaticCollisionX(), and
`then we get the bounce vector of the collision. Then, position the dynamic object at
`the collision position and point it to the position of collison + the bounce vector,
`and we get realistic bouncing! ;)
NewX# = sc_getStaticCollisionX()
NewY# = sc_getStaticCollisionY()
NewZ# = sc_getStaticCollisionZ()
NormX# = sc_getCollisionBounceX()
NormY# = sc_getCollisionBounceY()
NormZ# = sc_getCollisionBounceZ()
POSITION OBJECT Dyn,NewX#,0,NewZ#
POINT OBJECT Dyn,NewX#+NormX#,0,NewZ#+NormZ#
`The last bit of code is the code for making each ball bounce off of every other ball.
`It isnt too complicated, it checks if the object the current ball hit is between 10 and 25.
`If it is then the ball must have it another ball, since objects 10 to 25 are our balls.
`Now, the code above this will automatically bounce the current ball off of anything the current
`ball hits, even if it hits another ball. However, we need to bounce the ball hit in a direction as well,
`the angle we bounce the ball hit at is the opposite of the angle of the current ball.
`So, we rotate the ball that was hit to the current ball's y angle, then we turn it 180 degrees.
`This makes the ball ricochet in the opposite direction.
IF C >= 10 AND C <= 25
YROTATE OBJECT C,OBJECT ANGLE Y(Dyn)
TURN OBJECT RIGHT C,180
ENDIF
ENDIF
ENDIF
ENDFUNCTION
`And the delete memblock code that we need for Sparky's to work.
DELETE MEMBLOCK 1
In the attatched zip file is:
- DBP/DBA File
- Textures for every pool ball + Uv map if you want to change them
- Pool table and ball model
- Exe
Your signature has been erased by a mod because it's larger than 600x120...