Search code examples
delphidelphi-7collision

Delphi 7 - How to tell if object touches a color or another object


I'm writing 2d mini-games for another program I'm working on.

Problem is that I have very limited knowledge on coding that works with colliding objects.

For Example: how to test if 2 spheres collide like in Agar.io
or how the blocks from tetris detect that they touch each other,
or how Snake detects that the snake bit itself/food (without looking if the epicenters/coordinates of the middle of the objects are equal).

I'm using Delphi 7.


Solution

  • Collision testing is easy.
    If you want to test if two circles collide check the distance between their two center points:

    In a plane the distance between to points is calculated with the Pythagorean theorem sqrt((x2-x1)^2+(y2-y1)^2).

    if (sqrt((x2-x1)^2+(y2-y1)^2)) > (Radius(Circle1)+Radius(Circle2)) then 
    //x1,y1 = center point of circle1
    //x2,y2 = center point of circle2
    //or more efficiently:
    a:= (x2-x1)^2+(y2-y1)^2
    b:= (Radius(Circle1)+Radius(Circle2))^2;
    if a > b then
    

    If you want to check if two boxes collide there's a standard RTL routine for that.

    if IntersectRect(Rect1,Rect2) then ....
    

    As far as the snake goes, the thing that you're describing:

    if the epicenters/coordinates of the middle of the objects are equal

    Is exactly how it can be done, but a faster alternative is to use a discrete grid with integer coordinates and call a collision when two parts of the snake are on the same cell.

    type
      // The grid is initially empty except for a border around the edges
      TBodyPart = (bpNone, bpBorder, bpTail, bpBody, bpHead);
      TSnakeGrid = array[0..20,0..20] of TBodyPart;
    
      TSnake = class(TObject)
      private
         SnakeLength: integer;
         Grid: TSnakeGrid;
         .... 
         function IsCollision: boolean;
    
     function TSnake.IsCollision: boolean;
     begin
       Result:= Grid[Head.x, Head,y] <> bpEmpty;
     end;
    
     procedure TSnake.MoveSnake(Direction: TDirection);
     begin
       //Move the head
       Grid[Head.x, Head.y]:= bpBody;
       Inc(SnakeLength);
       case Direction of
         north: Dec(Head.y);
         south:= Inc(Head.y);
         west:= Dec(Head.x);
         east: Inc(Head.x);
       end; {case}
       if Grid[Head.x, Head.y] <> bpEmpty then Grid[Head.x,Head,y]:= bpHead
       else GameOver;
     end;  
    

    Google for "collision detection delphi vcl" and you will find lots of code.