Delphi 7 - 如何判断物体是否接触到颜色或其他物体

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

我正在为我正在开发的另一个程序编写 2d 迷你游戏。

问题是我对处理碰撞对象的编码知识非常有限。

例如:如何测试 2 个球体是否像 Agar.io
中那样发生碰撞 或者俄罗斯方块中的方块如何检测到它们相互接触,
或者 Snake 如何检测蛇位 itself/food(不查看对象中间的 epicenters/coordinates 是否相等)。

我正在使用 Delphi 7.

经典的贪吃蛇和俄罗斯方块游戏通常在网格上运行,因此二维数组可以容纳所有元素。对于碰撞,您可以简单地查找二维数组中给定网格位置是否有对象。

为了检测球体重叠,您需要一些几何图形来确定球体中心之间的距离是否小于两个半径的总和,请参阅 more on the theory here

sphere1x = 100;
sphere1y = 200;
sphere1r = 5;

sphere2x = 105;
sphere2y = 200;
sphere2r = 10;

deltax = sphere1x - sphere2x;
deltay = sphere1y - sphere2y;
dist = (deltax * deltax) + (deltay * deltay);
rad2 = (sphere1r * sphere1r) + (sphere2r * sphere2r);

// for the actual distance you'd have to square root both dist and rad2, 
// but we just want to compare which is bigger, so this is skipped for optimisation

if (dist < rad2) then
begin
    // sphere collision
end;

碰撞测试很简单。
如果你想测试两个圆是否碰撞检查它们两个中心点之间的距离:

在平面上,点之间的距离是用毕达哥拉斯定理计算的 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

如果您想检查两个框是否发生碰撞,可以使用标准的 RTL 例程。

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

就蛇而言,你所描述的东西:

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

这正是可以做到的,但更快的替代方法是使用具有整数坐标的离散网格,并在蛇的两个部分位于同一单元格上时调用碰撞。

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" 你会发现很多代码。