我正在为我的A Level项目制作我自己的太空入侵者版本,我仍然坚持使用碰撞检测。当子弹击中其中一个入侵者时,我需要检测到碰撞,我真的被困住了。
入侵者目前存储在一个二维数组中,并在计时器上移动,其代码如下:
for Row:=1 to 5 do
begin
frmGame.Canvas.FillRect(WaveArea)
for Column:=1 to 11 do
begin
frmGame.Canvas.Draw(30+Column*50+x, 180 Images[1].Picture.Graphic);
frmGame.Canvas.Draw(30+Column*50+x, 230 Images[2].Picture.Graphic);
end;
x:=x+xShift;
end;
if x>500 then
tmrMoveInvaders.Enabled:=False;
我写的碰撞代码不起作用,但我不确定原因。它可能是使用2D数组将图像加载到表单上的方式,但我不确定。
碰撞程序的代码是:
Procedure Collision(img:TImage);
Var
TargetLeft,BulletLeft:integer;
TargetRight,BulletRight:integer;
TargetTop,BulletTop:integer;
TargetBottom,BulletBottom:integer;
Hit:boolean;
begin
with frmGame do
hit:=true;
TagetLeft:=img.Left;
BulletLeft:=shpBullet.Left;
TargetRight:=img.Left+46; //left + width of the image
BulletRight:=shpBullet.Left+8;
TargetTop:=img.Top;
BulletTop:=shpBullet.Top;
TargetBottom:=img.Top+42; //top + height of image
BulletBottom:=shpBullet.Top+15;
if (TargetBottom < BulletTop) then hit:=false;
if (TargetTop > BulletBottom) then hit:=false;
if (TargetRight < BulletLeft) then hit:=false;
if (TargetLeft > BulletRight) then hit:=false;
if not img.Visible then hit:=false;
if hit=true then
img.Visible:=false;
非常感谢任何帮助。
答案 0 :(得分:3)
你的碰撞数学是合理的:当这四个检查中的一个为真,那么确实没有命中。所以你需要调试,因为显然别的东西是错的。
首先开始逻辑调试:
BoundsRect
。不能错。简而言之:在碰撞例程中,您假设2D数组中的图像控件包含有关它们在窗体上的位置的信息。但我怀疑他们甚至不是这种形式的孩子,更不用说设置任何Left
和Top
属性了,因为你用Canvas.Draw
手动绘制它们。
结论:像在油漆程序中一样计算图像的位置。或者设置每个图像的Parent
属性,并通过不绘制图像的图形来重写更新例程中的代码,而是通过设置Left
和Top
重新定位阵列中的图像组件
您可以使用IntersectRect
简化碰撞检测,如下所示:
const
ColCount = 11;
RowCount = 5;
type
TCol = 0..ColCount - 1;
TRow = 0..RowCount - 1;
TGameForm = class(TForm)
private
FBullet: TShape;
FTargets: array[TCol, TRow] of TImage;
procedure CheckCollisions;
end;
implementation
{$R *.dfm}
procedure TGameForm.CheckCollisions;
var
Col: TCol;
Row: TRow;
R: TRect;
begin
for Col := Low(TCol) to High(TCol) do
for Row := Low(TRow) to High(TRow) do
if IntersectRect(R, FTargets[Col, Row].BoundsRect, FBullet.BoundsRect) then
FTargets[Col, Row].Visible := False;
end;
尝试使用图形数组而不是图像:FTargets: array[TCol, TRow] of TGraphic;
Boolean
的2D数组,指示该坐标处的目标是否被命中。frmGame
)。现在停止吧!