1. Opakovanie |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Vytvoríme objektovú triedu TSkelet, pomocou ktorej budeme skladať kostru rôznych tvorov. Táto objektová trieda navyše umožní animovať kostru a jej jednotlivé časti. Pritom si zopakujeme:
Analýza a návrh
Zachytiť celé postavu človeka, ale aj zvieratka, je veľmi komplikované. Preto ju zjednodušíme na niekoľko častí - hlava, krk, ruky, trup, nohy:
Kostra pripomína n-árny strom:
Jednotlivé kosti takto zjednodušeného modelu kostry môžu byť sú "zavesené" na iných kostiach:
V reči n-árnych stromov by sme skôr povedali:
Ak chceme kostru zobrazovať na obrazovke, mať každá kostička bod, do ktorého sú zavesené detské kosti.
Zhrnutie: od každého objektu typu TSkelet potrebujeme:
Implementácia
V unit-e Skelet zadefinujem triedu TSkelet:
unit Skelet; interface uses // zoznam knižníc type TSkelet=class private // súkromné metódy, stavové premenné protected // chránené metódy, stavové premenné a vlastnosti public // verejné metódy, stavové premenné a vlastnosti end; implementation // implementácia metód end. |
Celá objektová trieda:
unit Skelet; interface uses Windows, Messages, SysUtils, Classes, Graphics; type TSkelet=class private FParent: TSkelet; FdX, FdY: Integer; FX, FY: Integer; FChilds: TList; function GetChild(Index: Integer): TSkelet; function GetChildCount: Integer; protected procedure DoStep; virtual; procedure DoPaint(Canvas: TCanvas); virtual; public constructor Create(Parent: TSkelet; dX, dY: Integer); destructor Destroy; override; procedure Step; procedure Paint(Canvas: TCanvas); property Parent: TSkelet read FParent; property dX: Integer read FdX write FdX; property dY: Integer read FdY write FdY; property X: Integer read FX write FX; property Y: Integer read FY write FY; property Childs[Index: Integer]: TSkelet read GetChild; property ChildCount: Integer read GetChildCount; end; implementation // TSkelet - public: constructor TSkelet.Create(Parent: TSkelet; dX, dY: Integer); begin inherited Create; FParent:=Parent; FdX:=dX; FdY:=dY; FChilds:=TList.Create; if FParent<>nil then FParent.FChilds.Add(Self); end; destructor TSkelet.Destroy; begin if FParent<>nil then FParent.FChilds.Remove(Self); if FChilds<>nil then begin while FChilds.Count>0 do TSkelet(FChilds[FChilds.Count-1]).Free; FChilds.Free; end; inherited; end; procedure TSkelet.Step; var Index: Integer; begin DoStep; for Index:=0 to FChilds.Count-1 do TSkelet(FChilds[Index]).Step; end; procedure TSkelet.Paint(Canvas: TCanvas); var Index: Integer; begin DoPaint(Canvas); for Index:=0 to FChilds.Count-1 do TSkelet(FChilds[Index]).Paint(Canvas); end; // TSkelet - protected: procedure TSkelet.DoStep; begin if Parent=nil then begin X:=dX; Y:=dY; end else begin X:=Parent.X+dX; Y:=Parent.Y+dY; end; end; procedure TSkelet.DoPaint(Canvas: TCanvas); begin if Parent=nil then Canvas.Ellipse(X-4, Y-4, X+4, Y+4) else begin Canvas.MoveTo(Parent.X, Parent.Y); Canvas.LineTo(X, Y); end; end; // TSkelet - private: function TSkelet.GetChild(Index: Integer): TSkelet; begin Result:=FChilds[Index]; end; function TSkelet.GetChildCount: Integer; begin Result:=FChilds.Count; end; |
Ukážka použitia:
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Skelet; type TForm1 = class(TForm) Image1: TImage; Timer1: TTimer; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private // Private declarations: Hlava: TSkelet; public // Public declarations: end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.FormCreate(Sender: TObject); var Krk, Trup: TSkelet; begin Hlava:=TSkelet.Create(nil, Image1.Width div 2, Image1.Height div 7); Krk:= TSkelet.Create(Hlava, 0, 10); TSkelet.Create(Krk, -20, 50); TSkelet.Create(Krk, +20, 50); Trup:= TSkelet.Create(Krk, 0, 70); TSkelet.Create(Trup, -20, 70); TSkelet.Create(Trup, +20, 70); Hlava.Step; Hlava.Paint(Image1.Canvas); end; procedure TForm1.FormDestroy(Sender: TObject); begin Hlava.Free; end; end. |
© 2004 Ľubomír SALANCI