开发者

Canvas/Bitmap scrolling question

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 sc开发者_运维技巧roll right/left/up/down just like an ordinary image viewer, however I can't seem to find what I'm looking for. Any ideas?


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.


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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜