Informaticasite van het Lauwers College te Buitenpost                 © R.J. van der Beek
 

Delphi Hoofdstuk 5. Een figuur laten bewegen.

  5.1 Een figuur naar rechts laten bewegen.

We willen een formulier dat er als volgt uitziet:
We laten in dit formulier een figuur bewegen.

Zet bovenaan in het formulier een label en noem die lblBeweeg
Onderaan zet je een button met het opschrift "stop", noem die cmdStop.

Het formulier zelf noemen we frmBeweeg. Dat doe je door in het properties-venster van het formulier (klik eerst op een leeg gedeelte van het formulier, en ga dan naar het properties-venster) op name te klikken, en daar als naam frmBeweeg in te voeren.
Voor bij CaptionBeweging in, dat verschijnt dan in de titelbalk. En je kunt ook een achtergrondkleurtje voor het formulier uitkiezen door op Color te klikken.

Klik dan in de toolbox op de wekker (dat is de zogenaamde "timer", zie hier linksonder) TTimer, en zet die ergens op het formulier.

Die wekker zie je wel in het ontwerpscherm, maar niet als het programma echt loopt.

Zet in het propertiesvenster van de timer Interval op 10.
Daarmee stel je in dat er om de 10 milliseconden iets gebeurt, en wat dan wel, dat zie je hierna.
En "Enabled" zet je op true, want als die op false staat dan is de timer niet geactiveerd, en dan gebeurt er niets.

Dubbelklik in het ontwerpformulier op de timer, dan kun je programmaregels invoeren. En wat daar staat, dat wordt om de 10 milliseconden uitgevoerd. Telkens als er weer 10 millisec. om zijn dan "loopt de wekker af", en dan gaat de computer uitvoeren wat hier in de procedure onder timer staat.

Tik eerst maar eens het volgende in: lblBeweeg.left := lblBeweeg.left + 100;

Als je het programma dan laat lopen dan zul je merken dat de label naar rechts beweegt.

In lblBeweeg.left wordt namelijk vastgelegd hoeveel pixels de linker-rand van de label van de linkerrand van het formulier verwijderd is.
En daar wordt om de 10 milliseconden 10 bij opgeteld, dus schuift hij op naar rechts.
Als je in de procedure onder timer het volgende intikt:
lblBeweeg.left := lblBeweeg.left + 10;
lblBeweeg.top := lblBeweeg.top + 5;
dan verschuift de label scheef naar beneden: hij gaat naar rechts en tegelijk naar beneden,want met lblBeweeg.top wordt vastgelegd hoeveel pixels de boven-rand van de label van de bovenrand van het formulier verwijderd is.

  5.2 Heen en weer bewegen.

Op een gegeven moment verdwijnt de label uit beeld.

Het zou mooier zijn dat hij, als hij aan de rechter rand toe is, de andere kant op gaat.
Dat kunnen we ook wel programmeren, maar dat wordt wel wat ingewikkelder.
We moeten dan bijhouden of de label naar rechts moet of naar links.
Dat leggen we vast in de variabele "rechts".
Als die variabele de waarde true heeft betekent dat dat de label naar rechts moet bewegen, en als hij de waarde false heeft dan moet de label naar links bewegen.
De variabele rechts is dus van het type boolean.

Als rechts gelijk is aan true, dan moet de opdracht zijn :
lblBeweeg.left := lblBeweeg.left + 10; ,
en anders moet de opdracht zijn: lblBeweeg.left := lblBeweeg.left - 10;

Verder moet nog bekeken worden wanneer de richting om moet draaien.

Veranderen van links naar rechts moet gebeuren als de box net voorbij de linker rand komt, dus als geldt: lblBeweeg.left < 0

Veranderen van rechts naar links moet gebeuren als de label net voorbij de rechter rand komt.
Maar lblBeweeg.Right bestaat niet, alleen lblBeweeg.Left.
Toch je kunt het aantal pixels, dat de rechter rand van de label van de linkerkant verwijderd is, wel berekenen met lblBeweeg.left + lblBeweeg.width
En als dat meer dan de breedte van het formulier is (en dat is frmBeweeg. width) dan moet de beweging omdraaien.
Eigenlijk moet de beweging al iets eerder omdraaien, omdat de besturingselementen een rand hebben, zodat de rechterrand al begint te verdwijnen als geldt:
lblBeweeg.left + lblBeweeg.width > frmBeweeg. width - 4

Daarom wordt de procedure die hoort bij de timer als volgt :

procedure TfrmBeweeg.Timer1Timer(Sender: TObject);

If ((lblBeweeg.Left + lblBeweeg.Width > frmBeweeg.Width - 4) And 
   (rechts = True)) Then rechts := False;

If (lblBeweeg.Left < 0) And (rechts = False) Then rechts := True;

If (rechts = True) Then lblBeweeg.Left := lblBeweeg.Left + 10
else  lblBeweeg.Left := lblBeweeg.Left - 10;

end;

De variabele rechts moet je wel declareren, en die moet ook bewaard blijven buiten de procedure van de timer, daarom moet je die variabele declareren als globale variabele
En daar tik je in, onder var frmBeweeg: TfrmBeweeg; :

rechts: Boolean;

Verder moet die variabele ook een beginwaarde hebben.
Daarom tik je bij de procedure TfrmBeweeg.FormCreate(Sender: TObject); in:

rechts := True;

Probeer het maar eens uit!

  5.3 De beweging laten stoppen.

Je kunt de beweging ook laten stoppen.
Als bij de timer "enabled" op false wordt gezet dan doet de timer niets meer, en dan stopt de beweging dus.

Als je op de button met het woord "Stop" klikt, dan is het de bedoeling dat de beweging stopt.
Daar kun je heel gemakkelijk voor zorgen.

Dubbelklik op die button, en tik als programmaregel in:

timer1.enabled := false;

Laat het programma lopen en probeer alles uit.

Het volledige programma ziet er dan als volgt uit:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TfrmBeweeg = class(TForm)
    cmdStop: TButton;
    Timer1: TTimer;
    lblBeweeg: TLabel;
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure cmdStopClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmBeweeg: TfrmBeweeg;
  rechts: Boolean;

implementation

{$R *.dfm}

procedure TfrmBeweeg.cmdStopClick(Sender: TObject);
begin
timer1.enabled := false;
end;

procedure TfrmBeweeg.FormCreate(Sender: TObject);
begin
rechts := True;
end;

procedure TfrmBeweeg.Timer1Timer(Sender: TObject);
begin
If ((lblBeweeg.Left + lblBeweeg.Width > frmBeweeg.Width - 4) And 
   (rechts = True)) Then rechts := False;

If (lblBeweeg.Left < 0) And (rechts = False) Then rechts := True;

If (rechts = True) Then lblBeweeg.Left := lblBeweeg.Left + 10
else  lblBeweeg.Left := lblBeweeg.Left - 10;

end;

end.

  5.4 Even wachten; datum en tijd.

Je kunt een timer ook gebruiken om er voor te zorgen dat er een poosje gewacht wordt voordat er iets gebeurt.
Stel je voor dat je een programma wilt maken waarbij er bij de start een label op het scherm staat met de huidige datum.
En dat de tekst op het label na 5 seconden verandert in de tijd, die steeds wordt bijgewerkt dus per seconde verandert.
Dan moet je het volgende doen:

Plaats een label op het formulier en noem die lblDatum

Plaats dan een timer op het formulier en noem die tmrTijd
Zet in het propertiesvenster van de timer Interval op 5000.
Daarmee stel je in dat er na 5000 milliseconden (dus 5 sec) iets gebeurt.
En "Enabled" zet je op true, want als die op false staat dan gebeurt er niets.

Dubbelklik op een leeg gedeelte van het formulier. Dan kun je de procedure TForm1.FormCreate(Sender: TObject); invoeren.

Tik het volgende in, tussen begin en end:

lblDatum.Caption := 'Datum: ' + FormatDateTime('dd-mm-yyyy', Date);

Dat heeft tot gevolg dat bij de start de datum op het label staat.

Dubbelklik daarna op de timer met de naam tmrTijd, dan kun je de eventhandler (dat is de programma-code) voor die timer invoeren.

Tik het volgende in, tussen begin en end:

lblDatum.Caption := ' Tijd: ' + TimeToStr(Time);
tmrTijd.Interval := 1000;

Dat heeft tot gevolg dat 5 seconden na de start de tijd op het label staat, want je had in het propertiesvenster van de timer Interval op 5000 gezet.
En vervolgens verschijnt na elke seconde de nieuwe tijd op het label. Want de opdracht tmrTijd.Interval := 1000; heeft tot gevolg dat na een seconde de eventhandler van de timer weer wordt uitgevoerd. Zo wordt de tijd steeds bijgewerkt, en heb je een lopende klok gemaakt.

 

In Delphi geeft Date dus automatisch de datum en Time geeft automatisch de tijd

Time is een functie die de systeemtijd als uitkomst geeft en wel als een getal van het type Double.
Het is een getal met de volgende eigenschappen:
Het aantal gehelen van dit getal bestaat uit het aantal dagen dat is verlopen sinds 30 december 1899.
Het gedeelte van het getal achter de komma geeft het gedeelte van de dag, die is verstreken op dat moment.
Een tijdswaarde van 0 komt dus overeen met 30-12-1899 om middernacht 00:00:00 uur.
Een tijdswaarde van 2.75 is dus gelijk aan 01-01-1900 om 06:00 uur in de ochtend.

De functie TimeToStr maakt van de tijdswaarde een string, maar alleen van het Tijd gedeelte.
Door het gebruik van een Formatfunctie, zoals FormatDateTime, kan er worden bepaald hoe de datum of tijd moet worden afgedrukt. Bij de opdracht lblDatum.Caption := 'Datum: ' + FormatDateTime('dd-mm-yyyy', Date); is gekozen voor 2 cijfers voor de dag (dd), 2 cijfers voor de maand (mm) en 4 cijfers voor het jaar (YYYY)

  5.5 Opdrachten.

Opgaven.
Maak nu opgave 5 van de oefenopgaven van hoofdstuk 8