delphi中的hitboxs

delphi中的hitboxs,delphi,Delphi,因此,我试图创建一个信息亭,在这个信息亭中,你可以将一个角色在表单周围移动到不同的图像上(例如移动到一个医学图像上,以显示医疗亭在该区域的位置),但我一直在确定这个可移动的角色是否以任何方式接触到任何图像。这是我尝试的基本思想过程。主要问题在于程序检查 type TForm1 = class(TForm) imgsprite: TImage; imgmed: TImage; imgMerch: TImage; Image2: TImage; Image

因此,我试图创建一个信息亭,在这个信息亭中,你可以将一个角色在表单周围移动到不同的图像上(例如移动到一个医学图像上,以显示医疗亭在该区域的位置),但我一直在确定这个可移动的角色是否以任何方式接触到任何图像。这是我尝试的基本思想过程。主要问题在于程序检查

type
  TForm1 = class(TForm)
    imgsprite: TImage;
    imgmed: TImage;
    imgMerch: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Image5: TImage;
    imgmedenter: TImage;
    imgFood: TImage;
    img: TImage;
    Panel1: TPanel;
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormActivate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure CheckCollisions;
  private
  isprite, spriteleft, spritetop : integer;
  bMove : boolean;
  FTargets: array[0..10] of TImage;
    { Private declarations }
  public
    { Public declarations }
  end;



var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.CheckCollisions;
var
iCount : integer;
bValid : boolean;
begin
iCount := - 1;
bValid := false;
while (bValid = false) OR (iCount >= 10) and (bMove = true) do
begin
  inc(icount);
  if (imgsprite.top =  FTargets[iCount].top) and (imgsprite.left = FTargets[iCount].left) then  //this just doesnt work
                                                                                                //and i dont know what to do
  begin
    bValid := true;
    bMove := false;
    case iCount of
    0 : imgmedenter.visible := true; //repeated for each thing in the array
    end;
  end;

end;

end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  iSprite := 0;
  bMove := true;
  Form1.DoubleBuffered := True;
  windowstate := wsmaximized;
  imgsprite.Top := ceil(clientheight/2);
  imgsprite.Left := floor(clientwidth/2);
  FTargets[0] := imgmed;
 // FTargets[1] := imgmed;
  //FTargets[2] := imgmed;
  //FTargets[3] := imgmed;
  //FTargets[4] := imgmed;
  //FTargets[5] := imgmed;
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
  vk_up:
  begin

  if bMove = true then
     begin
      inc(isprite);
      Checkcollisions;
     if (imgsprite.top >= 0) and (bMove = true)  then
     begin
         imgsprite.top := imgsprite.top - 10;
     case iSprite of
      1 : imgsprite.Picture.LoadFromFile('standingback.png');
      2 : imgsprite.Picture.LoadFromFile('backleft.png');
      3 : begin
           imgsprite.Picture.LoadFromFile('backright.png');
           iSprite := 0;
       end;
      end;
     end
     else
      iSprite := 0;
    end;
  end;

    VK_DOWN:
    begin
    if bMove = true then
    begin
      Checkcollisions;
      inc(isprite);
      if (imgsprite.top <= clientheight - imgsprite.height) and (bMove = true) then
     begin
       imgsprite.top := imgsprite.top + 10;
     case iSprite of
      1 : imgsprite.Picture.LoadFromFile('standing.png');
      2 : imgsprite.Picture.LoadFromFile('forwardsleft.png');
      3 : begin
           imgsprite.Picture.LoadFromFile('forwardsright.png');
           iSprite := 0;
       end;
      end;
     end
     else
      iSprite := 0;
    end;
  end;

    VK_LEFT:
    begin
    if bMove  = true then
    begin
    Checkcollisions;
     inc(isprite);
     if (imgsprite.left >= 0) and (bMove = true) then
     begin
      imgsprite.Left := imgsprite.Left - 10;
     case iSprite of
      1 : imgsprite.Picture.LoadFromFile('standingleft.png');
      2 : imgsprite.Picture.LoadFromFile('leftleft.png');
      3 : begin
           imgsprite.Picture.LoadFromFile('leftright.png');
           iSprite := 0;
       end;
      end;
     end
     else
      iSprite := 0;
    end;
  end;

    VK_RIGHT:
    begin
    if bMove = true then
    begin
    Checkcollisions;
    inc(iSprite);
    if (imgsprite.Left <= clientwidth - imgsprite.width ) and (bMove = true)   then
    begin
      imgsprite.Left := imgsprite.Left + 10;
      case iSprite of
      1 : imgsprite.Picture.LoadFromFile('standingright.png');
      2 : imgsprite.Picture.LoadFromFile('rightleft.png');
      3 : begin
           imgsprite.Picture.LoadFromFile('rightright.png');
           iSprite := 0;
      end;
     end;
     end
     else
      iSprite := 0;
    end;

  end;
end;
end;

类型
TForm1=类(TForm)
imgsprite:TImage;
imgmed:TImage;
imgMerch:TImage;
图2:TImage;
图3:TImage;
图4:TImage;
图5:TImage;
imgmedinter:TImage;
imgFood:TImage;
img:TImage;
小组1:TPanel;
过程FormKeyDown(发送方:TObject;变量关键字:Word;移位:TShiftState);
激活程序(发送方:TObject);
过程FormKeyPress(发送方:TObject;变量键:Char);
程序检查碰撞;
私有的
isprite、spriteleft、spritetop:整数;
bMove:布尔型;
FTargets:TImage的数组[0..10];
{私有声明}
公众的
{公开声明}
结束;
变量
表1:TForm1;
实施
{$R*.dfm}
程序TForm1.1检查碰撞;
变量
i计数:整数;
bValid:布尔型;
开始
i计数:=-1;
bValid:=假;
而(bValid=false)或(iCount>=10)和(bMove=true)则
开始
公司(icount);
如果(imgsprite.top=FTargets[iCount].top)和(imgsprite.left=FTargets[iCount].left),则//这根本不起作用
//我不知道该怎么办
开始
bValid:=真;
b移动:=假;
案例一
0:imgmedeter.visible:=真//对数组中的每个对象重复
结束;
结束;
结束;
结束;
程序TForm1.FormActivate(发送方:ToObject);
开始
iSprite:=0;
b移动:=真;
Form1.DoubleBuffered:=真;
windowstate:=wsmaximized;
imgsprite.Top:=ceil(clientheight/2);
imgsprite.Left:=楼层(客户宽度/2);
FTargets[0]:=imgmed;
//FTargets[1]:=imgmed;
//FTargets[2]:=imgmed;
//FTargets[3]:=imgmed;
//FTargets[4]:=imgmed;
//FTargets[5]:=imgmed;
结束;
过程TForm1.FormKeyDown(发送方:TObject;变量关键字:Word;
换档:t换档状态);
开始
案例关键
vk_up:
开始
如果bMove=true,则
开始
公司(isprite);
检查碰撞;
如果(imgsprite.top>=0)和(bMove=true),则
开始
imgsprite.top:=imgsprite.top-10;
案件记录
1:imgsprite.Picture.LoadFromFile('standingback.png');
2:imgsprite.Picture.LoadFromFile('backleft.png');
3:开始
imgsprite.Picture.LoadFromFile('backright.png');
iSprite:=0;
结束;
结束;
结束
其他的
iSprite:=0;
结束;
结束;
VK_DOWN:
开始
如果bMove=true,则
开始
检查碰撞;
公司(isprite);
如果(imgsprite.top=0)和(bMove=true),则
开始
imgsprite.Left:=imgsprite.Left-10;
案件记录
1:imgsprite.Picture.LoadFromFile('standingleft.png');
2:imgsprite.Picture.LoadFromFile('leftleft.png');
3:开始
imgsprite.Picture.LoadFromFile('leftright.png');
iSprite:=0;
结束;
结束;
结束
其他的
iSprite:=0;
结束;
结束;
右图:
开始
如果bMove=true,则
开始
检查碰撞;
公司(iSprite);

if(imgsprite.Left碰撞检测方法的问题在于,您只需检查图像组件是否具有由“上”和“左”属性确定的相同位置

只有当您的所有图像都具有相同的大小,并且只能以与图像宽度或高度相同的位置增量移动时,此方法才有效。或者简单地说,只有当您的所有图像都与固定网格对齐时,此方法才有效

现在,如果图像未在固定网格上对齐,则必须在表示图像的矩形之间执行碰撞检测

所以,首先需要得到表示图像的矩形,只需读取图像控件的属性即可,该属性以类型形式返回信息

现在是一种高级记录类型,它还包含一些处理矩形的有用方法。其中还有几种检测多个矩形之间碰撞的方法

对您来说,最有用的三种方法可能是:

  • 检查当前记录是否与其他记录相交 作为参数传递的
  • 它返回一个新的矩形,表示两个矩形之间的交点。如果要对这两个矩形的相交区域应用某些特殊效果,可能会很有用
  • 如果提供的作为参数传递的点或矩形包含在当前矩形中,则返回true。请注意,仅当传递给此方法的整个矩形包含在当前矩形中时,此方法才会返回true
因此,在您的情况下,碰撞检测代码类似于:

if imgsprite.BoundsRect.IntersectsWith(FTargets[iCount].BoundsRect) then
//Code to do what it needs to be done when collision is detected.
再看看你的代码和你的
while循环
我想它可能有很多不必要的复杂性。我可能错了,因为我没有看到你的全部代码

如果检测到冲突,我会使用for循环,然后中断循环,以避免检查与图像数组其余部分的冲突

因此,代码可能如下所示:

for iCount := 0 to 10 do
if imgsprite.BoundsRect.IntersectsWith(FTargets[iCount].BoundsRect) then
begin
  //Code to do what it needs to be done when collision is detected.
  Break; //Breaks the for loop in irder to prevent checking collision detection 
         //with rest of the items in FTargets array.
end;

VCL控件不适用于这种类型的使用。您可能需要一个完全不同的解决方案。@David是对的。这是我的标准示例,说明了如何做到这一点:…//这根本不起作用……如果没有解释行为与预期的不同,这几乎是一个无用的问题指示。总之,一些提示:1)您的
FTargets
数组可以有索引0..10,但您不能阻止
iCount
超出该范围。2) 此外,你的