Image 如何在Delphi中从合成图像创建pan
我是一个新的德尔福图形方法,我在创造一个呆板的。。。视口,这就是我在为一个项目做时如何称呼它的。很抱歉,我不能为它提供任何代码,但我停留在逻辑部分,搜索谷歌指向我一些OnPaint,Draw方法。但这些并不是我想要实现的,因为我有,例如:Image 如何在Delphi中从合成图像创建pan,image,delphi,delphi-2010,pan,Image,Delphi,Delphi 2010,Pan,我是一个新的德尔福图形方法,我在创造一个呆板的。。。视口,这就是我在为一个项目做时如何称呼它的。很抱歉,我不能为它提供任何代码,但我停留在逻辑部分,搜索谷歌指向我一些OnPaint,Draw方法。但这些并不是我想要实现的,因为我有,例如: 锚定到客户端顶部/底部/右侧和左侧的1600x1000背景图像 多个TImage元素放置在集合x/y坐标处 一个类似于HTML中地图元素的“热点”,我可以在其中设置可点击区域(对于我在步骤2中放置的图像) 不需要缩放 最重要的是,当背景被拖动时,那些放在背景上
抱歉,如果我不够清楚,我没有起点,因为我在delphi中根本没有这方面的经验。(使用RAD Studio 2010)这是一个非常简短的示例,说明如何以简单的方式实现它 您可以使用一个画框进行绘制,一个背景图像,一个包含信息和透明图像的记录数组 画布可以在偏移/缩放/旋转中操作。 移动和命中检测将在mousedown和mousemove中发生 它并不完整,但可能会给你一个如何完成的想法
[delphi]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls,PNGImage, StdCtrls;
type
TBuilding=Record // record for building informations
Pos:TPoint;
PNGImage:TPngImage;
// what ever needed
End;
TBuildingArray=Array of TBuilding; // array of buildings
TForm1 = class(TForm)
PaintBox1: TPaintBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private-Deklarationen }
FXoffs,FYOffs,FZoom:Double; // offset and zoom for painting
FMouseDownPoint:TPoint;
FBackGroundPNG:TPNGImage;
FBuildingArray:TBuildingArray;
procedure Check4Hit(X, Y: Integer);
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
uses Math;
{$R *.dfm}
Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
form : tagXFORM;
Winkel:Double;
begin
Winkel := DegToRad(Angle);
SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
form.eM11 := Zoom * cos( Winkel);
form.eM12 := Zoom *Sin( Winkel) ;
form.eM21 := Zoom * (-sin( Winkel));
form.eM22 := Zoom * cos( Winkel) ;
form.eDx := CenterpointX;
form.eDy := CenterpointY;
SetWorldTransform(ACanvas.Handle,form);
end;
Procedure ResetCanvas(ACanvas:TCanvas);
begin
SetCanvasZoomAndRotation(ACanvas , 1, 0, 0,0);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Path:String;
i:Integer;
begin
FZoom := 1;
DoubleBuffered := true;
Path := ExtractFilePath(Paramstr(0));
FBackGroundPNG:=TPNGImage.Create;
FBackGroundPNG.LoadFromFile(Path + 'infect.png');
SetLength(FBuildingArray,3);
for I := 0 to High(FBuildingArray) do
begin
FBuildingArray[i].PNGImage := TPngImage.Create;
FBuildingArray[i].PNGImage.LoadFromFile(Path + Format('B%d.png',[i]));
FBuildingArray[i].Pos.X := I * 300;
FBuildingArray[i].Pos.Y := Random(1000);
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i:Integer;
begin
for I := 0 to High(FBuildingArray) do
begin
FBuildingArray[i].PNGImage.Free;
end;
FBackGroundPNG.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if FZoom=0.5 then FZoom := 1 else FZoom := 0.5;
PaintBox1.Invalidate;
end;
procedure TForm1.Check4Hit(X,Y:Integer);
var
i,Index:Integer;
R:TRect;
P:TPoint;
begin
index := -1;
for I := 0 to High(FBuildingArray) do
begin
R := Rect(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y
,FBuildingArray[i].Pos.X + FBuildingArray[i].PNGImage.Width
,FBuildingArray[i].Pos.Y + FBuildingArray[i].PNGImage.Height);
P := Point(Round((x - FXOffs)/FZoom) ,Round((y - FYOffs)/FZoom));
if PtInRect(R,P) then Index := i;
end;
if index > -1 then
begin
Caption := Format('Last hit %d',[index]);
end
else Caption := 'No Hit';
end;
procedure TForm1.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Check4Hit(X,Y);
FMouseDownPoint.X := X;
FMouseDownPoint.Y := Y;
end;
procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
FXoffs := -( FMouseDownPoint.X - X) ;
FYoffs := -( FMouseDownPoint.Y - Y) ;
if FXoffs>0 then FXoffs := 0;
if FYoffs>0 then FYoffs := 0;
PaintBox1.Invalidate;
end;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
i:Integer;
begin
SetCanvasZoomAndRotation(PaintBox1.Canvas,FZoom,0,FXoffs,FYOffs);
PaintBox1.Canvas.Draw(0,0,FBackGroundPNG);
for I := 0 to High(FBuildingArray) do
begin
PaintBox1.Canvas.Draw(FBuildingArray[i].Pos.X,FBuildingArray[i].Pos.Y,FBuildingArray[i].PNGImage);
end;
end;
end.
[/delphi]
对不起,但在过去的几年里,我和拉扎勒斯而不是德尔福一起工作。但这篇文章将提供信息: 关于相对坐标,没什么好说的——很简单。 关于拖动:很久以前,在一个遥远的星系里。。这有点像:
// To start dragging
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
// To stop dragging
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
// To perform dragging
procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
你的问题是根据地形拖动建筑物吗?地形是不可调整大小的,它只有1600x1000,所以我需要在客户端(可能小于1600x1000)隐式地使其可拖动,客户端的最大约束是1600x1000,我需要terain(后台)在客户端窗体周围可拖动。不,没什么需要的。我会试试看我能做些什么。请继续回答问题。现在非常感谢,我会接受答案,只要我看到这个想法变得有价值(可能在一个小时左右),如果有人在拖动时背景(偏移量)重置为0,0有问题,请遵循以下步骤:declar a tPoint:tPoint;在{public}节下,然后在MouseDown事件集tPoint.x:=Trunc(FXoffs);和tPoint.y:=Trunc(fyoff);因为我们需要从一个doulbe中得到int。然后在MouseMove事件中,为各自的公式添加tempx和tempy。例如:FXoffs:=-(FMouseDownPoint.X-X)+tempx;和fyoff:=-(FMouseDownPoint.Y-Y)+tempy;这样程序就知道他上次在哪里停止了这个拖拽。问候。是的,TrpToBox已经把这些事件称为OnMouSurt/OnMouSeMeFor,但我将考虑Bunmie的答案,因为它不是那种低级编程。我的意思是,当Embarcadero已经在标准库中实现了“最佳”方法来完成类似的任务时,为什么还要做所有的艰苦工作呢。谢谢你抽出时间。