Timer zur Laufzeit

HarryXVI

Erfahrenes Mitglied
Ich möchte einen Timer TiBewegung initialisieren
Code:
TMonster = class(TSprite)
  private
    TiBewegung: TTimer;
    procedure BewegungsTimer(Sender: TObject);
.....
procedure TMonster.init_BewegungsTimer;
begin
TiBewegung := TTimer.Create(nil);
TiBewegung.Enabled := false;
TiBewegung.OnTimer := self.BewegungsTimer;
TiBewegung.Interval := 1000;
end;

Wenn ich den Timer vom Hauptformular "Karte" anmachen lasse
Code:
procedure TKarte.init_Monster(Monster: TMonster);
...
Monster.init_BewegungsTimer;
Monster.TiBewegung.Enabled := true;
passiert nicht das, was in der Prozedur BewegungsTimer vereinbart wurde, sondern gar nix.

Code:
procedure TMonster.BewegungsTimer(Sender: TObject);
var z: integer;
begin
z := random(3);
if zufall[z] = 1 then Left(100);                 //Left, Right, Up, Down sind geerbte Methoden des Typs TSprite.
if zufall[z] = 2 then Right(100);
if zufall[z] = 3 then Up(100);
if zufall[z] = 4 then Down(100);
end;


Habe ich vielleicht mit dem AOwner was falsch gemacht, dass der doch nicht nil ist?
Ich habe auf jeden Fall die zeitliche Reihenfolge beachtet: BewegungsTimer, init_BewegungsTimer, init_Monster
 
Zuletzt bearbeitet:

HarryXVI

Erfahrenes Mitglied
Code:
procedure TMonster.MAngriffsTimer(Sender: TObject);
Das is die Ereignismethode des Timers.
Direkt danach folgt die Prozedur, die den Timer erstellt.

Code:
procedure TMonster.init_MAngriffsTimer;
begin
TiMAngriff := TTimer.Create(nil);
TiMAngriff.Enabled := false;
TiMAngriff.OnTimer := self.MAngriffsTimer;
TiMAngriff.Interval := 1000;
end;
Ich weiß nicht warum, aber man kann die Ereignismethode dem OnTimer-Ereignis zuweisen, ohne einen Sender angeben zu müssen.

Nachher kann man dann den Timer aktivieren und es funktioniert.
Code:
Dander.TiMAngriff.Enabled := true;
Dander ist vom Typ TMonster.
 

CSANecromancer

Erfahrenes Mitglied
Code:
TiMAngriff.OnTimer := self.MAngriffsTimer;
Ich weiß nicht warum, aber man kann die Ereignismethode dem OnTimer-Ereignis zuweisen, ohne einen Sender angeben zu müssen.
Das liegt daran, daß du oben nicht die Methode OnTimer oder MAngriffsTimer aufrufst (dann würdest du tatsächlich den Sender benötigen). Es findet eine Zuordnung statt. Tatsächlich ist das OnTimer-"Ding" an sich ein Zeiger auf eine Speicheradresse, üblicherweise die Adresse, an der dann der auszuführende Code von OnTimer steht. Selbiges gilt für das MAngriffTimer-"Ding".
Durch die obige Zuweisung sagst du deinem Programm quasi "wenn jetzt OnTimer stattfindet, dann mache mit der Programmausführung nicht bei OnTimer weiter sondern bei MAngriffsTimer".
Das OnTimer-Ereignis selbst tritt dann automatisch ein (durch Aktivieren des Timer-Objekts) und dadurch kommt dann der MAngriffsTimer-Code zur Ausführung.
 

HarryXVI

Erfahrenes Mitglied
weitere Frage zu Timern: Ich möchte programmieren, dass eine bestimmte Zeit, nachdem ich den Timer aktiviert habe, eine Prozedur aufgerufen wird und der Timer danach sofort deaktivert wird.

Bsp: Eine Grafik verschwindet mit Destroy, 3 Sekunden später lädt Timer1 eine neue und schaltet sich selbst aus.

Letzteres könnte mit Timer1.Enabled := false in der OnTimer-Methode realisiert werden. Aber wie funktioniert das andere?
 

HarryXVI

Erfahrenes Mitglied
das ist nicht das Problem, damit komme ich zurecht und werde sehen, welche die bessere alternative ist.
Nein, mir geht es darum:
HarryXVI hat gesagt.:
eine bestimmte Zeit, nachdem ich den Timer aktiviert habe, eine Prozedur aufgerufen wird

Wenn ich Timer1.Enabled := true setze, wird ja sofort das OnTimer-Ereignis ausgelöst. Wie kann ich dies um ein bestimmtes Zeitintervall verzögern?
 

vop

Erfahrenes Mitglied
Du könntest einen weiterern Timer einsetzen, der nach 3 Sekunden feuert und von dem anderen Timer aktiviert wird.