Timer zur Laufzeit

HarryXVI

Erfahrenes Mitglied
Ich glaube, ihr versteht mich nicht richtig. Ich habe mal eine Zeitleiste gemalt, wie das Ereignis aussehen soll (siehe Anhang).

Bei 1 aktiviert eine Methode den Timer. Zwischen 1 und 2 vergehen 10 Sekunden, bis der Timer das ausführt, was unter OnTimer vereinbart wurde. Darin ist seine Selbstabschaltung unter Punkt 3 Enabled := false enthalten. Zwischen 2 und 3 geschieht also das, was in OnTimer steht.

Könnt ihr mir jetzt folgen? Außerdem, selbst wenn der Vorschlag von vop eine Möglichkeit wäre, wüsste ich nicht, wie ich das realisieren könnte.
 

Anhänge

  • Zeitleiste.bmp
    24,5 KB · Aufrufe: 45

CSANecromancer

Erfahrenes Mitglied
Könnt ihr mir jetzt folgen?
Ich glaube, jetzt komme ich endlich einigermaßen dahinter, was du willst.
Wenn ich das richtig verstehe, dann tritt Ereignis 1 nach 10 Sekunden (von Timer1) gesteuert auf.
Nach Abarbeiten von Ereignis 1 soll 3 Sekunden gewartet werden, bevor Ereignis 1 erneut mit 10 Sekunden Vorlauf angesteuert werden kann, richtig?

Also die billigste Methode wäre das Verlängern des Intervals von Timer1. Ich habe bisher noch keine Probleme damit gehabt, daß ein Timer direkt aktiviert wurde, aber wenn du sagst, daß das bei dir der Fall ist, dann könntest du Folgendes probieren:

(Formular Form1 mit zwei Timern Timer1 und Timer2)
Code:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Wenn Timer2 läuft, dann wurde erst vor Kurzem ein Timer1-Ereignis ausgelöst
  // und das Timer1-Ereignis soll nicht erneut ablaufen. Daher wird nur dann
  // die Timer1-Methode ausgeführt, wenn Timer2 deaktiviert ist.
  if Timer2.Enabled = false then
  begin
    // Sicherstellen, daß kein zweites Timer-Ereignis dazwischen funkt
    Timer1.Enabled := false;

    // Und weil wir schon dabei sind, gleich den Timer neu initialisieren
    Timer1.Interval := 10 * 1000;
  
    // Ab hier wird dann der Krempel von Timer1 ausgeführt, was auch immer das sein soll
    // ...

    // So, Timer1 ist fertig. Jetzt soll die 3 Sekunden Sperrfrist laufen, bevor Timer1 wieder
    // aktiviert werden kann.

    // Erstmal Timer2 deaktivieren, damit der nicht quer läuft
    Timer2.Enabled := false;

    // Timer2 neu initialisieren
    Timer2.Interval := 3 * 1000;

    // Und den Timer laufen lassen. Um das erneute Aktivieren von Timer1 kümmert sich dann Timer2.
    Timer2.Enabled := true;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  Timer1.Enabled := true;
  Timer2.Enabled := false;
end;

Meinstest du so etwas? Leuchtet mir zwar immer noch nicht so recht ein, aber das sollte u.U. das sein, was du haben willst.
 
Zuletzt bearbeitet:

HarryXVI

Erfahrenes Mitglied
Deine Idee war gut und ich habe sie nun so modifiziert, dass es in mein Programm passt. Das erläutere ich kurz (Timer1 heißt TiNeuMonster, Timer2 heißt TiAktiv).

TiAktiv ist der Aktivator von TiNeuMonster, ist also die ganze Zeit an.
Code:
procedure TKarte.FormCreate(Sender: TObject);
begin
... TiAktiv.Interval := 1;
TiAktiv.Enabled := true; ...
end;

Code:
procedure TKarte.TiAktivTimer(Sender: TObject);
begin
if (Dander = nil) or (Seedle = nil) then TiNeuMonster.Enabled := true;
end;
Er prüft jede Millisekunde, ob eines der beiden Objekte leer ist, wenn ja, dann aktiviert er TiNeuMonster, der folgendes macht:

Code:
procedure TKarte.TiNeuMonsterTimer(Sender: TObject);
begin
TiAktiv.Enabled := false;       
TiNeuMonster.Enabled := false;  // keine Wiederholung des Timer-Ereignisses
TiNeuMonster.Interval := 3000;
if Dander = nil then begin
  Dander := TMonster.Create;
  init_monster(Dander,'Dander.bmp','Dander.txt');
  end;
if Seedle = nil then begin
  Seedle := TMonster.Create;
  init_monster(Seedle,'Seedle.bmp','Seedle.txt');
  end;
Dander.ausgewaehlt := false;
Seedle.ausgewaehlt := false;
TiAktiv.Enabled := true;  // Aktivierungstimer wieder anschalten
end;

TiNeuMonster schaltet TiAktiv aus, damit der ihn nicht nochmal aktivert. Er macht auch sich selbst aus, damit das OnTimer-Ereignis einmalig bleibt. Nach 3 Sekunden prüft er, welches Objekt leer ist und erstellt ein neues. Dann macht er seinen Aktivator wieder an, um erneut gerufen zu werden, wenn eines der Objekte leer ist.

Edit: @CSANecromancer: Gut, dass du deine erste Antwort nochmal überarbeitet hast, war nämlich nicht sehr nett...
 
Zuletzt bearbeitet:

CSANecromancer

Erfahrenes Mitglied
Edit: @CSANecromancer: Gut, dass du deine erste Antwort nochmal überarbeitet hast, war nämlich nicht sehr nett...
Ich bin nicht unbedingt für Diplomatie oder Feingefühl bekannt. :suspekt:
Ich versuche zu helfen, aber wenn einfach zu wenig Infos da sind, dann schreibe ich beim 20. Mal Nachfragen (nicht unbedingt alle im gleichen Thread) auch mal etwas deutlichere und interpretationsfreie Worte. :) Aber siehst ja: Kann auch sein, daß was Sinnvolles zusammen kommt.
 
B

Butt4cak3

Hallo,
Ich suche jetzt schon seit etwa einer Stunde nach einer Lösung zu meinem Problem und bin letztendlich auf dieses Thema in diesem Forum gestoßen und ich dachte mir ich frage nach, auch wenn das hier schon etwas älter ist.

Jedenfalls geht es mir darum, dass ich ein kleines Spiel in Delphi baue in dem man den Spieler (einen Kreis) von oben sieht und ihn mit W, A, S und D steuert. Mit der Maus kann man zielen und schießen. Erst habe ich das alles in einer einzigen Unit gemacht und dadurch die Möglichkeit gehabt einen Timer auf der Form zu platzieren.

Jetzt will ich aber mehr Flexibilität. Das heißt, dass ich mir für den Spieler eine Klasse gebaut habe und jetzt an der für die Waffe sitze. Da diese ja in einem bestimmten Intervall schießen muss brauche ich einen Timer. Diesen habe ich auch schon erstellt, nur bekomme ich es einfach nicht gebacken das mit dem OnTimer-Event zu machen. Egal wo ich nachschaue: Ich versteh es nicht oder das Beispiel funktioniert bei mir nicht.

Code:
type
  TWeapon = class
  TimerReload, TimerShot : TTimer;
  constructor Create(ShotInterval, ReloadTime : Integer);
  procedure ReloadTimer;
  procedure reload;
  private
    { private declarations }
  public
    { public declarations }
    Damage, Spread : Real;
    Ammo, MaxAmmo : Integer;
  end;

implementation

procedure TWeapon.ReloadTimer;
begin
  // Hier wird Ammo dann auf MaxAmmo gesetzt
  TimerShot.Enabled := false;
end;

constructor TWeapon.Create(ShotInterval, ReloadTime : Integer); // Je nachdem wie ich das Spiel testen will ändere ich diese Werte
begin
  TimerShot := TTimer.Create(NIL);
  TimerShot.Enabled := false;
  TimerShot.Interval := ShotInterval;
  // Hier muss nun soweit ich weiß festgelegt werden was bei OnTimer passiert
end;

procedure TWeapon.reload; // Diese Prozedur wird aufgerufen, wenn der Spieler die R-Taste drückt
begin
  if TimerReload.Enabled = false then TimerReload.Enabled := true; // Der Timer wird gestartet, welcher sich nach einem Durchgang selbst wieder deaktiviert
end;

end.

Jetzt wüsste ich gerne, wie ich erreiche, dass die ReloadTimer-Prozedur aufgerufen wird, wenn der Intervall rum ist. Das ist der Teil, der mir bis jetzt nicht gelungen ist...