AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Timer einmalig sofort auslösen.

Ein Thema von xDIMAx · begonnen am 1. Aug 2012 · letzter Beitrag vom 2. Aug 2012
Antwort Antwort
xDIMAx

Registriert seit: 4. Feb 2012
5 Beiträge
 
#1

Timer einmalig sofort auslösen.

  Alt 1. Aug 2012, 20:55
Delphi-Version: 7
Guten Tag, ich würde gerne, wie im Titel beschrieben, einen Timer einmalig sofort auslösen und dann wieder in den Normalzustand versetzen, ohne, dass es zu Dopplungen oder Ähnlichem kommt.

Um diesen Teil des Programms zu erklären:
Man hat einen Shape, der per Timer zufällig versetzt wird. Innerhalb des Intervalls muss der Shape berührt werden, damit "das Spiel" nicht vorbei ist. Wenn man sich verklickt endet das Spiel ohne, dass man den Shape noch klicken kann. Ich will nun verhindern, dass nachdem man entweder erfolgreich war, oder Game Over ist, direkt der nächste Schritt folgt. Also die Versetzung des Shapes, wenn man den Shape geklickt hat, oder der Punktescreen, wenn man verliert, weil entweder der Intervall abegelaufen ist und man nichts geklickt hat, oder sich verklickt hat.


Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  H:=1; //Zufällige Variable, um dem Timer anzuzeigen, ob die Form angeklickt wurde.
  Timer1.Interval:=1;
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  G:=0; //Zufällige Variable, um dem Timer anzuzeigen, ob der Shape angeklickt wurde.
  Timer1.Interval:=1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Form1.Timer1.Interval:=TI; //TI ist der ursprüngliche Timerintervall. //////////XXXXX//////////
  if (G=0) and (H=0) then
    begin //Soll passieren, wenn der Shape innerhalb des Intervalls angeklickt wurde.
      G:=1; //G:=1; Sorgt dafür, dass man den Shape anklicken muss, um den Then-Befehl auszuführen.
      H:=0;
      Shape1.Left:=trunc(random*(Form1.Width-64))+16;
      Shape1.Top:=trunc(random*(Form1.Height-64))+64;
    end
  else
    begin
      Button1Click(Self); //Soll passieren, wenn entweder die Form oder gar nichts innerhalb des Intervalls angeklickt wurde.
    end;
end;
Das Problem ist nun, dass wenn ich den Timerintervall zurücksetzte (siehe Quellcode://///XXXXX/////), der ganze Then-Befehl nicht ausgeführt wird, wodurch der Ablauf des Intervalls keine Auswirkung mehr hat und man nur weiterkommt, indem man richtig klickt oder sich verklickt.
Also im Grunde funktioniert das Verlieren, durch Ablauf der Zeit nicht mehr.
Ich hoffe mein Problem irgendwie kenntlich machen oder mich viel zu wiederholen, hehe.


P.S. Für zukünftige Threads: Kann man den Titel des Threads noch verändern? Wenn ich ihn mir jetzt nochmal durchlese, kommt er mir ein bisschen komisch vor.

Geändert von xDIMAx ( 1. Aug 2012 um 21:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

AW: Timer einmalig sofort auslösen.

  Alt 1. Aug 2012, 21:48
Hallo erstmal

P.S. Für zukünftige Threads: Kann man den Titel des Threads noch verändern? Wenn ich ihn mir jetzt nochmal durchlese, kommt er mir ein bisschen komisch vor.
Ja. Klicke auf bearbeiten und dann auf erweiterter Editor.

Zu deinem Problem: Ich würde das wie folgt lösen:
Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
   H:=1; //Zufällige Variable, um dem Timer anzuzeigen, ob die Form angeklickt wurde.
   Timer1Timer(Sender);
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
begin
   G:=0; //Zufällige Variable, um dem Timer anzuzeigen, ob der Shape angeklickt wurde.
   Timer1Timer(Sender);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   if (G=0) and (H=0) then
   begin //Soll passieren, wenn der Shape innerhalb des Intervalls angeklickt wurde.
      G:=1; //G:=1; Sorgt dafür, dass man den Shape anklicken muss, um den Then-Befehl auszuführen.
      H:=0;
      Shape1.Left:=trunc(random*(Form1.Width-64))+16;
      Shape1.Top:=trunc(random*(Form1.Height-64))+64;
   end
   else
   begin
      Button1Click(Self); //Soll passieren, wenn entweder die Form oder gar nichts innerhalb des Intervalls angeklickt wurde.
   end;
end;
Du hast ja schon am Ende der Timer1Timer Methode die Button1Click Methode aufgerufen. Auf die gleiche Weise lässt sich die Timer1Timer Methode aufrufen ohne dass der Timer tatsächlich ausgelöst hat.

Ach, und tu dir selbst einen Gefallen und benenne deine Variablen richtig. D.h. insbesondere keine globalen Variablen mit einem Buchstaben.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

AW: Timer einmalig sofort auslösen.

  Alt 1. Aug 2012, 22:23
Timer1Timer(nil); und dann if not Assigned(Sender) then oder if Sender = nil then um zu prüfen, ob es "manuell" ausgelöst wurde.

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  Button1Click(nil);
  // Aber wenn hier sowieso sonst nichts passiert, dann bei "OnClick" direkt das "Button1Click" angeben
end;
Aber ganz im Ernst, warum willst du auf Zwang zwei verschiedene Ereignisse dort einbauen, welche mit dem Timer eigentlich nichts zu tun haben?

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  // verfehlt ... machwas, wenn danebengecklickt wird
  Timer1Timer(nil);
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  // getroffen ... machwas, wenn es erwischt wurde
  ...
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  // Zeit abgelaufen (oder danabengeklickt) ... mach was, wenn es nicht erwischt wurde
  // über Assigned(Sender) kannst du unterscheiden, ob Zeit oder Klick
  ...
end;
Und dazu noch eine eigene "Verschiebe"-Prozedur, welche das Shape verschiebt und die von den Timer- und Klickereignissen aufgerufen wird.
$2B or not $2B

Geändert von himitsu ( 1. Aug 2012 um 22:52 Uhr)
  Mit Zitat antworten Zitat
xDIMAx

Registriert seit: 4. Feb 2012
5 Beiträge
 
#4

AW: Timer einmalig sofort auslösen.

  Alt 2. Aug 2012, 08:31
Also bei der, von jfheins genannten, Lösung kommt es scheinbar zu der von mir angesprochenen Dopplung, bei der der Timer einmal manuell und kurz darauf nochmal durch den Intervall ausgelöst wird.

Und bei der, von himitsu genannten, blick ich nicht wirklich durch:

Der Vorschlag funktioniert gut:
Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  // verfehlt ... machwas, wenn danebengecklickt wird
  Timer1Timer(nil);
end;
Aber deine erste Zeile verstehe ich nicht so wirklich.
Timer1Timer(nil); und dann if not Assigned(Sender) then oder if Sender = nil then um zu prüfen, ob es "manuell" ausgelöst wurde.

Ich denke in der geht es genau um mein Problem, aber bin in Delphi noch Anfänger.
Ich probiere erst einmal ein bisschen rum und gucke ob ich nicht irgendwie dahinterkomme. ^^

EDIT: Also ich habe wirklich keine Ahnung. Alles, was ich versuche führt zu mehr Problemen. Man kann unabhängig von Start/Stop, das Spiel verlieren, gewinnen, alles anklicken. Ich weiß wirklich nicht weiter.

EDIT2:

Also ich habe es nun Folgendermaßen gemacht:

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
begin
  H:=1;
  Timer1Timer(nil);
end;

procedure TForm1.Shape1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  G:=0;
  Timer1Timer(nil);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if F=1 then //Eine weitere Random-Variable. ^^ Sorry, ich ersetze die später.
    begin
      F:=0;
      Exit;
    end;
  if Sender=nil then
    begin
      F:=1;
    end;
  if (G=0) and (H=0) then
    begin
      G:=1;
      H:=0;
      Shape1.Left:=trunc(random*(Form1.Width-64))+16;
      Shape1.Top:=trunc(random*(Form1.Height-64))+64;
    end
  else
    begin
      Button1Click(Self);
    end;
end;
Es funktioniert.... Danke.

Wenn ihr eine Idee habt, wie ich das besser hinkriegen könnte, könnt ihr weiter Vorschläge machen. ^^

Geändert von xDIMAx ( 2. Aug 2012 um 10:29 Uhr)
  Mit Zitat antworten Zitat
GHorn

Registriert seit: 24. Mär 2009
Ort: NRW
124 Beiträge
 
#5

AW: Timer einmalig sofort auslösen.

  Alt 2. Aug 2012, 10:08
Hallo,

welchen Interval-Wert hast du eingestellt? Wenn der größer als Null ist, tobt der Timer irgendwann von sich aus los.

Ich habe innerhalb des OnTimer-Events immer den Timer zunächst disabled und am Schluß enabled. Dann gibt's keine Überschneidungen.

Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  try
    //
    // Hier die Timer-Aktionen ...
    //
  finally
    Timer1.Enabled := True;
  end;
end;
Edit: Das Ganze noch in den try..finally Block gepackt, damit der
Timer in jedem Falle wieder aktiviert wird.

Geändert von GHorn ( 2. Aug 2012 um 10:17 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz