unit mTBewegteUhr;
{ Änderungen von West. Zeigt die 'echte' Zeit einschl. Sekunden an.}
{ Änderungen vom 30.08.2006 und vom 23.09.2008
Übergeben werden Mittelpunktskoordinaten und Radius.
Die Uhr kann auf einem Hintergrund mit beliebiger Farbe dargestellt werden! }
{Übung 14.3}
interface
uses Forms,
{TForm}
ExtCtrls,
{TTimer}
Graphics,
{TCanvas}
SysUtils;
{Zeitmethoden}
type TUhr =
class (TObject)
protected
kContainer: TForm;
{ Formular, auf dem gezeichnet wird }
zX, zY, zBreite: Integer;
{ Für Canvas-Methode 'Ellipse' benötigt }
zXM, zYM, zRadius: Integer;
{ Mittelpunktskoordinaten }
hZeit: TTimer;
{ Holt die Zeit (zum Stellen der Uhr) }
zStd,zMin, zSec, SMSec: Word;
procedure ZeitAnzeigen (Sender:TObject);
procedure Zeichnen(color: TColor);
public
constructor Create(XM, YM, Radius: integer);
destructor Destroy;
procedure Kennt (Container: TForm);
procedure Zeigen;
procedure Loeschen;
end;
type TBewegteUhr =
class(TUhr)
private
vx, vy: integer;
procedure Bewegen (Sender:TObject);
public
constructor Create(XM, YM, Radius: integer);
end;
implementation
(* ****************************** TBewegteUhr **************************** *)
constructor TBewegteUhr.Create(XM, YM, Radius: integer);
begin
randomize;
inherited create(XM, YM, Radius);
vx:= -5+random(11);
vy:= -5+random(11);
hZeit.OnTimer:= Bewegen;
hZeit.Enabled:= true;
hZeit.Interval:= 30;
// auch 1 ist möglich
end;
procedure TBewegteUhr.Bewegen(Sender:TObject);
begin
Loeschen;
{Bei Reflexion gehen vx und vy in -vx bzw. -vy über - Impulserhaltungssatz}
if zXM < zRadius
then vx:= -vx;
if zXM > (kContainer.ClientWidth - zRadius)
then vx:= -vx;
if zYM < zRadius
then vy:= -vy;
if zYM > (kContainer.ClientHeight - zRadius)
then vy:= -vy;
zXM:= zXM + vx;
zYM:= zYM + vy;
DecodeTime(Time, zStd, zMin, zSec, SMSec);
// zStd:= 23; // nur für Testzwecke!
// zMin:= 60; // nur für Testzwecke!
// zSec:= 45; // nur für Testzwecke!
Zeigen;
end;
(* alternativ bei der Reflexion:
procedure TBewegteUhr.Bewegen(Sender:TObject);
begin
Loeschen;
{Bei Reflexion gehen vx und vy in -vx bzw. -vy über - Impulserhaltungssatz}
if zXM < zRadius then vx:= abs(vx);
if zXM > (kContainer.ClientWidth - zRadius) then vx:= -abs(vx);
if zYM < zRadius then vy:= abs(vy);
if zYM > (kContainer.ClientHeight - zRadius) then vy:= -abs(vy);
zXM:= zXM + vx;
zYM:= zYM + vy;
DecodeTime(Time, zStd, zMin, zSec, SMSec);
// zStd:= 23; // nur für Testzwecke!
// zMin:= 60; // nur für Testzwecke!
// zSec:= 45; // nur für Testzwecke!
Zeigen;
end; *)
(* ****************************** TUhr *********************************** *)
constructor TUhr.Create (XM, YM, Radius: Integer);
begin
inherited Create;
zXM:= XM;
zYM:= YM;
zRadius:= Radius;
DecodeTime(Time, zStd, zMin, zSec, SMSec);
// In der Online-Hilfe nachschauen!
// zStd:= 23; // nur für Testzwecke!
// zMin:= 60; // nur für Testzwecke!
// zSec:= 45; // nur für Testzwecke!
hZeit := TTimer.Create (
nil);
hZeit.Interval := 1000;
hZeit.Enabled := False;
hZeit.OnTimer := ZeitAnzeigen;
end;
destructor TUhr.Destroy;
begin
Loeschen;
hZeit.Enabled := False;
// muss unbedingt geschehen!
hZeit.Destroy;
inherited Destroy;
end;
procedure TUhr.Kennt (Container: TForm);
begin
kContainer := Container;
end;
procedure TUhr.Zeichnen(color: Tcolor);
var StdWinkel, MinWinkel, SekWinkel: real;
x, y: integer;
begin
with kContainer.Canvas
do begin
Pen.Color := color;
// Brush.Color:= clWhite;
Brush.Style:= bsclear;
// Hintergrund in Containerfarbe
Pen.Width := 2;
zX := zXM - zRadius;
zY := zYM + zRadius;
zBreite := 2*zRadius;
// Breite = Durchmesser der Uhr
Ellipse (zX,zY,zX+zBreite,zY-zBreite);
{großer Zeiger = Minutenzeiger}
MoveTo (zXM,zYM);
MinWinkel:= (zMin/60)*2*Pi;
x:= zXM+Round(sin(MinWinkel)*0.9*zRadius);
y:= zYM-Round(cos(MinWinkel)*0.9*zRadius);
LineTo (x, y);
{kleiner Zeiger = Stundenzeiger}
MoveTo (zXM,zYM);
if zStd >= 12
then zStd := zStd - 12;
StdWinkel:= (zStd/12 + zMin/720)*2*Pi;
x:= zXM+Round(sin(StdWinkel)*0.6*zRadius);
y:= zYM-Round(cos(StdWinkel)*0.6*zRadius);
LineTo (x, y);
{Sekundenzeiger}
Pen.Width := 1;
MoveTo (zXM,zYM);
SekWinkel:= (zSec/60)*2*Pi;
x:= zXM+Round(sin(SekWinkel)*0.9*zRadius);
y:= zYM-Round(cos(SekWinkel)*0.9*zRadius);
LineTo (x, y);
end;
end;
procedure TUhr.Zeigen;
begin
Zeichnen(clBlack);
hZeit.Enabled:= true;
end;
procedure TUhr.ZeitAnzeigen (Sender:TObject);
begin
Loeschen;
DecodeTime(Time, zStd, zMin, zSec, SMSec);
// zStd:= 23; // nur für Testzwecke!
// zMin:= 60; // nur für Testzwecke!
// zSec:= 45; // nur für Testzwecke!
Zeigen;
end;
procedure TUhr.Loeschen;
begin
hZeit.Enabled:= false;
Zeichnen(kContainer.Color);
end;
end.