| Autor |
Beitrag |
mick
      
Beiträge: 159
|
Verfasst: Sa 28.03.09 00:08
hallo zusammen.
ich programmiere ein primitives zufallszahlenspiel. nach einem klick auf den start/stop-button soll in einem panel eine zufallszahl "rotieren", d.h. im paar millisekundentakt wird darin eine neu generierte zufallszahl zw. 1 und 6 angezeigt (auf der gleichen stelle wie die vorige, man sieht also immer nur eine ziffer). dies soll prinzipiell unendlich lange laufen, zumindest so lange, bis der user wieder auf den SELBEN start/stop-button klickt (im spielerischen sinne des programms in dem moment, wenn die hoechste zufallszahl im panel angezeigt wurde, aber soviel nur zur prog-logik nebenbei). mein problem: wie formuliere ich das? wenn man naemlich auf den start/stop-button zum ersten mal drueckt, das onclick-ereignis ausgeloest wird und die schleife zur zufallszahlenerzeugung und -ausgabe durchlaeuft, soll abgebrochen werden durch erneuten klick auf den selben button. doch dessen onclick-ereignis wird als prozedur doch grade ausgefuehrt. wie kann das klappen? eine spezielle bedingung in der repeat-schleife? fuer profis sicherlich ein leichtes, dies zu loesen, ich danke im voraus.
sofern nicht zu verwirrend, hier ein quellcode-auszug:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58:
| procedure TForm1.BitBtnStartStopClick(Sender: TObject);
procedure Verzoegerung; const Dauer = 70; var ZeitAnfang,ZeitEnde: Longint; begin ZeitAnfang := GetTickCount; repeat Application.ProcessMessages; ZeitEnde := GetTickCount; until (ZeitEnde-ZeitAnfang > Dauer); end;
procedure Auswertung; begin if User > Computer then MessageDlg('Herzlichen Glückwunsch!' + #13 + 'Sie haben eine ' + IntToStr(User) + ' gewürfelt, der Computer nur eine ' + IntToStr(Computer) + '.' + #13 + #13 + 'Sie haben gewonnen!',mtInformation,[mbOK],0) else if User < Computer then MessageDlg('Schade!' + #13 + 'Sie haben eine ' + IntToStr(User) + ' gewürfelt, der Computer hingegen eine ' + IntToStr(Computer) + '.' + #13 + #13 + 'Sie haben leider verloren.',mtInformation,[mbOK],0) else MessageDlg('Unentschieden!' + #13 + 'Der Computer hat ebenso wie Sie eine ' + IntToStr(User) + ' gewürfelt.' + #13 + #13 + 'Entscheiden Sie das Duell in einer erneuten Runde!',mtInformation,[mbOK],0); end; var i: Integer; begin if BitBtnStartStop.Caption = '&Start' then begin BitBtnStartStop.Kind := bkCancel; BitBtnStartStop.Caption := '&Stop';
User := Random(6) + 1; PnlUser.Caption := IntToStr(User); end else begin BitBtnStartStop.Enabled := False;
for i := 1 to 50 do begin Computer := Random(6) + 1; PnlComputer.Caption := IntToStr(Computer); Verzoegerung; end;
Auswertung; end; end; |
screenshot:
Moderiert von Narses: Bild als Anhang hochgeladen
ciao,
ltmick.
Einloggen, um Attachments anzusehen!
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 28.03.09 00:23
Zur "Verzögerung" nimm am besten dieses Delay:
www.delphipraxis.net/topic7355.html
Was du machen müsstest ist eine Schleife, die bis zum Abbruch läuft. Das geht z.B. mit Tag. Beispiel, hier zähle ich einfach eine Zahl hoch: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45:
| procedure TForm1.Button1Click(Sender: TObject);
procedure Delay(Milliseconds: Integer); var Tick: DWord; Event: THandle; begin Event := CreateEvent(nil, False, False, nil); try Tick := GetTickCount + DWord(Milliseconds); while (Milliseconds > 0) and (MsgWaitForMultipleObjects(1, Event, False, Milliseconds, QS_ALLINPUT) <> WAIT_TIMEOUT) do begin Application.ProcessMessages; if Application.Terminated then Exit; Milliseconds := Tick - GetTickcount; end; finally CloseHandle(Event); end; end;
var Value: Integer; begin if not (Sender is TButton) then Exit; if TButton(Sender).Tag = 1 then begin TButton(Sender).Tag := 0; TButton(Sender).Caption := 'Start'; end else begin Value := 0; TButton(Sender).Tag := 1; TButton(Sender).Caption := 'Abbrechen'; while TButton(Sender).Tag <> 0 do begin Inc(Value); Caption := IntToStr(Value); Delay(100); end; end; end; |
|
|
GTA-Place
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: Sa 28.03.09 11:14
Ein wenig OT: Ein großes Lob für die Formulierung der Frage und für den bisherigen Quelltext. So gut formatiert sieht man das selten!
Und die Lösung hat ja jaenicke nun auch schon formuliert 
_________________ "Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
|
|
mick 
      
Beiträge: 159
|
Verfasst: Sa 28.03.09 18:31
vielen dank fuer die antwort. habe es jetzt folgendermassen umgesetzt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66:
| procedure TForm1.BitBtnStartStopClick(Sender: TObject);
procedure Verzoegerung; const Dauer = 100; var ZeitAnfang,ZeitEnde: Longint; begin ZeitAnfang := GetTickCount; repeat Application.ProcessMessages; ZeitEnde := GetTickCount; until (ZeitEnde-ZeitAnfang > Dauer); end;
procedure Auswertung; begin if User > Computer then MessageDlg('Herzlichen Glückwunsch!' + #13 + 'Sie haben eine ' + IntToStr(User) + ' gewürfelt, der Computer nur eine ' + IntToStr(Computer) + '.' + #13 + #13 + 'Sie haben gewonnen!',mtInformation,[mbOK],0) else if User < Computer then MessageDlg('Schade!' + #13 + 'Sie haben eine ' + IntToStr(User) + ' gewürfelt, der Computer hingegen eine ' + IntToStr(Computer) + '.' + #13 + #13 + 'Sie haben leider verloren.',mtInformation,[mbOK],0) else MessageDlg('Unentschieden!' + #13 + 'Der Computer hat ebenso wie Sie eine ' + IntToStr(User) + ' gewürfelt.' + #13 + #13 + 'Entscheiden Sie das Duell in einer erneuten Runde!',mtInformation,[mbOK],0); end;
var i: Integer; begin
if BitBtnStartStop.Tag = 0 then begin BitBtnStartStop.Tag := 1; BitBtnStartStop.Kind := bkCancel; BitBtnStartStop.Caption := '&Stop';
while BitBtnStartStop.Tag <> 0 do begin User := Random(6) + 1; PnlUser.Caption := IntToStr(User); Verzoegerung; end; end else begin BitBtnStartStop.Tag := 0; BitBtnStartStop.Enabled := False;
for i := 1 to 50 do begin Computer := Random(6) + 1; PnlComputer.Caption := IntToStr(Computer); Verzoegerung; end;
Auswertung; end; end; |
werde trotzdem meine art der verzoegerung nutzen - dies ist vllt. nicht so effizient, aber leichter verstaenidlich und ich denke fuer diesen zweck zielfuehrend, oder?
darueber hinaus: wie zu sehen, habe ich
Delphi-Quelltext 1:
| if not (Sender is TBitBtn) then Exit; |
einkommentiert. es klappt naemlich auch so. oder brauche ich das wirklich? habe naemlich noch nicht ganz verstanden, warum das ganze funktioniert. die eigenschaft "tag" ist mir klar - hier als eine art flag genutzt. aber wie funktioniert das mit den onclick-ereignissen? ueberlagert der zweite klick den ersten? und wird der erste nach beendigung des zweiten an der stelle fortgesetzt, wo er durch den zweiten klick unterbrochen wurde, oder wie?
danke fuer die nachhilfe,
ciao,
mick.
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Sa 28.03.09 18:33
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 28.03.09 18:36
|
|
mick 
      
Beiträge: 159
|
Verfasst: Sa 28.03.09 18:59
danke fuer den hinweis mit
Delphi-Quelltext 1:
| Application.ProcessMessages; |
habe es in meinen unterlagen geaendert.
dann aber nochmals zu den ereignissen: der zweite klick ueberlagert also den ersten. die prozedur des ersten klicks wird nach beendigung der prozedur des zweiten klick dort weiter ausgefuehrt, wo sie unterbrochen wurde. ok. wenn dem so ist, koennte dann nicht folgender unerwuenschter effekt auftreten? sagen wir, in
Delphi-Quelltext 1: 2: 3: 4: 5:
| while BitBtnStartStop.Tag <> 0 do begin User := Random(6) + 1; PnlUser.Caption := IntToStr(User); Verzoegerung; end; |
wird die while-schleife dann unterbrochen, wenn grade der befehl
Delphi-Quelltext 1:
| User := Random(6) + 1; |
ausgefuehrt wird. dann kommt der durchlauf fuer den zweiten klick, und wenn danach an der zuvor unterbrochenen stelle in obiger while-schleife weitergemacht wird, muesste doch noch
Delphi-Quelltext 1: 2:
| PnlUser.Caption := IntToStr(User); Verzoegerung; |
ausgefuehrt werden. das wiederum haette zur folge, dass ganz am ende nochmals eine unerwuenschte ausgabe im PnlUser getaetigt wuerde, oder?
ciao,
mick.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 28.03.09 19:06
Die "Unterbrechung" passiert genau da, wo du die Abarbeitung der angekommenen Mausbotschaften erlaubst. Nämlich mit Application.ProcessMessages in Verzoegerung.
|
|
mick 
      
Beiträge: 159
|
Verfasst: Sa 28.03.09 19:40
ah, dann ist eine "unterbrechung" also nur bei
Delphi-Quelltext 1:
| Application.ProcessMessages; |
moeglich - mein oben geschilderter fall kann also nicht eintreten. das bedeutet auch, dass wenn ich die zeile oben aus dem code loesche, mein programm zwar noch compiliert wird, aber beim button-klick abstuerzen wird.
danke,
ciao,
mick.
|
|
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Sa 28.03.09 19:44
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 28.03.09 19:44
Abstürzen ist das falsche Wort, nicht mehr reagieren wird das Programm dann.
|
|
mick 
      
Beiträge: 159
|
Verfasst: Sa 28.03.09 19:52
super, leute, jetzt hab ich's. danke fuer eure hilfe,
ciao,
mick.
|
|
|