Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 Tutorial: Basic POOL and realistic collision
Index -> Programming, Turing -> Turing Tutorials
Goto page 1, 2  Next
View previous topic Printable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
thoughtful




PostPosted: 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 Very Happy . 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 Razz ).

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
Sponsor
sponsor
TheXploder




PostPosted: Fri Jan 23, 2004 8:25 pm   Post subject: (No subject)

wow, amazing!! Very Happy
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, Wink , Wink...
thoughtful




PostPosted: 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




PostPosted: 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




PostPosted: 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
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
Cervantes




PostPosted: Fri Jan 23, 2004 9:06 pm   Post subject: (No subject)

wow thats amazing!! GREAT work!!!
Cervantes




PostPosted: 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 Smile

ballspx and ballspy is so much easier than ballangle and velocity and weight and all Confused
thoughtful




PostPosted: 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
Sponsor
sponsor
Cervantes




PostPosted: 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




PostPosted: 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. Crying or Very sad
jonos




PostPosted: 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




PostPosted: 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 Confused
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
jonos




PostPosted: 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




PostPosted: 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 Laughing
Latest from compsci.ca/blog: Tony's programming blog. DWITE - a programming contest.
Cervantes




PostPosted: Tue Jan 27, 2004 11:18 am   Post subject: (No subject)

long live the if statements!! Smile

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 Smile
Display posts from previous:   
   Index -> Programming, Turing -> Turing Tutorials
View previous topic Tell A FriendPrintable versionDownload TopicRate TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 2  [ 28 Posts ]
Goto page 1, 2  Next
Jump to:   


Style:  
Search: