Computer Science Canada

[Tutorial] Collision Detection

Author:  Dan [ Tue Sep 24, 2002 3:06 pm ]
Post subject:  [Tutorial] Collision Detection

Collision Detection

Ok I am show you how to use a common method of collision detection which is some times called rectangle collision detection. What it dose is uses if statements to make a theoretical rectangles arrowed the objects and then dose some tings if the rectangles hit.

Well here is an example of how to do this. This example uses two ovals which we wont to bounce off everything. (sorry for the bad spelling if I get time I will spell check it Embarassed )


code:

var x, y : int %var for the 1st ovals quadents
var x2, y2 : int %var for the 2nd ovals quadents
var nx, ny, nx2, ny2 : int := 1 %vars for the chage in qroadents
var s : int := 10 %var for the size of the ovals

x := Rand.Int (10, 100) %set the x quadent for the 1st oval
y := Rand.Int (10, 100) %set the y quadent for the 1st oval
x2 := Rand.Int (10, 100) %set the x quadent for the 2nd oval
y2 := Rand.Int (10, 100) %set the y quadent for the 2nd oval

%main loop
loop
    Draw.Oval (x, y, s, s, red) %draws the 1st oval
    Draw.Oval (x2, y2, s, s, green) %draws the 2nd one

    %check to see if oval gose off the screen
    %for oval 1
   
    if x <= 0 then %check to see if it gose off the bottom
        nx := 1 %chages the direction
    elsif y <= 0 then %check to see if it gose off to the left
        ny := 1 %chages the direction
    end if

    if x >= maxx then %check to see if it gose off the top
        nx := - 1 %chages the direction
    elsif y >= maxy then %check to see if it gose off to the right
        ny := - 1 %chages the direction
    end if


    %check to see if oval gose off the screen
    %for oval 2
   
    if x2 <= 0 then %check to see if it gose off the bottom
        nx2 := 1 %chages the direction
    elsif y2 <= 0 then %check to see if it gose off to the left
        ny2 := 1 %chages the direction
    end if

    if x2 >= maxx then %check to see if it gose off the top
        nx2 := - 1 %chages the direction
    elsif y2 >= maxy then %check to see if it gose off to the right
        ny2 := - 1 %chages the direction
    end if



    %this if checks to see if the ovals have hit each other
    if x + s > x2 - s and x - s < x2 + s and y + s > y2 - s and y - s < y2 +
            s then
       
        put "the balls hit"
        delay (500)

        %chages the direction of all the ovals
        nx := nx * - 1
        ny := ny * - 1
        nx2 := nx2 * - 1
        ny2 := ny2 * - 1
   
    end if

    %this part adds the chage in qroadents to the
    %quradents and makes the ovals move
    x += nx
    y += ny
    x2 += nx2
    y2 += ny2

    delay (10)
    cls
end loop


Also i think tony has some stuff to add to this about other methods of doing this.

P.S. if there is anything you dont understand (or cant read becuse of my spelling) plz feal free to post and let us know. Wink

Author:  Tony [ Wed Sep 25, 2002 12:28 pm ]
Post subject: 

[tutorial] Oval Collision Detection

Well Dan explained how to use rectangle collision Detection... sord off...

Anyway, that is good enough for some cases, but in sertain games oval detection might prove better. Especially if you deal with circles Wink

The idea behind it is to find the distance between the centers of the circles and see if its less then sum of radiuses. If so, they have collided.

To make a collision Detection function, you need to know pythagorian theorem (C^2 = A^2 + B^2)

Here's how you use it:

code:

distance = ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))**0.5
%you take the square of differences of X coordinates and add
%a square of differences of Y coordinates then take a square
%root of the sum
%%%%%%
%I did (x)*(x) instead of x**2 because exponents is a function
%and it takes up more resourses then *, thus its faster
%Also **0.5 is the same as sqrt() - learn your math guys

if distance < radious1 + radious2
%might be a good idea to save radious1+radious2 as const/var
then
collision = true
end if


I hope this little tutorial helped. If something is still unclear, or you want to know how to do other types of detections, please post.

Author:  R.W.Z [ Fri Oct 04, 2002 5:05 pm ]
Post subject:  Try This

This would be a good tutorial but I didn't label much but this is almost the same thing as the other one but with this you can change the number of bouncing balls by changing BALLCOUNT but only the first two balls say if they collided with each other.

code:
const BALLCOUNT : int := 2
var ballX : array 1 .. BALLCOUNT of int
var ballY : array 1 .. BALLCOUNT of int
var directionX : array 1 .. BALLCOUNT of int
var directionY : array 1 .. BALLCOUNT of int

const RADIUS : int := 20

% Set random values for the x and y of each ball also the
% x and y direction for each ball
for i : 1 .. BALLCOUNT
    randint (ballX (i), RADIUS * 2, maxx - RADIUS * 2)
    randint (ballY (i), RADIUS * 2, maxy - RADIUS * 2)
    loop
        randint (directionX (i), -3, 3)
        randint (directionY (i), -3, 3)
        exit when directionX (i) not= 0 and directionY (i) not= 0
    end loop
end for

loop
    for i : 1 .. BALLCOUNT
        drawfilloval (ballX (i), ballY (i), RADIUS, RADIUS, 0)
        ballX (i) := ballX (i) + directionX (i)
        ballY (i) := ballY (i) + directionY (i)
        if ballX (i) < RADIUS or ballX (i) > maxx - RADIUS then
            directionX (i) := -directionX (i)
        end if
        if ballY (i) < RADIUS or ballY (i) > maxy - RADIUS then
            directionY (i) := -directionY (i)
        end if
        drawfilloval (ballX (i), ballY (i), RADIUS, RADIUS, 12)
    end for
    if ballX (1) + RADIUS > ballX (2) - RADIUS and ballX (1) - RADIUS < ballX (2) + RADIUS and ballY (1) + RADIUS > ballY (2) - RADIUS and ballY (1) - RADIUS < ballY (2) + RADIUS then
        locatexy (maxx div 2, maxy div 2)
        put "Balls Hit"
        delay(100)
        cls
    end if
    delay (10)
end loop


R.W.Z
Martin was here. Use code tags

Author:  JayLo [ Tue Nov 26, 2002 11:46 pm ]
Post subject:  for the rectangle collision...

I'm trying out a pool program... thanks for the rectangle collision program... However, I would like to make the collision more realistic as in a "real" pool bounce... I tried out the oval collision, but it seems as if the program only tells when it hits! I would like to find out if the balls can realistically bounce off each other in a real way. Please post any sort of help.

Author:  Tony [ Wed Nov 27, 2002 12:35 am ]
Post subject: 

ya, you can do that... you need to apply some physics and trig for it though... you should have no problem with grade11 knowledge of math and physics.

I will shortly post a new tutorial on this topic. Check out tutorial section for [trig]

Author:  void [ Mon Apr 07, 2003 8:00 pm ]
Post subject:  collison detection

when i click on a certain spot i want it to check if there is something within a certain radius of the point, say i click on (x,y)...i want to check if there is something within a 40 pixel radius of the spot Confused ...any ideas are welcome....can u try to explain it to me because i dont wanna just see code and copy it (im lazy Embarassed so if its there, i'll copy it Twisted Evil ), if you hafta tho ..i dont mind... Very Happy thanks alot.....this site is really helpful...and its a good oppurtunity for me to test my own skills by debuggin and helping others and receive help from you crazzy programmmers.......if i had a job i might give you pplz money for such an amazing site...its one of the very few on the net that have a point to them...alongside google and shockwave.com Wink GOOD JOB!!!! i know its commentss like this that make your day j/k Razz
im out...pz

Author:  Blade [ Mon Apr 07, 2003 8:05 pm ]
Post subject: 

use an if statement... lets say if you have a ball.... xy will be the mouse... so you make the forign object enter the radius of the mouse click.... then use an if statement to see if its there.. .such as
if forignobject < xy of ball + 40 then
the object has entered the radius

understand?

Author:  void [ Mon Apr 07, 2003 8:18 pm ]
Post subject: 

thanks alot ....i think i get it...but the thing is...what if its at like a 45 degree angle from the center (using a horizontal plane as 0 degreees and 180)...then how do you check it? lets say its a line headed at a circle at a 45 degree angle from the center of the circle....how would you check that?...because the xy only check the horizontal and vertical values does it not? the diagonals are completely ignored

Author:  Blade [ Mon Apr 07, 2003 8:38 pm ]
Post subject: 

what happens if you add 40 to x, and y, then find the distance between the both then get the midpoint from that.... would that work?

Author:  Catalyst [ Tue Apr 08, 2003 6:08 am ]
Post subject: 

use this function to find out if its in the circle

code:
function distance (x1, y1, x2, y2 : real) : real
    result ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5
end distance

Author:  void [ Tue Apr 08, 2003 6:45 am ]
Post subject: 

thanks man...that helped alot...im just wondering how come everyone uses **0.5 instead of sqrt...is it betta proggramming? or is it just kinda what ur used ta doing?

Author:  Catalyst [ Tue Apr 08, 2003 7:25 am ]
Post subject: 

might me a little faster since its not a function like sqrt, but i mainly just use by habit and that i can do cube roots and such by doing **0.3333,etc.

Author:  void [ Tue Apr 08, 2003 6:33 pm ]
Post subject: 

code:

var x, y, button : int

function distance (x1, y1, x2, y2 : real) : real
    result ( (x1 - x2) ** 2 - ( y1 - y1) ** 2) ** 0.5
end distance
loop
    Mouse.Where (x, y, button)
    locate (13, 13)
    put distance (6, 4, x, y)
    delay (5)
end loop

okay....heres what im attempting to do....i wanna see what the distance is....by radius from the mouse and the point that i randomly set in there.....but the thing is....i get a value of 0 (which should mean im directly over the point) far too many...how many different (6,4)'s can there be.....i've tried switching the (x,y) to x1 and y1 positions istead of their current x2,y2 possition...but the result is still the same..... Evil or Very Mad

Author:  Catalyst [ Tue Apr 08, 2003 9:14 pm ]
Post subject: 

u messed the code up..

Quote:

result ( (x1 - x2) ** 2 - ( y1 - y1) ** 2) ** 0.5


should be


Quote:

result ( (x1 - x2) ** 2 - ( y1 - y2 )** 2) ** 0.5

Author:  void [ Wed Apr 09, 2003 6:56 am ]
Post subject: 

hehehehehehe Embarassed ooopsssiiies......dont i feel like an idiot.... Laughing

Author:  FwuffyTheBunny [ Wed Apr 09, 2003 10:11 am ]
Post subject: 

Hey man, i like the bouncing ball program, ill probly use sum of it to help me in making my projects in school, so all in all thanks

Author:  Homer_simpson [ Fri Apr 25, 2003 11:04 pm ]
Post subject: 

here's is what i used in my custom created GUI to detect if mouse is over buttons or not

code:
function mouseover (x, y, x1, y1, x2, y2 : int) : boolean
    if x >= x1 and x <= x2 then
        if y >= y1 and y <= y2 then
            result true
        end if
    end if
    result false
end mouseover

and this is how it is used
code:
var mousex, mousey, mouseb : int

function mouseover (x, y, x1, y1, x2, y2 : int) : boolean
    if x >= x1 and x <= x2 then
        if y >= y1 and y <= y2 then
            result true
        end if
    end if
    result false
end mouseover
loop
    mousewhere (mousex, mousey, mouseb)
    if mouseover (mousex, mousey, 15, 320, 115, 340) then
        drawfillbox (15, 320, 115, 340, 9)
    else
        drawfillbox (15, 320, 115, 340, 12)
    end if
end loop

Author:  hello [ Sun May 11, 2003 7:35 pm ]
Post subject:  thx

thx for helping with the collision detection and i will show my finished version of the game
thx again

Author:  Pickles [ Fri May 07, 2004 9:11 pm ]
Post subject:  ..

I dont really understand it which is pretty sad because i should, is distance the point between the radius and what your looking for it to hit, and if distance is less than radius then that means that its hit.. ? Sorry if it sounds like a stupid question, i just cant seem to wrap my head around the concept

Author:  Viper [ Sun Nov 21, 2004 9:25 pm ]
Post subject: 

i find my self alwyas using the mousewhere is that jus b/c it the quickest 2 do or jus b/c im a newb would using keys be better or jus stick with mouse thing

Author:  w00t [ Wed Dec 01, 2004 8:17 am ]
Post subject: 

Hey, If figured this would be the place to be..

[mod:13299fcbab]No it isn't. Questions are best answered when asked in Turing Help. While I'm here, "fullscreen" only works in Turing 3.x, whereas View.Update only works in 4.0. That'd explain the flickering part.[/mod:13299fcbab]

Author:  Andy [ Wed Dec 01, 2004 4:03 pm ]
Post subject: 

u guys do realize that this topic is almost two years old right?

Author:  w00t [ Wed Dec 01, 2004 6:01 pm ]
Post subject: 

I'm using 3.2 Sad

Author:  hq78 [ Wed Jan 05, 2005 5:10 pm ]
Post subject: 

how do you do the collision detection with a box? or like a 20 X 20 pixel picture with another 20 X 20 pixel picture?

Author:  zylum [ Wed Jan 05, 2005 5:57 pm ]
Post subject: 

check whether the horizontal distance between them is less than or equal to the sum of half of their lengths and the verticle distance is less than of equal to the sum of half of their heights. these distances would ofcourse be measured from the center of one box to the center of the other

Author:  diablo [ Mon Jan 17, 2005 1:15 pm ]
Post subject:  collision detection

i read the tutorials and i still have a question:
i am making a game and my character uses large bullets
(about 15x15 pixels each), but i cant seem to get the bullets to kill the enemy when they hit. they just seem to pass thru each other.
can any1 help?

Author:  Dan [ Fri Jan 21, 2005 5:18 pm ]
Post subject:  Re: collision detection

diablo wrote:
i read the tutorials and i still have a question:
i am making a game and my character uses large bullets
(about 15x15 pixels each), but i cant seem to get the bullets to kill the enemy when they hit. they just seem to pass thru each other.
can any1 help?


Hard to help with somting like that with out seeing your code at all, post your question in turing help section with the code.

Author:  Paper*Mate [ Sun Jun 05, 2005 12:28 pm ]
Post subject: 

so how would fix that the bullet doesnt go through the obsticles... heres my code

setscreen ("offscreenonly")
var x, y : int
var x3, x2, y3, y2 : int := 200
var shot : boolean := false
var bulletx, bullety : int := 0
x := 100
y := 100
var chars : array char of boolean

loop
drawfillbox (50, 110, 40, 280, black)
drawfillbox (590, 110, 600, 280, black)
drawfillbox (490, 0, 500, 25, black)
drawfillbox (490, 375, 500, maxy, black)
drawfillbox (125, 375, 135, maxy, black)
drawfillbox (125, 0, 135, 25, black)
drawfilloval (320, 190, 50, 50, black)
drawfillbox (maxx, maxy, 637, 0, black)
drawfillbox (0, 0, maxx, 2, black)
drawfillbox (0, 0, 2, maxy, black)
drawfillbox (0, 397, maxx, maxy, black)
drawfilloval (x, y, 6, 6, 12)
Input.KeyDown (chars)
if chars (KEY_UP_ARROW) then
if whatdotcolor (x, y + 9) = 0
then
y := y + 5
end if
end if
if chars (KEY_RIGHT_ARROW) then
if whatdotcolor (x + 9, y) = 0 then
x := x + 5
end if
end if
if chars (KEY_LEFT_ARROW) then
if whatdotcolor (x - 9, y) = 0 then
x := x - 5
end if
end if
if chars (KEY_DOWN_ARROW) then
if whatdotcolor (x, y - 9) = 0 then
y := y - 5
end if
end if
if chars (KEY_CTRL) and shot = false then

bulletx := x
bullety := y
shot := true
end if
if bulletx < maxx and shot then
bulletx += 10
drawfilloval (bulletx, bullety, 2, 2, brightred)
elsif bulletx >= maxx then
shot := false
end if
View.Update
delay (10)
cls
end loop


reply quick

Author:  [Gandalf] [ Sun Jun 05, 2005 12:43 pm ]
Post subject: 

heck, I know this is proabbyl an assignment and I'm not supposed to help you. I'm also sure that you should be listening to Dan and posting this is the Help sections. I'm also sure that you shouldn't post things multiple times to get help. But what the hey...

What you need is a whatdotcolour check for the bullet's x and y cordinates as well as the coordinates of you (big dot).

*edit* use [ code] tags next time when posting code.

Author:  Paper*Mate [ Sun Jun 05, 2005 1:06 pm ]
Post subject: 

im sorry to bug u again... but can u put up the actual code cause i dont understand what u r trying to tell me... its just that im a newbie at writting codes

Author:  Bacchus [ Sun Jun 05, 2005 6:27 pm ]
Post subject: 

Well, then start to program smaller and easier to understand program until your able to program larger more complex ones instead of relying on others to give you the code, because if you just 'mooch' off of other you won't learn anything.

Author:  Jujeff [ Mon May 12, 2008 12:01 pm ]
Post subject:  Re: [Tutorial] Collision Detection

Hello! I'm new to here, and Turing (sort of) so I'm sorry if I appear a noob. I wanted to make a platformer for a school project, so I realized I needed to make my character jump. I found the highly-helpful Mazer Jump Tutorial, copied and pasted (there are some numbers I couldn't figure out the use of), and tweaked it to my needs.

After putting in a platform, I discovered that this messed everything up (the character cannot jump once on a platform), I tried to fix it as best as I could, and added in a boolean variable by recommendation of a friend, however as it is not clear to me the use of this, I will paste the code that I had before the boolean variable.

(The problem of the jumping of the platform, as far as I can see, is that the Yvelocity must be 0 to be able to jump, but the character can only be on the platform if Yvelocity is above the value of "gravity".)

Code:

setscreen ("graphics:1011;699;nobuttonbar;offscreenonly")

% VARIABLES!

var keystroke : array char of boolean

var height : int := 1
var LeftWall : int := 1
var RightWall : int := 1011
var movespeed : int := 10
var jumpspeed : int := 30
var gravity : int := 2

var Xposition, Yposition : int
var Xvelocity, Yvelocity : real

Xposition := 20
Yposition := 400
Xvelocity := 0
Yvelocity := 0

% game loop

loop

Input.KeyDown (keystroke)

% horizontal movement

if keystroke ('a') then
Xvelocity := -movespeed
elsif keystroke ('d') then
Xvelocity := movespeed
else
Xvelocity := 0
end if

% jump movement

if keystroke ('w') and Yposition = height then
Yvelocity := jumpspeed
end if
% world (lines and where you can walk and such)

drawline (0, height, maxx, height, blue)

drawline (245, 146, 384, 146, blue)

% line (if you're on the middle line, stay on it)

if Xposition >= 245 and Xposition <= 384 and Yposition >= 140 then

Yposition := 140
Yvelocity := 10
end if

% reinstate gravity every loop

Yvelocity -= gravity
Xposition += round (Xvelocity)
Yposition += round (Yvelocity)

% don't fall through the ground or go past the edges

if Yposition <= height then
Yposition := height
Yvelocity := 0
end if

if Xposition < LeftWall then
Xposition := 1
end if

if Xposition > RightWall then
Xposition := 1010
end if

% character (square for now)

drawfillbox (Xposition - 10, Yposition, Xposition + 10, Yposition + 20, green)

drawfillbox (Xposition - 10, Yposition, Xposition + 10, Yposition + 20, red)

% animation

View.Update
delay (25)
cls

end loop

Author:  Jujeff [ Mon May 12, 2008 7:48 pm ]
Post subject:  Re: [Tutorial] Collision Detection

EDIT:::: don't worry, it's been figured out

Author:  DaveAngus [ Tue May 20, 2008 12:39 pm ]
Post subject:  Re: [Tutorial] Collision Detection

This is great Dan!
Another easy way to detect colour could be

whatdotcolor


you could do something like

code:


 if whatdotcolor (posx + 25, posy) = black then

        % What ever you want inside here

    end if




I think this would work.
Let me know if it wouldnt.

Take care


: