Arrays delphi中的碰撞检测(pascal)
我正在为我的A级项目制作我自己版本的太空入侵者,我被碰撞检测卡住了。当子弹击中入侵者时,我需要检测碰撞,我真的被卡住了 入侵者当前存储在2d数组中,并在计时器上移动,其代码如下:Arrays delphi中的碰撞检测(pascal),arrays,delphi,collision-detection,pascal,Arrays,Delphi,Collision Detection,Pascal,我正在为我的A级项目制作我自己版本的太空入侵者,我被碰撞检测卡住了。当子弹击中入侵者时,我需要检测碰撞,我真的被卡住了 入侵者当前存储在2d数组中,并在计时器上移动,其代码如下: 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)
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;
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;
我写的冲突代码不起作用,但我不知道为什么。这可能是通过使用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;
程序冲突(img:TImage);
变量
TargetLeft,BulletLeft:整数;
TargetRight、BulletRight:整数;
TargetTop,BulletTop:整数;
TargetBottom,BulletBottom:整数;
Hit:布尔型;
开始
用frmGame do
点击:=正确;
TagetLeft:=img.Left;
BulletLeft:=shpbilet.Left;
TargetRight:=图像左侧+46//左+图像的宽度
BulletRight:=SHPBilet.左+8;
TargetTop:=img.Top;
BulletTop:=shpbilet.Top;
TargetBottom:=图像顶部+42//图像的顶部+高度
BulletBottom:=SHPBilet.顶部+15;
如果(TargetBottomBulletBottom),则点击:=false;
如果(TargetRightBulletRight),则点击:=false;
如果图像不可见,则点击:=假;
如果hit=true,则
img.Visible:=假;
任何帮助都将不胜感激。您的碰撞数学是正确的:当这四个检查中的一个为真时,则确实没有碰撞。所以你需要调试,因为很明显还有别的地方出了问题 首先从逻辑上开始调试:
- 问:我到底在检查什么?A:图像和子弹的位置
- 问:子弹的位置是什么?答:这是我在表单上看到的形状控件的
边界反射。不会错的
- 嗯
- 问:图像的位置是什么?答:相同:这是我在表单上看到的图像组件的边界矩形
- 问:真的吗?A:是的。。。哦,等等;我自己画的图像!!!(哈,为什么??)
- 问:那可能是原因吗?嗯,可能是
左属性和顶属性了,因为您可以使用Canvas.draw来手动绘制它们
结论:按照绘制程序计算图像的位置。或者设置每个图像的Parent
属性,并在更新例程中重写代码,方法是不绘制图像的图形,而是通过设置Left
和Top
重新定位阵列中的图像组件
评论:
- 我完全同意Wouter的观点:由于许多语法错误,您的代码无法编译。请确保将真正的编译代码放在StackOverflow上,最好直接从源代码编辑器复制粘贴
- 您可以使用简化碰撞检测,如下所示:
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;
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:TGraphic的数组[TCol,TRow]代码>
- 或者更好,如果所有目标都是相同的图像:将其设置为
布尔值的2D数组,指示该坐标处的目标是否被击中
- 停止使用全局表单变量(
frmGame
)。现在就停下来李>
- 生成form类的所有例程和方法,如上所示
- 将form类的所有全局变量设为私有字段,如上所示
代码的预期用途是什么?该代码的目的是检测子弹形状何时与入侵者图像重叠,然后不显示被击中的图像。目前的情况是子弹直接穿过入侵者的图像,但是子弹没有显示图像,而是在入侵者经过的地方划出一条线。好吧,进行一些调试。你知道如何使用调试器,对吗?我还建议你在纸上解决这些问题。图表纸。拿支铅笔,我觉得这段代码连编译都没有。这里有TagetLeft
,而声明的变量称为TargetLeft
,计算top
和left
的最佳方法是什么?与当前绘制图形的方法完全相同:left:=30+列*50+x代码>。谢谢你的建议,我明天会试一试。