Jak przekazać zmienną w procedurze typu Event?

0

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?

0

(Sender as TImage)

0

Ż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ć.

0

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)

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

Dziękować, te rady mogą się bardzo przydać. Już implementuję.

0

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 :-)

0

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 :)

0

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!

1 użytkowników online, w tym zalogowanych: 0, gości: 1