Autor |
Beitrag |
Vorschlag
      
Beiträge: 63
|
Verfasst: Mo 04.01.10 15:35
Ich habe ein kleines Memory Spiel nach Narses Vorlage erstellt.
Nun habe ich nach dieser Anleitung eine kleine Highscoreliste eingebaut: www.delphi-library.d...iewtopic.php?t=70217
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.Button1Click(Sender: TObject); begin with lvHighscore.Items.Add do begin Caption := 'Narses'; Data := Pointer(Random(100)); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
habe ich geändert zu
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); var Zeit1, Zeit2, Differenz: TDateTime; begin Form1.LbEndzeit.Caption:=TimeToStr(now); Zeit1:= StrToTime(Form1.LbEndzeit.Caption); Zeit2:= StrToTime(Form1.LbAnfangszeit.Caption); Differenz := Zeit1 - Zeit2; with lvHighscore.Items.Add do begin Caption := EdName.Text; Data := (Differenz); SubItems.Add(TimeToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; |
Da ich die Highscoreliste nach benötigter Zeit sortieren möchte.
Leider gibt es mit dem Pointer Probleme.
Kann mir jemand helfen?
Wird wohl nur ein kleiner Fehler sein.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.01.10 18:17
Moin!
Zunächstmal: Vorschlag hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); Form1.LbEndzeit.Caption := TimeToStr(now); | |
Du hast einen Button zum Eintragen des Highscores und in dessen Handler bestimmst du erst die Endzeit?  Das kann doch nicht richtig sein, oder?
Du kannst in der .Data-Eigenschaft nur einen Integer ablegen, keinen TDateTime-Wert (passt nicht, ist 8 Bytes groß, Integer nur 4 Bytes). Du musst das in Sekunden umwandeln:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| var Zeit1, Zeit2: TDateTime; Differenz: Integer; begin Form1.LbEndzeit.Caption := TimeToStr(now); Zeit1 := StrToTime(Form1.LbEndzeit.Caption); Zeit2 := StrToTime(Form1.LbAnfangszeit.Caption); Differenz := SecondsBetween(Zeit1,Zeit2); with lvHighscore.Items.Add do begin Caption := EdName.Text; Data := Pointer(Differenz); SubItems.Add(IntToStr(Integer(Data))); SubItems.Add(DateTimeToStr(Now)); end; end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Mo 04.01.10 18:31
Zitat: | Du hast einen Button zum Eintragen des Highscores und in dessen Handler bestimmst du erst die Endzeit? Das kann doch nicht richtig sein, oder? |
Das Problem ist, ich arbeite mit 2 Formularen.
Im 1. ist das Spiel und beim Spielende kommt man zum 2. Formular (Highscoreliste). Das Problem ist, dass die gebrauchte Zeit zwar auch im 1. Formular berechnet wird und ausgeben wird nur ich nicht weiß, wie man diesen Wert in das 2. Formular übernehmen kann?
Danke für den 2. Tipp, funktioniert super 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.01.10 20:35
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mo 04.01.10 21:12
Hi
Ohne Anspruch auf irgendwas, nur schnell überflogen: Wahrscheinlich kannst du auch unter implementation ein uses einfügen, und dort dann die Unit des ersten Formulars einbringen. Wenn du in der des ersten die des zweiten verwendest, und nun umgekehrt im 2. die des 1., würde die Unit sich indirekt selbst einbinden(wenns im interface-teil steht). Im Implementation-Teil geht das aber: 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:
| unit FrmMain;
interface
uses Windows, ;
type TMainFrm = class(TForm) public function GetHighscoreData: THighscoreData; end;
implementation
uses FrmHighscores;
end. unit FrmHighscores;
interface
uses Windows, ;
type THighscoreFrm = class(TForm) end;
implementation
uses FrmMain;
end. |
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Mo 04.01.10 23:17
Ich bin wirklich noch nen Delphifrischling
Daher bräuchte ich genauer Angaben. Also das mit dem Uses habe ich erledigt.
Nun kann ich einfach den Wert von z.b.
Label1.text auf FrmMain in FrmHighscore verwenden?
Was schreibe ich dann in FrmHighscore?
Delphi-Quelltext
oder
Delphi-Quelltext
?
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mo 04.01.10 23:34
Moin!
Vorschlag hat folgendes geschrieben : | Daher bräuchte ich genauer Angaben. Also das mit dem Uses habe ich erledigt.
Nun kann ich einfach den Wert von z.b.
Label1.text auf FrmMain in FrmHighscore verwenden?
Was schreibe ich dann in FrmHighscore? |
Langsam  nicht den Ereigniszeitpunkt aus den Augen verlieren.
In dem Moment, in dem das Spiel beendet ist muss auch der neue Highscore-Eintrag angelegt werden. Es ist also nicht erforderlich, in der Unit frmHighscore auf frmMain zuzugreifen, sonden aus frmMain auf frmHighscore. Du musst also nur in der frmMain unterhalb von implementation ein uses frmHighscore; hinzufügen (so ungefähr, je nachdem wie deine Units wirklich heißen).
Dann verschiebst du den Code-Teil, der ein neues ListItem anlegt aus frmHighscore in frmMain an die Stelle, wo das Spielende festgestellt wurde.
cu
Narses
//EDIT: Reihenfolge der Forms getauscht; Danke an Hidden! 
_________________ There are 10 types of people - those who understand binary and those who don´t.
Zuletzt bearbeitet von Narses am Di 05.01.10 00:22, insgesamt 1-mal bearbeitet
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mo 04.01.10 23:55
Hi
Letzteres. Ich würde aber nicht direkt auf die Komponenten auf dem Formular zugreifen, sondern das das Formular selbst machen lassen. Dazu deklarierst du eine Funktion in FrmMain, die diesen Wert ausgibt, und kannst dann, auch wenn du ihn an mehreren Stellen ausliest, später noch sehr leicht etwas ändern oder einbauen, das bei jedem Auslesen geschehen soll.
Edit:
Narses hat folgendes geschrieben : | Es ist also nicht erforderlich, in der Unit frmHighscore auf frmMain zuzugreifen, sonden aus frmMain auf frmHighscore. |
Stimmt
Narses hat folgendes geschrieben : | Du musst also nur in der frmHighscore unterhalb von implementation ein uses frmMain; hinzufügen (so ungefähr, je nachdem wie deine Units wirklich heißen). |
Das ist jetzt wieder anders herum, als du gerade gesagt hast  So wie ich das verstanden habe, muss in FrmMain ein uses FrmHighscore rein und dann zur Ausgabe der Ergebnisse:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TMainFrm.ShowHighscores; var aHighscoreFrm: THighscoreFrm; begin aHighscoreFrm := THighScoreFrm.Create; try aHighScoreFrm.AddHighscore(StrToInt(Edit1.Text)); aHighscoreFrm.ShowModal; finally aHighscoreFrm.Free; end; end; |
Wie du vielleicht gemerkt hast, erzeugst du das Highscoreformular erst, wenn du es brauchst. Du kannst es also bei Project\AutocreateForms herausnehmen, wenn du das noch nicht gemacht hast.
Narses hat folgendes geschrieben : | Dann verschiebst du den Code-Teil, der ein neues ListItem anlegt aus frmHighscore in frmMain an die Stelle, wo das Spielende festgestellt wurde.  |
Das würde dann THighscoreFrm in der Prozedur AddHighscore() machen. Die muss in den Public-Teil:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type THighscoreFrm = class(TForm) private FHighscore: Integer; public procedure AddHighscore(aHighscore: Integer); end;
procedure THighscoreFrm.AddHighscore(aHighscore: Integer); begin FHighscore := aHighscore; end; |
[Disclaimer] Der [s]-Tag in [quote]s dient hier nur zur Hervorhebung von Full/No Ack
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
Zuletzt bearbeitet von Hidden am Di 05.01.10 05:31, insgesamt 2-mal bearbeitet
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 00:02
Also ich habe es selber hinbekommen
Unit2:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure TForm2.BtHighscoreeintragenClick(Sender: TObject); begin with lvHighscore.Items.Add do begin Caption := EdName.Text; SubItems.Add(Form1.LbGebrauchteZeit.Caption); SubItems.Add(DateTimeToStr(Now)); end; end; |
und in Unit1 habe ich die LbGebrauchteZeit.Caption berechnen lassen, sobald das Spiel zu Ende ist.
Nun mal schauen, ob ich es hinbekommen, die Spielstände speichern zu lassen (in ner Datei  )
Danke!!!
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Di 05.01.10 00:10
Hi
Narses hatte schon Recht, der Zeitpunkt stimmt nicht  Die Anzeige sollte schon bei Spielende erfolgen, also aus der MainFrm aus. Das ist auch etwas einfacher, da so nur diese die HighscoreFrm kennen muss und nicht umgekehrt.
lg,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 00:38
Bekomme nun folgende Fehler beim Compilieren:
[DCC Fataler Fehler] F2039 Ausgabedatei 'Memory.exe' kann nicht erstellt werden
???
--- Moderiert von Narses: Beiträge zusammengefasst---
Problem ist behoben. Das Programm war noch 3mal geöffnet (habe es im TaskManager unter Prozess gekillt).
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 20:55
Ich bekomme leider trotz der Demo (von hier: www.delphi-library.d...ewtopic.php?t=70217) es nicht hin, das die Bestenliste gespeichert wird.
Von euch hat nicht zufällig einer kurz Lust mir dies einzubauen?
Das Projekt würde ich dann hochladen 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 05.01.10 22:16
Moin!
Vorschlag hat folgendes geschrieben : | Von euch hat nicht zufällig einer kurz Lust mir dies einzubauen? |
Einbauen?  Sicher nicht, aber ich würde mir mal anschauen, wo´s hakt.
Vorschlag hat folgendes geschrieben : | Das Projekt würde ich dann hochladen |
Dann pack mal alle Dateien, aber OHNE die EXE, aus dem Projekt in ein ZIP-Archiv hier in den Anhang.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 22:26
Ist derzeit jetzt mal ohne das in Datei speichern.
Werde morgen früh mich nochmal dransetzen oder vlt. später
Aber vielleicht erkennst du ja jetzt schon Fehler.
Zuletzt bearbeitet von Vorschlag am Di 05.01.10 22:57, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 05.01.10 22:34
Moin!
Vorschlag hat folgendes geschrieben : | Ist derzeit jetzt mal ohne das in Datei speichern. |
Ähm, du hast Probleme mit dem Speichern, aber den Code dazu nicht drin. Was nutzt das dann jetzt?
Vorschlag hat folgendes geschrieben : | Werde morgen früh mich nochmal dransetzen oder vlt. später  |
Melde dich nochmal, wenn du den Code drin hast, der nicht funktioniert.
cu
Narses
//EDIT: Fenstertitel hat folgendes geschrieben: | Memory - Copyright 2010 by Matthias K. |
Interessant, wenn man bedenkt, dass der Quelltext des Spiels wörtlich dem Tutorial entspricht...
Moderiert von Narses: Name auf Anfrage gekürzt.
_________________ There are 10 types of people - those who understand binary and those who don´t.
Zuletzt bearbeitet von Narses am Do 21.01.10 17:41, insgesamt 1-mal bearbeitet
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 22:56
pssst...
Dieses Programm wird ja auch nicht veröffentlicht, sondern nur in der Schule abgegeben
Könntest du vielleicht bitte meinen Namen aus dem Zitat löschen?
Ich hatte gestern die Version mit Dateispeicherung wieder gelöscht und die letzte funktionierende weiterbenutzt. Ich werde später (oder morgen) nochmal die Dateispeicherungsversion uploaden.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 05.01.10 23:06
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Di 05.01.10 23:24
so mal schnell zusammengesetzt...
Moderiert von Narses: Gelöschten Anhang wiederhergestellt.
Einloggen, um Attachments anzusehen!
Zuletzt bearbeitet von Vorschlag am Di 19.01.10 16:47, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 06.01.10 00:29
Moin!
Vorschlag hat folgendes geschrieben : | so mal schnell zusammengesetzt... |
Jup, so ist es.
Was mir auf Anhieb beim Drüberschauen aufgefallen ist: - Wenn man ein Spiel "gewonnen" (=alle Paare gefunden) hat, dann kommt dieser Dialog:
Zitat: | ---------------------------
Memory
---------------------------
Herzlichen Glückwunsch Sie haben gewonnen!
Benötigte Zeit in Sekunden: 38
Sie haben 22 Züge gebraucht und haben 9 Paare gefunden.
---------------------------
OK
--------------------------- | Aha? Kann man auch mehr oder weniger als 9 Paare bei meiner Memory-Version finden?
- Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten.
- Man kann sogar Highscores mit Spielen anlegen, die gerade erst gestartet wurden (also ohne Züge/Paare/Zeit).
- Man kann Highscores ohne Namen hinzufügen. (wozu?)
- Wenn man das Highscore- oder Hilfefenster mit dem X oben rechts schließt, "hängt" das Programm!
-> Liegt daran, dass du das Hauptformular wechselweise zu den anderen (Neben-)Formularen ein-/ausblendest. Wenn das Hauptformular aber ausgeblendet ist, kann ich das Programm nicht mehr bedienen oder schließen. Ansatz: Zeige die beiden anderen Formulare modal an, dann kann das nicht passieren.
- FormClose der Highscore-Form wird nie ausgeführt, weil du das Programm mit Application.Terminate beendest; solltest du auf Close der MainForm umstellen, sonst wird das nie was.
- LoadHighscores wird nie aufgerufen, kann also nichts laden.
- Aber selbst wenn es aufgerufen würde, es wird nicht funktionieren, weil du den Code aus meinem (Highscore-)Tutorial wieder wörtlich abgeschrieben hast, ohne beim Laden auf die Anpassungen einzugehen, die für dein Format der Liste nötig wären. Z.B.:
Delphi-Quelltext 1:
| if (Zeile.Count = 3) then | Du hast jeweils 5 Elemente in einer Highscore-Zeile, also wird keine Zeile überhaupt geladen. Und selbst wenn man aus der 3 eine 5 macht klappt´s nicht, weil der Code, der eine Highscorezeile neu erstellt, nicht angepasst ist.
cu
Narses
Einloggen, um Attachments anzusehen!
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Vorschlag 
      
Beiträge: 63
|
Verfasst: Mi 06.01.10 10:12
Narses hat folgendes geschrieben : |
Was mir auf Anhieb beim Drüberschauen aufgefallen ist:- Wenn man ein Spiel "gewonnen" (=alle Paare gefunden) hat, dann kommt dieser Dialog:
Zitat: | ---------------------------
Memory
---------------------------
Herzlichen Glückwunsch Sie haben gewonnen!
Benötigte Zeit in Sekunden: 38
Sie haben 22 Züge gebraucht und haben 9 Paare gefunden.
---------------------------
OK
--------------------------- | Aha? Kann man auch mehr oder weniger als 9 Paare bei meiner Memory-Version finden?
|
Da hast du Recht  Habe ich geändert.
Narses hat folgendes geschrieben : |
Wenn ein Spiel zuende ist, kann ich nochmal einen Highscore eintragen, zwar "nicht fertig", aber mit den restlichen Daten.
|
Wie kann ich dies unterbinden?
Narses hat folgendes geschrieben : |
Man kann sogar Highscores mit Spielen anlegen, die gerade erst gestartet wurden (also ohne Züge/Paare/Zeit).
|
Habe ich entfernt.
Narses hat folgendes geschrieben : |
Man kann Highscores ohne Namen hinzufügen. (wozu?)
|
Danke für den Tipp, habe ich korrigiert
Narses hat folgendes geschrieben : |
Wenn man das Highscore- oder Hilfefenster mit dem X oben rechts schließt, "hängt" das Programm! -> Liegt daran, dass du das Hauptformular wechselweise zu den anderen (Neben-)Formularen ein-/ausblendest. Wenn das Hauptformular aber ausgeblendet ist, kann ich das Programm nicht mehr bedienen oder schließen. Ansatz: Zeige die beiden anderen Formulare modal an, dann kann das nicht passieren.
|
Was meinst du mit modal?
Narses hat folgendes geschrieben : |
FormClose der Highscore-Form wird nie ausgeführt, weil du das Programm mit Application.Terminate beendest; solltest du auf Close der MainForm umstellen, sonst wird das nie was.
|
Hattest du dies vielleicht schon in deiner Version gefixt? Weil dort steht ja:
Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm2.BtnExitClick(Sender: TObject); begin Form1.Close; end; |
und
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin SaveHighscores; end; |
?
Narses hat folgendes geschrieben : |
LoadHighscores wird nie aufgerufen, kann also nichts laden.
|
Delphi-Quelltext 1: 2: 3: 4:
| procedure TForm2.FormCreate(Sender: TObject); begin LoadHighscores; end; |
Ist damit gefixt worden?
Narses hat folgendes geschrieben : |
Aber selbst wenn es aufgerufen würde, es wird nicht funktionieren, weil du den Code aus meinem (Highscore-)Tutorial wieder wörtlich abgeschrieben hast, ohne beim Laden auf die Anpassungen einzugehen, die für dein Format der Liste nötig wären. Z.B.:
Delphi-Quelltext 1:
| if (Zeile.Count = 3) then | Du hast jeweils 5 Elemente in einer Highscore-Zeile, also wird keine Zeile überhaupt geladen. Und selbst wenn man aus der 3 eine 5 macht klappt´s nicht, weil der Code, der eine Highscorezeile neu erstellt, nicht angepasst ist. |
Ich versucht dies umzusetzen... (hoffentlich schaffe ich es...)
Ich werde nachher nochmal meinen aktuellen Stand hochladen, falls du nochmal drüber sehen möchtest.
|
|
Dieses Thema ist gesperrt, Du kannst keine Beiträge editieren oder beantworten.
Das Thema wurde von einem Team-Mitglied geschlossen. Wenn du mit der Schließung des Themas nicht einverstanden bist, kontaktiere bitte das Team.
|
|