Delphi 7 - 将 TImage 分配给 TImage 数组
Delphi 7 - Assigning a TImage to array of TImage
我正在制作自定义战舰游戏,我有一个 10x10 的对象网格 (TImage)。我需要在运行时更改它们的 .Picture 属性,以便船只出现在视口中。我需要根据给定的坐标更改图片 属性,因此我创建了以下数组:
image: array[1..10,1..10] of TImage;
我试过为它们分配一个像这样的 TImage 对象:
player1.image[1,1] := player1.bcvrA1;
它应该包含指向视口上所有 TImage 对象的链接(它存在于表单预启动中)所以我可以像这样更改一个 SampleTImage.Picture 属性:
image[x,y].Picture.LoadFromFile(SamleFile);
但这会引发访问冲突错误。
Access violation at address 0046CF10 in module 'Project2.exe'. Read of
address 00000628.
我在发布这个问题之前做了一些研究,但是 Whosebug 上提出类似问题的每个人都在运行时创建对象,在我的例子中,所有 TImage 对象都是在运行时创建的,并且需要分配给一个双维数组,所以我可以更多地更改属性 'conveniently'.
如果这样做不可能,我真的很想看看任何可能的最佳解决方案。 :)
如果这个问题已经被问到并回答了十几次,我感到非常抱歉。我对这种对象操作的东西很陌生。
感谢您的宝贵时间! ;)
我建议您使用 TImageList
来存储图像并根据需要使用 TImages
在屏幕上显示这些图像。
确保图像是透明的。如果不想在代码中旋转图像,可以在 ImageList 中复制图像。
如果您将对象存储在数组中,请注意该数组从零(或垃圾)开始。
这就是你收到错误的原因。
如果你想使用数组,使用这样的东西:
procedure TForm1.CreateForm(Sender: TObject);
begin
//Init array here, no action needed, because all object members are zero to start with.
end;
procedure TForm1.AddShip(Location: TPoint; ImageIndex: integer);
var
x,y: integer;
NewImage: TImage;
Bitmap: TBitmap;
begin
x:= Location.x; y:= Location.y;
if ImageArray[X, Y] = nil then begin
NewImage:= TImage.Create(Self);
NewImage.Parent:= Panel1;
NewImage.Transparent:= true;
NewImage.Left:= x * GridSize;
NewImage.Top:= y * GridSize;
ImageArray[x,y]:= NewImage;
end;
if ImageList1.GetBitmap(ImageIndex, Bitmap) then begin
ImageArray[x,y].Picture.Assign(Bitmap);
end else raise Exception.Create(Format('Cannot find an image with index %d in %s',[ImageIndex,'ImageList1']));
end;
通常我建议不要在游戏中使用 TImages 作为 sprite,但对于像经典战舰游戏中的战舰这样缓慢(非?)移动的物体,我想这没问题。
请注意,图像不会重叠,您的图像列表中只有方块的船。
图像列表中的图像之一必须是 'empty' 位图,其中只有一个内部透明颜色的矩形。如果里面没有战舰,你就把它分配给一个矩形。
显然,您需要对网格的状态做一些簿记。
这个你记下来了。
TGridRect = record
shiptype: TShiptype;
orientation: THorizontalOrVertical;
shipsection: integer;
HiddenFromEnemy: boolean;
end;
TGrid = array[0..9,0..9] of TGridRect;
如果你有gridrect
,那么你不需要图片,直接在窗体的OnPaint事件中绘制即可。
procedure TForm1.Paint(Sender: TObject);
var
GridRect: TGridRect;
Bitmap: TBitmap;
ImageIndex: integer;
begin
for x:= 0 to 9 do begin
for y:= 0 to 9 do begin
GridRect:= Grid[x,y];
ImageIndex:= Ord(GridRect.ShipType) * NumberOfParts
+ GridRect.ShipSection * (Ord(GridRect.Orientation)+1);
Bitmap:= TBitmap.Create;
try
ImageList1.GetBitmap(ImageIndex, Bitmap);
Panel1.Canvas.Draw(x*GridSize, y*GridSize, Bitmap);
finally
Bitmap.Free;
end;
end; {for y}
end; {for x}
祝你好运。
我正在制作自定义战舰游戏,我有一个 10x10 的对象网格 (TImage)。我需要在运行时更改它们的 .Picture 属性,以便船只出现在视口中。我需要根据给定的坐标更改图片 属性,因此我创建了以下数组:
image: array[1..10,1..10] of TImage;
我试过为它们分配一个像这样的 TImage 对象:
player1.image[1,1] := player1.bcvrA1;
它应该包含指向视口上所有 TImage 对象的链接(它存在于表单预启动中)所以我可以像这样更改一个 SampleTImage.Picture 属性:
image[x,y].Picture.LoadFromFile(SamleFile);
但这会引发访问冲突错误。
Access violation at address 0046CF10 in module 'Project2.exe'. Read of address 00000628.
我在发布这个问题之前做了一些研究,但是 Whosebug 上提出类似问题的每个人都在运行时创建对象,在我的例子中,所有 TImage 对象都是在运行时创建的,并且需要分配给一个双维数组,所以我可以更多地更改属性 'conveniently'.
如果这样做不可能,我真的很想看看任何可能的最佳解决方案。 :)
如果这个问题已经被问到并回答了十几次,我感到非常抱歉。我对这种对象操作的东西很陌生。
感谢您的宝贵时间! ;)
我建议您使用 TImageList
来存储图像并根据需要使用 TImages
在屏幕上显示这些图像。
确保图像是透明的。如果不想在代码中旋转图像,可以在 ImageList 中复制图像。
如果您将对象存储在数组中,请注意该数组从零(或垃圾)开始。
这就是你收到错误的原因。
如果你想使用数组,使用这样的东西:
procedure TForm1.CreateForm(Sender: TObject);
begin
//Init array here, no action needed, because all object members are zero to start with.
end;
procedure TForm1.AddShip(Location: TPoint; ImageIndex: integer);
var
x,y: integer;
NewImage: TImage;
Bitmap: TBitmap;
begin
x:= Location.x; y:= Location.y;
if ImageArray[X, Y] = nil then begin
NewImage:= TImage.Create(Self);
NewImage.Parent:= Panel1;
NewImage.Transparent:= true;
NewImage.Left:= x * GridSize;
NewImage.Top:= y * GridSize;
ImageArray[x,y]:= NewImage;
end;
if ImageList1.GetBitmap(ImageIndex, Bitmap) then begin
ImageArray[x,y].Picture.Assign(Bitmap);
end else raise Exception.Create(Format('Cannot find an image with index %d in %s',[ImageIndex,'ImageList1']));
end;
通常我建议不要在游戏中使用 TImages 作为 sprite,但对于像经典战舰游戏中的战舰这样缓慢(非?)移动的物体,我想这没问题。
请注意,图像不会重叠,您的图像列表中只有方块的船。
图像列表中的图像之一必须是 'empty' 位图,其中只有一个内部透明颜色的矩形。如果里面没有战舰,你就把它分配给一个矩形。
显然,您需要对网格的状态做一些簿记。
这个你记下来了。
TGridRect = record
shiptype: TShiptype;
orientation: THorizontalOrVertical;
shipsection: integer;
HiddenFromEnemy: boolean;
end;
TGrid = array[0..9,0..9] of TGridRect;
如果你有gridrect
,那么你不需要图片,直接在窗体的OnPaint事件中绘制即可。
procedure TForm1.Paint(Sender: TObject);
var
GridRect: TGridRect;
Bitmap: TBitmap;
ImageIndex: integer;
begin
for x:= 0 to 9 do begin
for y:= 0 to 9 do begin
GridRect:= Grid[x,y];
ImageIndex:= Ord(GridRect.ShipType) * NumberOfParts
+ GridRect.ShipSection * (Ord(GridRect.Orientation)+1);
Bitmap:= TBitmap.Create;
try
ImageList1.GetBitmap(ImageIndex, Bitmap);
Panel1.Canvas.Draw(x*GridSize, y*GridSize, Bitmap);
finally
Bitmap.Free;
end;
end; {for y}
end; {for x}
祝你好运。