Delphi多个对象的碰撞检测问题
由于某些原因,我的冲突代码不能处理多个对象。它可以完美地与一个物体配合使用,但当我尝试同时与另一个物体配合使用时,它失败了,玩家可以通过每个物体移动。我计划在一个动态数组中创建对象,并为每个对象循环此代码,但它有相同的问题,因为运行两次代码会导致所有碰撞检测中断 1个对象工作的完整项目粘贴箱: 2个对象不工作的完整项目粘贴箱: 定时器程序,两个对象的碰撞检测代码复制两次:Delphi多个对象的碰撞检测问题,delphi,collision-detection,Delphi,Collision Detection,由于某些原因,我的冲突代码不能处理多个对象。它可以完美地与一个物体配合使用,但当我尝试同时与另一个物体配合使用时,它失败了,玩家可以通过每个物体移动。我计划在一个动态数组中创建对象,并为每个对象循环此代码,但它有相同的问题,因为运行两次代码会导致所有碰撞检测中断 1个对象工作的完整项目粘贴箱: 2个对象不工作的完整项目粘贴箱: 定时器程序,两个对象的碰撞检测代码复制两次: procedure TForm1.OnTick(Sender: TObject); var I
procedure TForm1.OnTick(Sender: TObject);
var IntersectionRect: TRect;
begin
//First object
if not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape1.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape1.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
if d = true then
Image1.Left := Image1.Left + 5;
end;
if not((Image1.BoundsRect.BottomRight.Y >= Shape1.Top - 10) and (Image1.BoundsRect.BottomRight.Y <= Shape1.Top + 10) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
if s = true then
Image1.Top := Image1.Top + 5;
end;
if not((Image1.BoundsRect.TopLeft.X - 10 <= (Shape1.Left + Shape1.Width)) and (Image1.BoundsRect.TopLeft.X + 10 >= (Shape1.Left + Shape1.Width)) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
if a = true then
Image1.Left := Image1.Left - 5;
end;
if not((Image1.BoundsRect.TopLeft.Y <= Shape1.BoundsRect.BottomRight.y + 10) and (Image1.BoundsRect.TopLeft.Y >= Shape1.BoundsRect.BottomRight.y - 10) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
if w = true then
Image1.Top := Image1.Top - 5;
end;
//second object
if not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape2.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape2.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape2.BoundsRect)) then
begin
if d = true then
Image1.Left := Image1.Left + 5;
end;
if not((Image1.BoundsRect.BottomRight.Y >= Shape2.Top - 10) and (Image1.BoundsRect.BottomRight.Y <= Shape2.Top + 10) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape2.BoundsRect)) then
begin
if s = true then
Image1.Top := Image1.Top + 5;
end;
if not((Image1.BoundsRect.TopLeft.X - 10 <= (Shape2.Left + Shape2.Width)) and (Image1.BoundsRect.TopLeft.X + 10 >= (Shape2.Left + Shape1.Width)) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape2.BoundsRect)) then
begin
if a = true then
Image1.Left := Image1.Left - 5;
end;
if not((Image1.BoundsRect.TopLeft.Y <= Shape2.BoundsRect.BottomRight.y + 10) and (Image1.BoundsRect.TopLeft.Y >= Shape2.BoundsRect.BottomRight.y - 10) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape2.BoundsRect)) then
begin
if w = true then
Image1.Top := Image1.Top - 5;
end;
end;
程序TForm1.OnTick(发送方:TObject);
var IntersectionRect:TRect;
开始
//第一个对象
如果不是(((Image1.Width+Image1.BoundsRect.TopLeft.x)>=Shape1.Left-10)和((Image1.Width+Image1.BoundsRect.TopLeft.x)=Shape1.Top-10)和(Image1.BoundsRect.BottomRight.Y=Shape2.Left-10)和((Image1.Width+Image1.BoundsRect.TopLeft.x)=Shape2.Top-10)和(Image1.BoundsRect.BottomRight.Y,代码实际上是这样说的“如果A不与B碰撞或A不与C碰撞,则移动”您需要的是相反的“如果A不与B碰撞且A不与C碰撞,则移动”,例如
现在所有这些都没有经过测试-我只是想告诉你如何继续-我不会为你写代码。另外,你需要重复s,w和a
但是,希望您现在能够看到正确构建代码的价值。这非常有用,但您如何才能将其更改为适用于对象数组?因为您不能在每次希望它适用于新对象时向所有IF语句中添加另一个AND语句。您的代码是为“高效快速操作”而设计的,而不是为了健壮性d易于维护。您需要认真重构它,分离碰撞检测和移动功能。这当然会降低代码运行速度,但有一些优化可以使其运行更快,例如在检测到碰撞时中断碰撞检测循环。一旦分离了该功能,expa对任意数量的形状进行绑定成了儿戏。此外,您的代码更易于阅读和维护。公平地说,剪切和粘贴块也不是一个真正的选项。此外,我将颠倒逻辑-使用s、d、a和w来确定使用了哪种碰撞检测,而不是确定是否存在碰撞,然后确定是否存在碰撞f我们可以移动。您的操作方式有很多错误。老实说,我看不出如何在数组中使用if语句,因为我无法为数组中的每个形状添加无限多的if语句。例如:
// both objects
if (not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape1.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape1.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect))
and (not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape2.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape2.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape2.BoundsRect)) ) then
begin
if d = true then
Image1.Left := Image1.Left + 5;
end;
if not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape1.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape1.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
if d = true then
Image1.Left := Image1.Left + 5;
end;
if d = true then
if not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape1.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape1.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then
begin
Image1.Left := Image1.Left + 5;
end;
function CollideD( Image1 : TImage Shape1Rect : TShape ); // or as appropriate
begin
if not(((Image1.Width + Image1.BoundsRect.TopLeft.x) >= Shape1.Left-10 ) and ((Image1.Width + Image1.BoundsRect.TopLeft.x) <= Shape1.Left+10 ) and IntersectRect(IntersectionRect, Image1.BoundsRect, Shape1.BoundsRect)) then Result := FALSE else Result := TRUE;
end;
procedure MoveD( Iamge1 : TImage );
begin
Image1.Left := Image1.Left + 5;
end;
...
if d = true then
if not CollideD( Image1, Shape1 ) then
begin
MoveD( Image1 );
end;
var
iCanMove : Boolean;
...
iCanMove := TRUE;
if d then
begin
for I := 0 to ShapeList.Count - 1 do
begin
if CollideD( Image1, ShapeList[ I ] ) then
begin
iCanMove : FALSE;
break;
end;
end;
if iCanMove then MoveD( Image1 );
end;