画布/位图滚动问题

发布于 2024-09-19 04:49:48 字数 127 浏览 7 评论 0原文

我正在尝试制作一个基于 Delphi 画布的小游戏。基本上,我想制作一个相当大的位图(例如,3000x3000),然后将其加载到画布中,并且能够像普通图像查看器一样向右/向左/向上/向下滚动,但是我不能似乎找到了我要找的东西。有什么想法吗?

I'm trying to make a small game based on the canvas in Delphi. Basically, I'd like to make a fairly large bitmap ( 3000x3000, for example ), then load it into the canvas, and being able to scroll right/left/up/down just like an ordinary image viewer, however I can't seem to find what I'm looking for. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦屿孤独相伴 2024-09-26 04:49:48

将图像加载到屏幕外的 TBitmap 对象。然后,OnPaint,或者只要适合您的特定应用程序,就使用 BitBltCanvas.Draw 绘制 的矩形子图像TBitmap 到画布上。子部分应从 TBitmap 上的 (X, Y) 开始,并且宽度和高度等于 ClientWidthClientHeight 的形式,分别。

现在,响应键盘事件。编写 FormKeyDown 事件处理程序,并监听 Key = VK_LEFTKey = VK_RIGHTKey = VK_UPKey = VK_DOWN(使用case 语句)。当您检测到按下此类键时,根据需要增加/减少 XY,并使用此起点再次绘制场景。

您还可以响应 MouseDownMouseMoveMouseUp 事件以使用鼠标滚动。您可以只使用中间的一个(MouseMove):您可以检查光标是否靠近表单边缘,如果是,则沿该方向平滑滚动(使用 TTimer< /code>,例如)。或者,您可以在 MouseDown 中将 FMouseDown 标志设置为 true,并在 中将其重置为 false鼠标按下。然后,在 MouseMove 中,如果 FMouseDowntrue,则将位图沿 x 方向滚动增量 X-XOld ,以及 y 方向上的增量 Y-YOld。 (这里,XYMouseMove 事件处理程序的参数;(X, Y) 是当前光标的位置。)

XOld := X;
YOld := Y;

无论FMouseDown 打开还是关闭,MouseMove 过程都应该结束。

Load the image to an off-screen TBitmap object. Then, OnPaint, or whenever is suitable in your particular application, use BitBlt or Canvas.Draw to draw a rectangular subimage of the TBitmap onto the canvas. The subpart should start at (X, Y) on the TBitmap and have a width and height equal to ClientWidth and ClientHeight of the form, respectively.

Now, respond to keyboard events. Write a FormKeyDown event handler, and listen to Key = VK_LEFT, Key = VK_RIGHT, Key = VK_UP, and Key = VK_DOWN (use a case statement). When you detect such a key being pressed, increase/decrease X or Y, as appropriate, and paint the scene again using this starting point.

You can also respond to the MouseDown, MouseMove, and MouseUp events to scroll using the mouse. Either you can use the middle one only (MouseMove): You can check if the cursor is near an edge of the form, and if so, scroll in this direction smoothly (using a TTimer, for instance). Alternatively, you can set a FMouseDown flag to true in MouseDown, and reset it to false in MouseUp. Then, in MouseMove, scroll the bitmap by a delta X-XOld in the x direction if FMouseDown is true, and a delta Y-YOld in the y direction. (Here, X and Y are parameters of the MouseMove event handler; (X, Y) is the current position of the cursor.) The MouseMove procedure should end with

XOld := X;
YOld := Y;

no matter if FMouseDown is on or off.

明媚殇 2024-09-26 04:49:48

我也有同样的问题。我的位图约为 5000x5000 像素,加载到 500x500 像素的 Timage 中。

我编写了一个代码来移动Timage中的位图周围,它不能超出

在开头的Form1 var中声明的AlteMausPos的“边界”。
Kerzenbitmap 是包含 5000x5000 图片的位图。
MausPosDifferenz 包含按下鼠标键时移动鼠标的绝对像素数 (x,y)。

然后它会检查所有内容是否都在位图的范围内,然后再使用 CopyRect 进行复制。

我的大脑花了一些时间才发现复制右方以使用绝对改变的鼠标位置的最佳方法。

procedure Form1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var picLimits: Tpoint;
begin
  AlteMausPos.X := X;
  AlteMausPos.Y := Y;
end;


procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var SourceRect, DestRect: TRect;
begin
  var tempBMP:= Tbitmap.Create;
  MausPosDifferenz.X := MausPosDifferenz.X+ (AlteMausPos.X- X);
  MausPosDifferenz.Y := MausPosDifferenz.Y+ (AlteMausPos.Y- Y);
  if MausPosDifferenz.X >= Kerzenbitmap.Width- Image1.Width then MausPosDifferenz.X := Kerzenbitmap.Width-Image1.Width;
  if MausPosDifferenz.X < 0 then MausPosDifferenz.X:=0;
  if MausPosDifferenz.Y >= Kerzenbitmap.Height-Image1.Height then MausPosDifferenz.Y := Kerzenbitmap.Height-Image1.Height;
  if MausPosDifferenz.Y < 0 then MausPosDifferenz.Y:=0;

  SourceRect:=  Rect( MausPosDifferenz.X, MausPosDifferenz.Y, Image1.Width+ MausPosDifferenz.X, Image1.Height+ MausPosDifferenz.Y);
  DestRect:=    Rect( 0,0, Image1.Width, Image1.Height);
  tempBMP.Assign(Kerzenbitmap);
  TempBMP.Canvas.CopyRect(DestRect, Kerzenbitmap.Canvas, SourceRect);

  Image1.Picture.Assign(tempBMP);
  tempBMP.Free;
end;

I had the same problem. My Bitmap is about 5000x5000 pixel, loaded into an Timage of 500x500 pixels.

I wrote a code to move the bitmap arround in the Timage, and it cant go out of the "borders"

AlteMausPos is declared in Form1 var at the beginning.
Kerzenbitmap is your bitmap that contains the 5000x5000 picture.
MausPosDifferenz contains the absolut amount of pixels(x,y) you have moved your mouse while mousekey down.

Then it checks if everything is in Range of the bitmap before copying it with CopyRect.

It took some time for my brain to find out that the best way to copy the rect ist to use the absolut changed mouseposition.

procedure Form1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var picLimits: Tpoint;
begin
  AlteMausPos.X := X;
  AlteMausPos.Y := Y;
end;


procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var SourceRect, DestRect: TRect;
begin
  var tempBMP:= Tbitmap.Create;
  MausPosDifferenz.X := MausPosDifferenz.X+ (AlteMausPos.X- X);
  MausPosDifferenz.Y := MausPosDifferenz.Y+ (AlteMausPos.Y- Y);
  if MausPosDifferenz.X >= Kerzenbitmap.Width- Image1.Width then MausPosDifferenz.X := Kerzenbitmap.Width-Image1.Width;
  if MausPosDifferenz.X < 0 then MausPosDifferenz.X:=0;
  if MausPosDifferenz.Y >= Kerzenbitmap.Height-Image1.Height then MausPosDifferenz.Y := Kerzenbitmap.Height-Image1.Height;
  if MausPosDifferenz.Y < 0 then MausPosDifferenz.Y:=0;

  SourceRect:=  Rect( MausPosDifferenz.X, MausPosDifferenz.Y, Image1.Width+ MausPosDifferenz.X, Image1.Height+ MausPosDifferenz.Y);
  DestRect:=    Rect( 0,0, Image1.Width, Image1.Height);
  tempBMP.Assign(Kerzenbitmap);
  TempBMP.Canvas.CopyRect(DestRect, Kerzenbitmap.Canvas, SourceRect);

  Image1.Picture.Assign(tempBMP);
  tempBMP.Free;
end;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文