Akvárium

Príklad
V grafickej ploche -- mori sa budú pohybovať dva druhy zvierat – ryby a dafnie. Ich správanie je nasledujúce -- ryba sa pohybuje v mori a zje dafniu, keď je dosť blízko nej, vtedy ryba trochu narastie. Dafnie sa pohybujú a rodia, keď používateľ kliká myšou do mora, dafnií sa nikdy nie je v mori viac ako 100.

Vytvorme najprv triedu Zviera, do ktorej zahrnieme spoločné atribúty a metódy všetkých zvierat

X a Y -- súradnice zvieraťa
dX, dY -- posúvanie zvieraťa o daný počet bodov v oboch smeroch
metóda Nastav -- inicializačná metóda, ktorá vytvorí zviera na daných súradniciacha a nastaví mu posuny
metóda Pohni -- ktorá pohne zvieraťom tak, aby zostalo vo vnútri grafickej plochy
Potom budú všetky zvieratá na obrazovke objekty triedy Ryba alebo Dafnia. Majú spoločné atribúty a metódy z triedy Zviera, ale navzájom sa odlišujú  – napríklad spôsobom ako sa vykreslia, alebo môžu obsahovať aj niektoré ďalšie vlastnosti.

Aby sme nemuseli viackrát písať rovnaké časti programu, využijeme vlastnosť OOP, ktorú nazývame dedičnosť (po anglicky inheritance).

Zadefinujeme najprv triedu Zviera:
 
type Zviera = class
         X, Y, dX, dY:integer;
         procedure Nastav(nX, nY, ndX, ndY : integer);
         procedure Pohni;
     end;

procedure Zviera.Nastav(nX, nY, ndX, ndY : integer);
begin
  X:=nX; Y:=nY; dX:=ndX; dY:=ndY;
end;

procedure Zviera.Pohni;
begin
  X:=X+dX; Y:=Y+dY;
  if (X<0) or (X>400) then dX:=-dX;
  if (Y<0) or (Y>400) then dY:=-dY;
end;

V triede Zviera sme naprogramovali základné správanie sa zvierat. Teraz sa môžeme zamyslieť nad správaním každého zvieraťa, ktoré chceme oživiť v mori.

Začnime Dafniou. Bude mať vlastnú metódu na vykreslenie, ostatné metódy zdedí od triedy Zviera, teda keď sa zavolá pre nejakú inštanciu triedy metóda Pohni, použije sa metóda predka -- t.j. metóda triedy Zviera.
 
procedure Dafnia.Kresli;
begin
  g.Pixels[X,Y]:=clBlack; // na súradnice X,Y vykreslíme bod (X, Y sme zdedili)
end;

Zadefinovali sme novú triedu Dafnia. Tá obsahuje všetky atribúty a metódy z triedy Zviera a navyše metódu Kresli. Hovoríme, že:

Zadefinujme triedu Ryba, ktorá bude mať zrejme viac metód a jednu premennú.
 
type Ryba = class(Zviera)
       private
         S:integer;
       public
         procedure Nastav(nX, nY, ndX, ndY, nS : integer);
         procedure Kresli;
         function JeBlizko(var d:Dafnia):boolean;
         procedure Rast;
       end;

procedure Ryba.Nastav(nX, nY, ndX, ndY, nS:integer);
begin
  inherited Nastav(nX,nY,ndX,ndY);
  S:=nS;
end;

procedure Ryba.Kresli;
var r : integer;
begin
  r:=round(sqrt(S));
  g.Pen.Color:=clBlue;
  g.Brush.Color:=clBlue;
  g.Ellipse(X-2*r,Y-r,X+2*r,Y+r);
end;

function Ryba.JeBlizko(var d:Dafnia):boolean;
var xx,yy:real;
begin
  xx:=(d.X-X)/2;
  yy:=d.Y-Y;
  Result:=xx*xx+yy*yy<S;
end;

procedure Ryba.Rast;
begin
  S:=S+2;
end;

Pozn.: Hoci potomkovia triedy Zviera majú metódu Kresli, nezadefinovali sme ju v pôvodnej triede Zviera. Mohli sme to urobiť, ale nespravili sme to preto, že to zatiaľ nemá praktický význam – aj tak by sme ju museli pre každého potomka celú prepísať.

Pripravme si premenné tohto projektu
 
var d:array [1..100]of dafnia; // niekoľko dafnií
    r:Ryba;
    poc:integer; 
      // počet dafnií -- bude sa meniť, keď ich ryba bude jesť 
      // alebo keď sa budú vytvárať nové pri klikaní myšou

Do formuláru položme Timer a na jeho tikanie pohnime všetkými objektami v mori:
 
procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
begin
   r.Pohni;
   i:=1;
   while i<poc do
     if not r.JeBlizko(d[i]) then begin d[i].Pohni; inc(i) end
     else begin r.Rast; d[i]:=d[poc]; dec(poc); end;
   g.Pen.Color:=clAqua;
   g.Brush.Color:=clAqua;
   g.Rectangle(0,0,400,400);
   r.Kresli;
   for i:=1 to poc do d[i].Kresli();
end;

Pri pohybe myšou v mori so stlačeným ľavým tlačidlom vygenerujme na príslušnom mieste kliknutia dafniu:
 
procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if (not (ssLeft in Shift)) or (poc=100) or ( X<0 ) or
     ( X>400 )or( Y<0 )or( Y>400) then exit;
  inc(poc);
  d[poc]:=Dafnia.Create;
  d[poc].Nastav(X,Y,1+random(3),random(3));
end;

! Vyskúšajte projekt.
 



materiál vznikol na základe prednášok Ľubomíra Salanciho