Author: Tomas Rutkauskas
I'm planning to make an isometric map based game. Now, to do this, I need to know
if the user clicked on one (or more) squares, for example, a building or a
creature. I cannot figure out how to do this.
Answer:
Create a new project. On the form, create a TImage and align it to client. Also
assign the form's OnCreate event, and the Image's OnMouseUp and OnMouseDown events.
Paste this code into Unit1 and run. A 10x10 grid will be drawn. Click in it to
highlight a square.
1 unit Unit1;
2
3 interface
4
5 uses
6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 ExtCtrls;
8
9 type
10 TForm1 = class(TForm)
11 Image1: TImage;
12 procedure FormCreate(Sender: TObject);
13 procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
14 Shift: TShiftState; X, Y: Integer);
15 procedure Image1MouseUp(Sender: TObject; Button: TMouseButton;
16 Shift: TShiftState; X, Y: Integer);
17 procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
18 private
19 public
20 end;
21
22 var
23 Form1: TForm1;
24
25 implementation
26
27 uses
28 Math;
29
30 {$R *.DFM}
31
32 var
33 XC: Integer;
34 YC: Integer;
35 LastX: Single;
36 LastY: Single;
37
38 const
39 Scale = 20;
40
41 procedure Map(const WorldX: Single; const WorldY: Single; out DisplayX: Integer;
42 out DisplayY: Integer);
43 begin
44 DisplayX := Round(XC + Scale * (WorldX - WorldY) * 0.5 * Sqrt(3));
45 DisplayY := Round(YC + Scale * (WorldX + WorldY) * 0.5);
46 end;
47
48 procedure UnMap(const DisplayX: Integer; const DisplayY: Integer; out WorldX:
49 Single;
50 out WorldY: Single);
51 var
52 Sum: Single;
53 Diff: Single;
54 begin
55 Diff := (DisplayX - XC) / (0.5 * Scale * Sqrt(3));
56 Sum := (DisplayY - YC) / (0.5 * Scale);
57 WorldY := (Sum - Diff) / 2;
58 WorldX := Sum - WorldY;
59 end;
60
61 procedure TForm1.FormCreate(Sender: TObject);
62 var
63 I: Integer;
64 X1: Integer;
65 Y1: Integer;
66 X2: Integer;
67 Y2: Integer;
68 begin
69 XC := ClientWidth div 2;
70 YC := ClientHeight div 2;
71 with Image1.Picture.Bitmap do
72 begin
73 Width := Image1.Width;
74 Height := Image1.Height;
75 end;
76 for I := -5 to 5 do
77 begin
78 Map(I, 5, X1, Y1);
79 Map(I, -5, X2, Y2);
80 with Image1.Picture.Bitmap.Canvas do
81 begin
82 MoveTo(X1, Y1);
83 LineTo(X2, Y2);
84 end;
85 Map(5, I, X1, Y1);
86 Map(-5, I, X2, Y2);
87 with Image1.Picture.Bitmap.Canvas do
88 begin
89 MoveTo(X1, Y1);
90 LineTo(X2, Y2);
91 end;
92 end;
93 end;
94
95 procedure ColorizeCell(const Color: TColor);
96 var
97 PolygonData: array[0..3] of TPoint;
98 begin
99 if ((Abs(LastX) < 5) and (Abs(LastY) < 5)) then
100 begin
101 Map(Floor(LastX), Floor(LastY), PolygonData[0].X, PolygonData[0].Y);
102 Map(Floor(LastX), Ceil(LastY), PolygonData[1].X, PolygonData[1].Y);
103 Map(Ceil(LastX), Ceil(LastY), PolygonData[2].X, PolygonData[2].Y);
104 Map(Ceil(LastX), Floor(LastY), PolygonData[3].X, PolygonData[3].Y);
105 with Form1.Image1.Picture.Bitmap.Canvas do
106 begin
107 Brush.Style := bsSolid;
108 Brush.Color := Color;
109 Polygon(PolygonData);
110 end;
111 end;
112 end;
113
114 procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
115 Shift: TShiftState; X, Y: Integer);
116 begin
117 Unmap(X, Y, LastX, LastY);
118 ColorizeCell(clRed);
119 end;
120
121 procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
122 Shift: TShiftState; X, Y: Integer);
123 begin
124 ColorizeCell(clWhite);
125 end;
126
127 procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y:
128 Integer);
129 begin
130 ColorizeCell(clWhite);
131 Unmap(X, Y, LastX, LastY);
132 ColorizeCell(clYellow);
133 end;
134
135 end.
|