Piszę prostą grę w Delphi. Mam procedurę OnClick, powiązaną z dynamicznie tworzonym obrazkiem TImage. Jak przekazać w tej procedurze, który obrazek został kliknięty?
(Sender as TImage)
Żeby nie być gołosłownym, zamieszczam rzeczone fragmenty kodu.
Oto słynny OnClick:
procedure TGameEngine.Image1Click(Sender: TObject); //po kliknięciu na planetę wyświetla okno informacyjne
var
OknoPlanety : TForm;
ObrazekPlanety : TImage;
Nazwa : TLabel;
Current : Byte;
begin
OknoPlanety := TForm.Create(GameEngine);
OknoPlanety.Parent := GameEngine;
OknoPlanety.Visible := True;
OknoPlanety.Caption := 'Podgląd planety - ' + planety[Current].Nazwa;
OknoPlanety.Height := 500;
OknoPlanety.Width :=500;
OknoPlanety.Color := clBlack;
ObrazekPlanety := TImage.Create(GameEngine);
ObrazekPlanety.Parent := OknoPlanety;
ObrazekPlanety.Left := 15;
ObrazekPlanety. Top := 15;
ObrazekPlanety.Height := 200;
ObrazekPlanety.Width := 200;
ObrazekPlanety.Picture.LoadFromFile('Images/Planeta'+inttostr(Current)+'Big.bmp');
Nazwa := TLabel.Create(GameEngine);
Nazwa.Parent := OknoPlanety;
Nazwa.Caption := 'Nazwa planety: ' + planety[Current].Nazwa;
Nazwa.Font.Color := clWhite;
Nazwa.Font.Size := 12;
Nazwa.Left := 250;
Nazwa.Top := 25;
Nazwa := TLabel.Create(GameEngine);
Nazwa.Parent := OknoPlanety;
Nazwa.Caption := 'Temp. minimalna: ' + inttostr(planety[Current].TempMin);
Nazwa.Font.Color := clWhite;
Nazwa.Font.Size := 12;
Nazwa.Left := 250;
Nazwa.Top := 55;
Nazwa := TLabel.Create(GameEngine);
Nazwa.Parent := OknoPlanety;
Nazwa.Caption := 'Temp. maksymalna: ' + inttostr(planety[Current].TempMax);
Nazwa.Font.Color := clWhite;
Nazwa.Font.Size := 12;
Nazwa.Left := 250;
Nazwa.Top := 85;
Nazwa := TLabel.Create(GameEngine);
Nazwa.Parent := OknoPlanety;
Nazwa.Caption := 'Liczba pól: ' + inttostr(planety[Current].Pola);
Nazwa.Font.Color := clWhite;
Nazwa.Font.Size := 12;
Nazwa.Left := 250;
Nazwa.Top := 115;
end;
A oto cała procedura tworząca planetę:
procedure TGameEngine.MakePlanet (var a: TSiatka; d: TPlanetImage);
var
i, j, k: byte;
b, c: byte;
w : array[1..MapSize,1..MapSize] of byte; //tablica współrzędnych
begin
randomize;
for i := 1 to MapSize do //zerowanie tablicy współrzędnych
for j := 1 to MapSize do
w[i,j] := 0;
for k := 1 to IlePlanet do
begin
b := random(MapSize)+1;
c := random(MapSize)+1;
if w[b,c] = 1 then
begin
continue;
end
else
begin
with planety[k] do
begin
Nazwa := 'Jowisz';
TempMin := random(5)-100;
TempMax := random(80)+10;
Pola := random(200)+55;
PosX := b;
PosY := c;
ID := k;
end;
w[b,c] := 1; //to pole jest zajęte
a[b,c].Picture.LoadFromFile(d[k]);
a[b,c].OnClick := Image1Click;
end;
end;
end;
Na samym końcu dowiązuję procedurę Image1Click do każdej utworzonej planety. Co chcę zrobić? Chcę, żeby kliknięcie danej planety skutkowało wyświetleniem adekwatnych danych w nowym okienku. Jak więc przekazać, na danym przykładzie, do procedury Image1Click, która z planet została kliknięta? Jeżeli sender as TImage tutaj wystarczy, to prosiłbym o wskazanie jak go użyć.
Dla każdego tworzonego dynamicznie TImage dla każdej planety dodajesz tą samą procedurę dla OnClick.
A w tej procedurze korzystasz z rady Miśka:
(Sender as TImage)
gdzie (Sender as TImage) będzie właśnie obrazkiem klikniętej planety
Z (Sender as TImage) możesz potem korzystać dowolnie:
np.
(Sender as TImage).Height := 50;
czy
(Sender as TImage).WyświetlDane;
Możesz też rzutować
TImage(Sender) to jest to samo co (Sender as TImage)
RudyBestyj napisał(a)
Z (Sender as TImage) możesz potem korzystać dowolnie:
np.
(Sender as TImage).Height := 50;
czy
(Sender as TImage).WyświetlDane;
do czegoś takiego trzeba obiektowo pisać - tu nie przejdzie
TImage(Sender) to jest to samo co (Sender as TImage)
nie do końca - as sprawdza typy, a twarde rzutowanie nie
i := 1;
niema := true;
while (i <= MapSize) and niema do
begin
j := 1;
while (j <= MapSize) and niema do
begin
if a[i,j] = Sender then
niema := false;
Inc(j);
end;
Inc(i);
end;
if not niema then
begin
dec(i);
dec(j);
//adres obrazka masz w i, j
end;
Dziękować, te rady mogą się bardzo przydać. Już implementuję.
Sorry za double post, ale chcę jeszcze odnieść się do początkowej, gwałtownej wymiany zdań - mamy tu bowiem dupne nieporozumienie. Mianowicie nie zauważyłem separatora między treścią posta i podpisem Miśka mówiącym coś o głupocie ludzi korzystających z neta... Wziąłem podpis za dalszą część posta, stąd moja poniekąd przesadna reakcja. Cóż mogę rzec - zły dzień dziś miałem, palnąłem głupotę, mam nadzieję że Misiek przyjmie szczere przeprosiny. I jeszcze raz za rady dziękuję, ale dziś już nie implementuję, spać mi się chce :-)
A ja mam jeszcze prostszą radę.
Rozwijając pomysł Miśka - po co definiować n obrazków i tyleż procedur. Lepiej dać jeden TImage, jedną procedurę OnClick, a w niej - sprawdzać koordynaty klikniętego miejsca. Szybciej, prościej, mniej pamięciożernie :)
Dzięki za radę, ale problem jest już rozwiązany i wszystko śmiga :-) A oto fragment działającego kodu z implementacją rady Miśka.
procedure TGameEngine.PlanetClick(Sender: TObject); //po kliknięciu na planetę wyświetla okno informacyjne
var
PlanetWindow : TForm;
PlanetImage : TImage;
Label1 : TLabel;
Buildings, Defense, Fleet : TButton;
begin
PlanetWindow := TForm.Create(GameEngine);
PlanetWindow.Parent := GameEngine;
PlanetWindow.Visible := True;
PlanetWindow.Caption := 'Podgląd planety - ' + (Sender as TPlanetClass).Planets.Name;
PlanetWindow.Height := 500;
PlanetWindow.Width :=600;
PlanetWindow.Color := clBlack;
PlanetImage := TImage.Create(GameEngine);
PlanetImage.Parent := PlanetWindow;
PlanetImage.Left := 15;
PlanetImage. Top := 15;
PlanetImage.Height := 200;
PlanetImage.Width := 200;
PlanetImage.Picture.LoadFromFile((Sender as TPlanetClass).Planets.BigImageSource);
Label1 := TLabel.Create(GameEngine);
Label1.Parent := PlanetWindow;
Label1.Caption := 'Nazwa planety: ' + (Sender as TPlanetClass).Planets.Name;
Label1.Font.Color := clWhite;
Label1.Font.Size := 12;
Label1.Left := 250;
Label1.Top := 25;
[...]
I tak dalej :-) Jeszcze raz - dzięki za pomoc!