我正在为另一个我正在制作的节目写二维迷你游戏。
问题是我对与碰撞对象有关的编码知识非常有限。
例如:如何测试2个球体是否像Agar.io中那样发生碰撞
或者来自俄罗斯方块的块如何检测到它们相互接触,
或者Snake如何检测到蛇咬自己/食物(不看物体中间的中心/坐标是否相等)。
我使用Delphi 7。
答案 0 :(得分:3)
碰撞测试很容易。
如果你想测试两个圆是否碰撞,检查它们的两个中心点之间的距离:
在一个平面中,点之间的距离用毕达哥拉斯定理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 ....
就蛇而言,你所描述的是:
如果物体中间的中心/坐标相等
究竟是如何做到的,但更快的选择是使用带整数坐标的离散网格,并在蛇的两个部分位于同一个单元格时调用碰撞。
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;
谷歌的“碰撞检测delphi vcl”,你会发现很多代码。
答案 1 :(得分:1)
经典的Snake和Tetris游戏通常在网格上运行,因此2D数组可以容纳所有元素。对于碰撞,您可以简单地查找在给定网格位置的2D阵列中是否存在对象。
要检测球体重叠,您需要一些几何体来确定球体中心之间的距离是否小于两个半径的组合,请参阅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;