Posted: Fri Jan 23, 2004 8:16 pm Post subject: Tutorial: Basic POOL and realistic collision
Okay here is my long promised tutorial
I have seen a lot of reference to poor tonys tutorial, which has some bugs. That turotial was meant to be a base information, he said in his post that he did not spend all the time figuring all the trig out. So give him a break . BTW my tutorial was inspired by somewhat same principle and then i added some stuff.
The tutorial is not just on collision but it actually provieds a base package for n e pool game, with a lot of room to expand. I actually took out a old version of my ISP and had to delete some stuff to make it so it doesnt give the whole solution. The collision algorithm is very good, but it might have some problem, such as the balls sticking together, now that i want u to figure on your own (my ISP has an advanced version of the same algorith with no problems ).
Also you can change the values of the constants to increase ball size, decay, highest speed, lowest speed or number of balls e.t.c.
And also i will like to thank tony and catalyst who at the start helped me understand how the realistic collision works.
code:
% by Abdullah Ramay a.k.a Thoughtful
% some variables may not be used in this tutorial becuase this is taken from my game that i am making for my ISP
%click on the white ball and drag to take a shot
var white_x : real% positions
var white_y : real
var white_xsp : real%velocities
var white_ysp : real
var x, y, but : int
var sunk_x, sunk_y : int
const totalballs := 3 %change this to change number of balls
var balls_x : array 1 .. totalballs of real%positions
var balls_y : array 1 .. totalballs of real
var balls_xsp : array 1 .. totalballs of real%velocities
var balls_ysp : array 1 .. totalballs of real
var balls_check : array 1 .. totalballs of int
var font : int := Font.New ("verdana:5:bold")
var font2 : int := Font.New ("verdana:5")
var distance : real
var xsp_temp1, ysp_temp1, xsp_temp2, ysp_temp2 : real
var movedist1, movedist2, collangle, mass, a1, a2, nX, nY, optimisedP : real
const decay := 75 %inversely poportional to stopping, bigger decay= longer moving ball
const lowbar := 50
const ballradius := 8 %radius of the ball, try 18 for monster ball ;=)
const lowestspeed := .01%lowest possible speed
const highestspeed := 10 %highest possible speed
const ballcollidedistance := ballradius * 2 %how far does the ball has to be before it collides
const pocketcollidedistance := 20
var cuecolor : int := white
setscreen ("title:Thoughtful's Pool")
setscreen ("offscreenonly")
View.Set ("graphics:600;350")
sunk_x := 20
sunk_y := 20
mass := 1
for i : 1 .. totalballs %initialises starting positions
balls_x (i) := Rand.Int (20 + lowbar, (maxx - 20)) + Rand.Real
balls_y (i) := Rand.Int (20, (maxy - 20)) + Rand.Real
balls_xsp (i) := 0
balls_ysp (i) := 0
balls_check (i) := 1
end for
% ignore these , jus some initial setup values
white_x := (maxx div 2)
white_y := (maxy div 2) + (lowbar / 2)
white_xsp := 0
white_ysp := 0
proc drawfield %draws the field
drawfillbox (0, 0, maxx, maxy, brown)
drawfillbox (10, 10 + lowbar, maxx - 10, maxy - 10, white)
drawfillbox (20, 20 + lowbar, maxx - 20, maxy - 20, green)
end drawfield
%collision of white ball to balls
proc white_collide
for i : 1 .. totalballs
distance := ((balls_x (i) - white_x) * (balls_x (i) - white_x) + (balls_y (i) - white_y) * (balls_y (i) - white_y)) ** 0.5
if distance < ballcollidedistance then
% this the part which controls the ball to ball collision
/******************************************************************************************
* the collision part is below *
******************************************************************************************/
optimisedP := (2.0 * (a1 - a2)) / (mass + mass) %you can have different masses, i am using same masses for all balls
balls_xsp (i) := balls_xsp (i) + (optimisedP * mass * nX) %finally initialises the x and y velocoities to the balls
balls_ysp (i) := balls_ysp (i) + (optimisedP * mass * nY)
white_xsp := white_xsp - (optimisedP * mass * nX)
white_ysp := white_ysp - (optimisedP * mass * nY)
/******************************************************************************************
* the collision part ends *
******************************************************************************************/
end if
end for
end white_collide
%collision of balls to balls
proc balls_collide
for i : 1 .. totalballs
for k : i .. totalballs
if k not= i then
distance := (((balls_x (i) - balls_x (k)) * (balls_x (i) - balls_x (k))) + ((balls_y (i) - balls_y (k)) * (balls_y (i) - balls_y (k)))) ** 0.5
if distance < ballcollidedistance then
balls_xsp (i) := balls_xsp (i) - (optimisedP * mass * nX)
balls_ysp (i) := balls_ysp (i) - (optimisedP * mass * nY)
balls_xsp (k) := balls_xsp (k) + (optimisedP * mass * nX)
balls_ysp (k) := balls_ysp (k) + (optimisedP * mass * nY)
% moves the balls forward a step so they dont get stuck with each other( but the balls will still stick)
balls_x (i) += balls_xsp (i)
balls_y (i) += balls_ysp (i)
balls_x (k) += balls_xsp (k)
balls_y (k) += balls_ysp (k)
end if
end if
end for
end for
end balls_collide
% controls the motion& collision with the side bars, also decays the speed so it slows
proc balls_mov
for i : 1 .. totalballs
if balls_check (i) not= 0 then
balls_x (i) += balls_xsp (i)
balls_y (i) += balls_ysp (i)
if balls_x (i) < (20 + ballradius) then
balls_x (i) := 20 + ballradius
balls_xsp (i) := - (balls_xsp (i))
end if
if balls_x (i) > (maxx - (20 + ballradius)) then
balls_x (i) := maxx - (20 + ballradius)
balls_xsp (i) := - (balls_xsp (i))
end if
if balls_y (i) < (20 + ballradius) + lowbar then
balls_y (i) := (20 + ballradius) + lowbar
balls_ysp (i) := - (balls_ysp (i))
end if
if balls_y (i) > (maxy - (20 + ballradius)) then
balls_y (i) := maxy - (20 + ballradius)
balls_ysp (i) := - (balls_ysp (i))
end if
if balls_xsp (i) > 0 then
balls_xsp (i) := balls_xsp (i) - (balls_xsp (i) / decay)
end if
if balls_ysp (i) > 0 then
balls_ysp (i) := balls_ysp (i) - (balls_ysp (i) / decay)
end if
if balls_xsp (i) < 0 then
balls_xsp (i) := balls_xsp (i) + (- (balls_xsp (i) / decay))
end if
if balls_ysp (i) < 0 then
balls_ysp (i) := balls_ysp (i) + (- (balls_ysp (i) / decay))
end if
if balls_ysp (i) > - (lowestspeed) and balls_ysp (i) < (lowestspeed) then
balls_ysp (i) := 0
end if
if balls_xsp (i) > - (lowestspeed) and balls_xsp (i) < (lowestspeed) then
balls_xsp (i) := 0
end if
end if
end for
end balls_mov
proc whiteball_mov %controls the moving of the white ball
white_x += white_xsp
white_y += white_ysp
Mouse.Where (x, y, but)
% bouncing of the wall
if white_x < (20 + ballradius) then
white_x := 20 + ballradius
white_xsp := - (white_xsp)
end if
if white_x > (maxx - (20 + ballradius)) then
white_x := maxx - (20 + ballradius)
white_xsp := - (white_xsp)
end if
if white_y < (20 + ballradius) + lowbar then
white_y := (20 + ballradius) + lowbar
white_ysp := - (white_ysp)
end if
if white_y > (maxy - (20 + ballradius)) then
white_y := maxy - (20 + ballradius)
white_ysp := - (white_ysp)
end if
% decays the ball
if white_xsp > 0 then
white_xsp := white_xsp - (white_xsp / decay)
end if
if white_ysp > 0 then
white_ysp := white_ysp - (white_ysp / decay)
end if
if white_xsp < 0 then
white_xsp := white_xsp + (- (white_xsp / decay))
end if
if white_ysp < 0 then
white_ysp := white_ysp + (- (white_ysp / decay))
end if
% makes the ball stop
if white_ysp > - (lowestspeed) and white_ysp < (lowestspeed) then
white_ysp := 0
end if
if white_xsp > - (lowestspeed) and white_xsp < (lowestspeed) then
white_xsp := 0
end if
end whiteball_mov
proc poolcue
if (x > white_x - 5) and x < (white_x + ballradius) and (y > white_y - ballradius) and y < (white_y + ballradius) and but = 1 then
white_xsp := 0
white_ysp := 0
loop
drawfield
Mouse.Where (x, y, but) %gets
exit when but = 0
drawfilloval (round (white_x), round (white_y), ballradius, ballradius, white)
drawoval (round (white_x), round (white_y), ballradius, ballradius, black)
balls_mov
Draw.Line (round (white_x), round (white_y), x, y, cuecolor)
delay (10)% take this away if the game runs too slowly, my computer is a 2.6 Ghz so doesnt amtters to me :)
View.Update
cls
end loop
white_xsp := (white_x - x) / 15 % gets the power from cue for the shot
white_ysp := (white_y - y) / 15
if white_xsp > highestspeed then % sees if the power is according to the highest speed e.t.c
white_xsp := highestspeed
elsif white_xsp < -highestspeed then
white_xsp := -highestspeed
end if
if white_ysp > highestspeed then
white_ysp := highestspeed
elsif white_ysp < -highestspeed then
white_ysp := -highestspeed
end if
end if
end poolcue
% main loop, i always like procedure, very easy to add rules and stuff to the game, my final isp just uses a single procedure for all rules
loop
drawfield
white_collide
balls_collide
whiteball_mov
balls_mov
if but = 1 then
poolcue
end if
View.Update
cls
end loop
i hope u liked it, if you did let me know by replying
Sponsor Sponsor
TheXploder
Posted: Fri Jan 23, 2004 8:25 pm Post subject: (No subject)
wow, amazing!!
I think it speeds up a bit too fast, and slows almost abruptly, I think it should roll a bit more. But hey +10 bits good job, maybe some mods can give you more, hint, hint, , ...
thoughtful
Posted: Fri Jan 23, 2004 8:29 pm Post subject: (No subject)
thanks a lot, though as i said i left some error in their..otherwise it wont be any fun..all the guys would have the same pool game...so you can improve this and put in rules e.t.c, the version i made actually jsut had a procedure for everything and was very easy to add/ remove stuff(specially rules for 8-ball,9-ball,e.t.c).
The slowing down and speed you can adjust with the constants.
AsianSensation
Posted: Fri Jan 23, 2004 8:31 pm Post subject: (No subject)
very very nice. This is a great program. It also has that kinda of polished look to it. Here, have some bits, you deserve it.
+50 bits
Tony
Posted: Fri Jan 23, 2004 8:58 pm Post subject: (No subject)
awesome 8) I'm going to link to this from my old tutorial
+50Bits
Posted: Fri Jan 23, 2004 9:06 pm Post subject: (No subject)
wow thats amazing!! GREAT work!!!
Cervantes
Posted: Sat Jan 24, 2004 1:32 pm Post subject: (No subject)
hmmm.. I wonder if there's a way to use this kind of collision style in Slime Volleyball
ballspx and ballspy is so much easier than ballangle and velocity and weight and all
thoughtful
Posted: Sat Jan 24, 2004 5:13 pm Post subject: (No subject)
yes..you can, jsut use a decay for the y speed, so tht it goes downwards if you thinking off a side view volley ball.
If its top view ti should be rpetty simple
Sponsor Sponsor
Cervantes
Posted: Sat Jan 24, 2004 5:54 pm Post subject: (No subject)
hhmmm.. I shall try to impliment that...
I'm almost done making a game like the space game that turing comes with.. will post it here in a bit.
Kuntzy
Posted: Mon Jan 26, 2004 7:27 pm Post subject: (No subject)
Great tutorial! +bits, it helped me out a lot, I get your code, only when I run the pool oi made base off of yours, my veloities seem to ammplify when balls collide with eachother.
jonos
Posted: Mon Jan 26, 2004 7:54 pm Post subject: (No subject)
where do all you guys learn this. do you get the basics from compsci class then just learn it on your own. im trying to learn on my own cause my compsci grade 10 class was useless, but ahhhhhhh it takes so long.
Tony
Posted: Mon Jan 26, 2004 8:40 pm Post subject: (No subject)
yeah, preaty much. Just pick up syntax from compsci class and pick a challange for yourself. You'll learn a great deal while trying to achieve it.
btw - pool involves trig and physics, so that might be a bit above gr10 level
Posted: Mon Jan 26, 2004 8:42 pm Post subject: (No subject)
ok, should i take trig and physics in grade 11 and stuff like that or will i learn that in compsci 11 and 12
Tony
Posted: Mon Jan 26, 2004 8:45 pm Post subject: (No subject)
you learn trig in grade10/11 math. And you should defenatly take physics 11 if you're into making games. You dont learn that in CS... heck, you dont learn anything in CS. Just "if" statements
Posted: Tue Jan 27, 2004 11:18 am Post subject: (No subject)
long live the if statements!!
we learn trig (or start learning it) in gr 10 math, (im only in gr 10 now, and have math next semester)
you also learn some physics in gr10 science, but not enough to do much in turing... for compsci it just helps you understand the physics in other ppls games