Entwickler-Ecke

Sonstiges (Delphi) - Button MouseDown


Soapy - Mi 23.01.08 19:17
Titel: Button MouseDown
So jetzt hab ich wieder ein neues Problem bei meinem Spiel:

Ich will auf einen Button drücken mit dem ich ein Haus bauen kann.
Nun will ich das Haus platzieren - an der Cursorposition, an der der Spieler auf die Karte drückt.
Die Cursorpositionen sind nicht das Problem. Das Problem ist: Wie schaff ich es, dass es mir das Haus genau an dieser Position baut?
Ich hab mir gedacht mit OnMouseDown vielleicht, aber da ich mich damit jedoch nicht besonders gut auskenne, und ich im großen, weiten Internet keine Artikel gefunden haben, die mir weitergeholfen haben, sind meine bisherigen Versuche kläglich gescheitert.


bflegel - Mi 23.01.08 19:31

Hallo,

ich verstehe das Problem zwar nicht ganz, aber wenn Du die Cursorposition hast und Du weist, wie hoch und wie breit Dein Haus ist, dann nimm die Cursorposition doch als Mittelpunkt.


Delphi-Quelltext
1:
2:
Bild.left := Cursorposition.x - (Bildbreite/2)
Bild.Top := Cursorposition.y - (Bildbhöhe/2)


Bye
bflegel


Soapy - Mi 23.01.08 19:35

Ja
aber wenn ich jetzt meine linke Maustaste drücke, dann soll das Haus bei den Koordinaten stehen, bei denen ich die Mausgedrückt habe!
Ich brauch nur zu wissen, wie ich das mit dem Klick mache, die TImages in denen die Bilder sind werden bei einem Klick auf den Button erzeugt!


bflegel - Mi 23.01.08 19:39

Mal sehen ob ich es richtig verstanden habe:

Du hast ein TImage (Karte). Du klickst irgendwo auf die Karte, DANACH auf einen Button und es soll bei den Koordinaten des letzten Klicks ein Haus gebaut werden?

Dann speichere doch im TImageOnMouseClick die Koordinaten z.B. in eine globale Variable und lese diese im Button-Click aus.

Bye
bflegel


Soapy - Mi 23.01.08 19:50

So ähnlich!
Ich klick auf einen Button, dann mit der Maus auf die Karte und dann soll an der Stelle wo ich auf die Karte geklickt hab ein Haus entstehen.

Kannst du mir das mit dem TImageOnMouseDown erklären? Weil ich hab das bisher noch nicht gebraucht und hab leider davon auch keinen blassen schimmer.

Aber Danke für die Antwort!


bflegel - Mi 23.01.08 19:56

Nun, dann sind wir schon zwei. Ich habs auch noch nicht benutzt. Aber da Du zuerst auf den Button "Haus bauen" klickt, setze entweder eine globale Variable z.B. auf "1" (Oder "missbrauche" die Tag-Eigenschaft des TImages zur Speicherung.

Dann im OnMouseDown des TImage fragst Du zuerst ab ob die Variable auf "1" steht und zeichne dann Dein Haus, oder wenn die Variable "2" ist, dann einen Baum, bei "3" einen Strauch usw.

bye
bflegel


Soapy - Mi 23.01.08 20:00

Ok dankeschön! Das werde ich mal ausprobieren!


Soapy - Mi 23.01.08 20:21

hilfeeeeeeeeeeee...
Kann mir jemand erklären wie ich den Code hier -


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;

  Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= CursorPosX;
  FImages[length(FImages)-1].Top:= CursorPosY;
  FImages[length(FImages)-1].Picture.LoadfromFile('Bildpfad');


- in ein OnMouseDown-Ereignis eines TImages richtig einfüge?

Das hier funktioniert so nicht:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Image3MouseDown(Sender:Tobject;Button:TMouseButton;Shift: TShiftState;X, Y: Integer);
var CursorPosX, CursorPosY : integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;

Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= CursorPosX;
  FImages[length(FImages)-1].Top:= CursorPosY;
  FImages[length(FImages)-1].Picture.LoadfromFile('Bildpfad');
end;


Wenn ich das aber jetzt in einem normalen Button ausführe funktioniert es einwandfrei:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button1Click(Sender: TObject);
var CursorPosX, CursorPosY : integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;

Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= 50;
  FImages[length(FImages)-1].Top:= 50;
  FImages[length(FImages)-1].Picture.LoadfromFile('Bildpfad');
Image1.Visible := true;
end;


bflegel - Mi 23.01.08 20:32

Auf die Schnelle würde ich sagen:


Delphi-Quelltext
1:
2:
FImages[length(FImages)-1].Left:= CursorPosX;
FImages[length(FImages)-1].Top:= CursorPosY;


und

Delphi-Quelltext
1:
2:
FImages[length(FImages)-1].Left:= 50;
FImages[length(FImages)-1].Top:= 50;


ist nicht ganz dasselbe.

Daher dürfte er das Image irgendwohin setzen, aber nicht dahin, wo Du möchtest.

bflegel


Yogu - Mi 23.01.08 20:40

Du bekommst die Client-Koordinaten der Maus doch schon per Parameter beim Ereignis überliefert - warum rufst du die dannn noch mal ab? Du kannst einfach X und Y nehmen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Image3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= X+25
  FImages[length(FImages)-1].Top:= Y+10;
  FImages[length(FImages)-1].Picture.LoadfromFile('Bildpfad');
end;


Soapy - Mi 23.01.08 21:04

Danke, euch beiden!
So nun hab ich es auf Yogu's weise probiert...

... und es tut immer noch nicht *heul*

So sieht mein Quelltext aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Menus, StdCtrls, Tabs, ComCtrls, jpeg, ImgList;

type
  TForm1 = class(TForm)
    PopupMenu1: TPopupMenu;
    Timer1: TTimer;
    Schliessen: TMenuItem;
    Label3: TLabel;
    ScrollBox2: TScrollBox;
    Image2: TImage;
    Label2: TLabel;
    ScrollBox3: TScrollBox;
    Image3: TImage;
    Label1: TLabel;
    TabControl1: TTabControl;
    Haus1: TButton;
    Haus2: TButton;
    Haus3: TButton;
    Haus4: TButton;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Timer2: TTimer;
    Image1: TImage;
    procedure Timer2Timer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Haus1Click(Sender: TObject);
    procedure TabControl1Change(Sender: TObject);
    procedure SchliessenClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Image3MouseDown(Sender:Tobject;Button:TMouseButton;Shift: TShiftState;X, Y: Integer);
  private
   FImages: array of Timage;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
{  procedure AI(IntiligenzEinfach : integer);}


  implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
ScrollBox2.Left := Scrollbox3.Width-300;
Scrollbox3.Width := Screen.Width+5;
Scrollbox3.Height := Screen.Height+3;
Scrollbox2.Parent := Scrollbox3;
Form1.Height := Screen.Height+5;
TabControl1.Left := Screen.Width - (TabControl1.Width + 50);
Button1.Visible:= False;
Button2.Visible:= False;
Button3.Visible:= False;
Button4.Visible:= False;
Image1.Visible := False;
end;

procedure TForm1.SchliessenClick(Sender: TObject);
begin
Form1.Close;
end;

procedure TForm1.TabControl1Change(Sender: TObject);
begin
If TabControl1.TabIndex= 0 Then
begin
Haus1.Visible:= True;
Haus2.Visible:= True;
Haus3.Visible:= True;
Haus4.Visible:= True;
end
else
begin
Haus1.Visible:= False;
Haus2.Visible:= False;
Haus3.Visible:= False;
Haus4.Visible:= False;
end;

If TabControl1.TabIndex= 1 Then
begin
Button1.Visible:= True;
Button2.Visible:= True;
Button3.Visible:= True;
Button4.Visible:= True;
end
else
begin
Button1.Visible:= False;
Button2.Visible:= False;
Button3.Visible:= False;
Button4.Visible:= False;
end;

end;

procedure TForm1.Haus1Click(Sender: TObject);
begin
Form1.Close;
end;

procedure TForm1.Button1Click(Sender: TObject);
var CursorPosX, CursorPosY : integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;

Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= 50;
  FImages[length(FImages)-1].Top:= 50;
  FImages[length(FImages)-1].Picture.LoadfromFile('C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\staemme.jpg');
Image1.Visible := true;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var Component: TComponent;
            i: integer;
begin
  for i:= 1 to length(Fimages) do begin
      Component:= FindComponent('Image'+Inttostr(i));
      if assigned(Component) then
         (Component as TImage).Free;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
ScrollBox2.Left := Scrollbox3.Width-300;
TabControl1.Left := Screen.Width - (TabControl1.Width + 50);

if odd(GetAsyncKeyState (VK_Escape)) then
begin
PopUpMenu1.Popup(50,50);
end;

if boolean(getasynckeystate(ord('K'))) then
Scrollbox2.Visible := not Scrollbox2.Visible;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
var CursorPosX, CursorPosY : integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;


Image1.Left := CursorPosX-(Image1.Width div 2);
Image1.Top := CursorPosY-(Image1.Height div 2);

  If Image3.Left < 150 Then
  begin
  If CursorPosX < 10 Then
  Image3.Left := Image3.Left+15;
  end;


  If Image3.Left > -(Image3.Width-Screen.Width+150Then
  begin
  If CursorPosX > Screen.Width-10 Then
  Image3.Left := Image3.Left-15;
  If Image3.Left > Image3.Width+150 Then

  end;


  If Image3.Top < 150 Then
  begin
  If CursorPosY < 10 Then
  Image3.Top := Image3.Top+15;
  end;


  If Image3.Top > -(Image3.Height-Screen.Height+150Then
  begin
  If CursorPosY > Screen.Height-10 Then
  Image3.Top := Image3.Top-15;
  end;
end;

procedure TForm1.Image3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages)); 
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50
  FImages[length(FImages)-1].Left:= X;
  FImages[length(FImages)-1].Top:= Y;
  FImages[length(FImages)-1].Picture.LoadfromFile('C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\staemme.jpg');
end;

end.


Sieht jemand einen Fehler?


Yogu - Mi 23.01.08 21:49

user profile iconSoapy hat folgendes geschrieben:
... und es tut immer noch nicht

Aha. Es tut immer noch nicht. Wenn ich meine Glaskugel nicht gerade eben verloren hätte, dann wüsste ich jetzt, was dieser Fehler ist. Weil die Glaskugel jedoch gerade nicht da ist, wärst du so nett, und erklärst, worin genau dieser Fehler besteht?


Soapy - Mi 23.01.08 21:52

Tut mir Leid!
Der Fehler ist der, dass es wenn ich jetzt einen Mausklick mache, das Bild immer noch nicht erscheint!
Wenn ich allerdings auf den Button1 klicke funktioniert alles!


Yogu - Mi 23.01.08 21:55

Warum regelst du das Klicken über ein Image, wenn du das Symbol "staemme.jpg" dann doch auf einer ScrollBox anzeigen lässt? Es kann sein, dass dein Image das "stämme.jpg" überdeckt. Oder ist das Image3 gar nicht in der ScrollBox? Dann kann das gar nicht klappen.

Regel das ganze am bestem beim Klick auf die Scrollbox.


Soapy - Mi 23.01.08 21:59

Das Image ist in der Scrollbox!
Das staemme.jpg wird aber nicht überdeckt von meiner Karte... Ich hab die Karte nämlich auf visible := false gesetzt und dann gings immernoch nicht!


Xentar - Mi 23.01.08 22:02

Ist die Karte dein Image3? Gib den Komponenten mal vernünftige Namen..

wenn ja:
wenn du die Karte auf visible := false setzt, wird soweit ich weiß auch das MouseDown Event nicht mehr aufgerufen...
Hast du mal einen Haltepunkt gesetzt, ob der da überhaupt durchläuft?


Yogu - Mi 23.01.08 22:02

user profile iconSoapy hat folgendes geschrieben:
Ich hab die Karte nämlich auf visible := false gesetzt

Daran liegt es wahrscheinlich. Wenn das Image ausgeblendet ist, auf das du klicken willst, passiert auch nichts.

Mist, zu langsam :P


Soapy - Mi 23.01.08 22:27

Ja aber als ich es ausgeblendet habe hab ich auch den Code von Image3mousedown in scrollbox3mousedown geändert!
Außerdem wird das Bild nicht verdeckt, da es mit dem gleichen Code von Button1Click auch nicht verdeckt wird!
Oh man...
ich verzweifel noch!


Xentar - Mi 23.01.08 22:29

user profile iconSoapy hat folgendes geschrieben:
Ja aber als ich es ausgeblendet habe hab ich auch den Code von Image3mousedown in scrollbox3mousedown geändert!


Hast du da einfach nur die Bezeichnung verändert, oder auch das Event neu zugewiesen, nämlich an die Scrollbox?


Soapy - Mi 23.01.08 22:31


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Image3MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages)); 
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50
  FImages[length(FImages)-1].Left:= X;
  FImages[length(FImages)-1].Top:= Y;
  FImages[length(FImages)-1].Picture.LoadfromFile('C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\staemme.jpg');
  Image3.Visible := false;
end;


So und oben neu deklariert!


Soapy - Mi 23.01.08 22:41

Ich habe es jetzt so gelöst:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Image3Click(Sender: TObject);
var CursorPosX, CursorPosY:integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;
Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= CursorPosX;
  FImages[length(FImages)-1].Top:= CursorPosY;
  FImages[length(FImages)-1].Picture.LoadfromFile('C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\staemme.jpg');
  Image3.Visible := false;
end;


Nur wenn ich jetzt auf das Image3 klicke, wird es deaktiviert?!?!?! Ach Gott... Wie ich es hasse!


Soapy - Mi 23.01.08 22:51

Juhu ich habs!
Vielen Dank für eure Antworten und Lösungsversuche!

Meine Lösung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Image3Click(Sender: TObject);
var CursorPosX, CursorPosY:integer;
begin
Cursorposx := ScreenToClient(Mouse.CursorPos).X;
cursorposy := ScreenToClient(Mouse.CursorPos).Y;
Setlength(FImages, length(FImages)+1);
  FImages[length(FImages)-1]:= TImage.Create(self);
  FImages[length(FImages)-1].Name:= 'Kaserne'+InttoStr(length(FImages));
  FImages[length(FImages)-1].Parent:= Scrollbox3;
  FImages[length(FImages)-1].height:= 20;
  FImages[length(FImages)-1].width:= 50;
  FImages[length(FImages)-1].Left:= CursorPosX;
  FImages[length(FImages)-1].Top:= CursorPosY;
  FImages[length(FImages)-1].Picture.LoadfromFile('C:\Dokumente und Einstellungen\Philipp\Eigene Dateien\staemme.jpg');
  Image3.Enabled := false;
  Image3.Visible := true;
end;