 Computer Science Canada Programming C, C++, Java, PHP, Ruby, Turing, VB   Username:   Password: Wiki Blog Search Turing Chat Room Members
POOL tutorial including Realistic Angels        Author Message
thoughtful  Posted: Sun Jan 18, 2004 4:05 pm   Post subject: POOL tutorial including Realistic Angels

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                                                             *                     ******************************************************************************************/             collangle := arctand ((balls_y (i) - white_y) / ((balls_x (i) - white_x))) %get angle                         nX := cosd (collangle) %x vector             nY := sind (collangle) %y vector             a2 := balls_xsp (i) * nX + balls_ysp (i) * nY%figure out reultant velcoities             a1 := white_xsp * nX + white_ysp * nY  %resultants             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                                         collangle := arctand ((balls_y (k) - balls_y (i)) / ((balls_x (k) - balls_x (i))))                                         nX := cosd (collangle)                     nY := sind (collangle)                     a1 := balls_xsp (i) * nX + balls_ysp (i) * nY                     a2 := balls_xsp (k) * nX + balls_ysp (k) * nY                     optimisedP := (2.0 * (a1 - a2)) / (mass + mass)                     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     for i : 1 .. totalballs %draws the balls         drawfilloval (round (balls_x (i)), round (balls_y (i)), ballradius, ballradius, i)         drawfilloval (round (balls_x (i)), round (balls_y (i)), ballradius - 4, ballradius - 4, white)         drawoval (round (balls_x (i)), round (balls_y (i)), ballradius, ballradius, black)         Font.Draw (intstr (i), round (balls_x (i)) - 2, round (balls_y (i)) - 2, font, 7)     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       drawfilloval (round (white_x), round (white_y), ballradius, ballradius, white)     drawoval (round (white_x), round (white_y), ballradius, ballradius, black)   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   Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First         Page 1 of 1  [ 1 Posts ]
 Jump to:  Select a forum  CompSci.ca ------------ - Network News - General Discussion     General Forums   -----------------   - Hello World   - Featured Poll   - Contests     Contest Forums   -----------------   - DWITE   - [FP] Contest 2006/2008   - [FP] 2005/2006 Archive   - [FP] 2004/2005 Archive   - Off Topic     Lounges   ---------   - User Lounge   - VIP Lounge     Programming -------------- - General Programming     General Programming Forums   --------------------------------   - Functional Programming   - Logical Programming   - C     C   --   - C Help   - C Tutorials   - C Submissions   - C++     C++   ----   - C++ Help   - C++ Tutorials   - C++ Submissions   - Java     Java   -----   - Java Help   - Java Tutorials   - Java Submissions   - Ruby     Ruby   -----   - Ruby Help   - Ruby Tutorials   - Ruby Submissions   - Turing     Turing   --------   - Turing Help   - Turing Tutorials   - Turing Submissions   - PHP     PHP   ----   - PHP Help   - PHP Tutorials   - PHP Submissions   - Python     Python   --------   - Python Help   - Python Tutorials   - Python Submissions   - Visual Basic and Other Basics     VB   ---   - Visual Basic Help   - Visual Basic Tutorials   - Visual Basic Submissions     Education ----------- - Student Life   Graphics and Design ----------------------- - Web Design     Web Design Forums   ---------------------   - (X)HTML Help   - (X)HTML Tutorials   - Flash MX Help   - Flash MX Tutorials   - Graphics     Graphics Forums   ------------------   - Photoshop Tutorials   - The Showroom   - 2D Graphics   - 3D Graphics     Teams ------ - dTeam Public

 Style: Appalachia blueSilver eMJay subAppalachia subBlue subCanvas subEmjay subGrey subSilver subVereor Search: