1. Opakovanie
Domovská stránka Programovanie v C++ OOP a Windows Ročníkový projekt Princípy počítačov Princípy databáz Všeličo Kontakt

 

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