![]() |
Programm stoppt
Hallo und guten Tag,
Ich habe vor kurzem ein kleines Spiel in Delphi geschrieben, welches Pfeilfänger heißt: Mithilfe einer TImage-Componente werden Labels aufgefangen, wodurch man sich dann die Punkte kassiert... Nur bloß irgendwann (letzte Label's bei Spielsessions sind unterschiedlich) hören die Label auf sich überhaupt zu bewegen... Hier der Vollständige Code:
Delphi-Quellcode:
Ich hoffe ihr könnt mir helfen...
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.Imaging.pngimage, Vcl.Menus, Vcl.StdCtrls, Vcl.Buttons; type TForm1 = class(TForm) Image1: TImage; Label3: TLabel; SpeedButton1: TSpeedButton; Label7: TLabel; Label14: TLabel; Label13: TLabel; Label12: TLabel; Label11: TLabel; Label10: TLabel; Label5: TLabel; Label6: TLabel; Label9: TLabel; Label8: TLabel; Label2: TLabel; Label1: TLabel; Label4: TLabel; Timer1: TTimer; Memo1: TMemo; Memo2: TMemo; Label15: TLabel; Label16: TLabel; procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure SpeedButton1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure labelmove(labe: Tlabel); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; gamestarted: boolean; gamestartclick, punktetemporär, imagetop, buttonspace, labelspace, imagespace, zeit, zufallslabel: integer; implementation uses Unit2; {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); begin memo1.Lines.Clear; memo2.Lines.Clear; memo1.Lines.LoadFromFile('languages\session-language.txt'); memo2.Lines.LoadFromFile('languages\' + memo1.Lines[0] + '.lang'); Form1.Caption:=memo2.Lines[0]; Speedbutton1.Caption:=memo2.Lines[1]; Schlieen1.Caption:=memo2.Lines[3]; Spiel1.Caption:=memo2.Lines[2]; Einstellungen1.Caption:=memo2.lines[4]; N1.Caption:=memo2.lines[5]; Spieleinstellungen1.Caption:=memo2.Lines[6]; Hilfe1.Caption:=memo2.lines[7]; Benutzung1.Caption:=memo2.lines[8]; ber1.Caption:=memo2.lines[9]; gamestartclick:=0; timer1.interval:=50; zeit:=0; punktetemporär:=0; randomize; imagetop:=Image1.Top; imagespace:=Image1.Left + Image1.Width; buttonspace:=Speedbutton1.Width; labelspace:=label1.Left; Label1.Font.Color:=clblack; Label2.Font.Color:=clblack; Label3.Font.Color:=clblack; Label4.Font.Color:=clblack; Label5.Font.Color:=clblack; Label6.Font.Color:=clblack; Label7.Font.Color:=clblack; Label8.Font.Color:=clblack; Label9.Font.Color:=clblack; Label10.Font.Color:=clblack; Label11.Font.Color:=clblack; Label12.Font.Color:=clblack; Label13.Font.Color:=clblack; Label14.Font.Color:=clblack; end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: word; Shift: TShiftState); begin if gamestarted=true then begin case Key of VK_UP: if image1.Top - 50 <0 then begin image1.Top := image1.Top; end else image1.Top := image1.Top - 50; VK_DOWN: if image1.Top + 475 > Form1.Height then begin image1.Top := image1.Top end else image1.Top := image1.Top + 50; end; end; end; procedure TForm1.SpeedButton1Click(Sender: TObject); begin gamestartclick:= gamestartclick + 1; if ((gamestarted=False) and (gamestartclick mod 2 = 1)) then begin gamestarted:=True; timer1.Enabled:=True; Speedbutton1.Enabled:=False; end; end; procedure TForm1.Timer1Timer(Sender: TObject); var i, hochzählen: integer; begin zeit:=zeit+1; if zeit = 40 then begin zufallslabel:=random(14)+1; end; if zufallslabel=1 then begin labelmove(Label1); if ((((Label1.Left <= imagespace) and (Label1.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*8)) or (Image1.Top=imagetop+(50*7)))) then begin Label1.Left:=labelspace; Label1.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=2 then begin if ((((Label2.Left <= imagespace) and (Label2.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*8)) or (Image1.Top=imagetop+(50*7)) or (Image1.Top=imagetop+(50*6)) or (Image1.Top=imagetop+(50*5)))) then begin Label2.Left:=labelspace; Label2.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=3 then begin labelmove(Label3); if ((((Label3.Left <= imagespace) and (Label3.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*8)) or (Image1.Top=imagetop+(50*7)) or (Image1.Top=imagetop+(50*6)) or (Image1.Top=imagetop+(50*5)) or (Image1.Top=imagetop+(50*4)))) then begin Label3.Left:=labelspace; Label3.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=4 then begin labelmove(Label4); if ((((Label4.Left <= imagespace) and (Label4.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*8)) or (Image1.Top=imagetop+(50*7)) or (Image1.Top=imagetop+(50*6)) or (Image1.Top=imagetop+(50*5)) or (Image1.Top=imagetop+(50*4)) or (Image1.Top=imagetop+(50*3)) or (image1.Top=imagetop+(50*2)))) then begin Label4.Left:=labelspace; Label4.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=5 then begin labelmove(Label5); if ((((Label5.Left <= imagespace) and (Label5.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*6)) or (Image1.Top=imagetop+(50*5)) or (Image1.Top=imagetop+(50*4)) or (Image1.Top=imagetop+(50*3)) or (Image1.Top=imagetop+(50*2)) or (Image1.Top=imagetop+(50*1)))) then begin Label5.Left:=labelspace; Label5.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=6 then begin labelmove(Label6); if ((((Label6.Left <= imagespace) and (Label6.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*5)) or (Image1.Top=imagetop+(50*4)) or (Image1.Top=imagetop+(50*3)) or (Image1.Top=imagetop+(50*2)) or (Image1.Top=imagetop+(50*1)) or (Image1.Top=imagetop+(50*0)) or (Image1.Top=imagetop+(50*(-1))))) then begin Label6.Left:=labelspace; Label6.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=7 then begin labelmove(Label7); if ((((Label7.Left <= imagespace) and (Label7.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*3)) or (Image1.Top=imagetop+(50*2)) or (Image1.Top=imagetop+(50*1)) or (Image1.Top=imagetop+(50*0)) or (Image1.Top=imagetop+(50*(-1))) or (Image1.Top=imagetop+(50*(-2))))) then begin Label7.Left:=labelspace; Label7.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=8 then begin labelmove(Label8); if ((((Label8.Left <= imagespace) and (Label8.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*2)) or (Image1.Top=imagetop+(50*1)) or (Image1.Top=imagetop+(50*0)) or (Image1.Top=imagetop+(50*(-1))) or (Image1.Top=imagetop+(50*(-2))) or (Image1.Top=imagetop+(50*(-3))) or (Image1.Top=imagetop+(50*(-4))))) then begin Label8.Left:=labelspace; Label8.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=9 then begin labelmove(Label9); if ((((Label9.Left <= imagespace) and (Label9.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*0)) or (Image1.Top=imagetop+(50*(-1))) or (Image1.Top=imagetop+(50*(-2))) or (Image1.Top=imagetop+(50*(-3))) or (Image1.Top=imagetop+(50*(-4))) or (Image1.Top=imagetop+(50*(-5))))) then begin Label9.Left:=labelspace; Label9.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=10 then begin labelmove(Label10); if ((((Label10.Left <= imagespace) and (Label10.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*(-1))) or (Image1.Top=imagetop+(50*(-2))) or (Image1.Top=imagetop+(50*(-3))) or (Image1.Top=imagetop+(50*(-4))) or (Image1.Top=imagetop+(50*(-5))) or (Image1.Top=imagetop+(50*(-6))) or (Image1.Top=imagetop+(50*(-7))))) then begin Label10.Left:=labelspace; Label10.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=11 then begin labelmove(Label11); if ((((Label11.Left <= imagespace) and (Label11.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*(-3))) or (Image1.Top=imagetop+(50*(-4))) or (Image1.Top=imagetop+(50*(-5))) or (Image1.Top=imagetop+(50*(-6))) or (Image1.Top=imagetop+(50*(-7))) or (Image1.Top=imagetop+(50*(-8))))) then begin Label11.Left:=labelspace; Label11.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=12 then begin labelmove(Label12); if ((((Label12.Left <= imagespace) and (Label12.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*(-4))) or (Image1.Top=imagetop+(50*(-5))) or (Image1.Top=imagetop+(50*(-6))) or (Image1.Top=imagetop+(50*(-7))) or (Image1.Top=imagetop+(50*(-8))))) then begin Label12.Left:=labelspace; Label12.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=13 then begin labelmove(Label13); if ((((Label13.Left <= imagespace) and (Label13.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*(-6))) or (Image1.Top=imagetop+(50*(-7))) or (Image1.Top=imagetop+(50*(-8))))) then begin Label13.Left:=labelspace; Label13.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; if zufallslabel=14 then begin labelmove(Label14); if ((((Label14.Left <= imagespace) and (Label14.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*(-7))) or (Image1.Top=imagetop+(50*(-8))))) then begin Label14.Left:=labelspace; Label14.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end; end; end; procedure TForm1.labelmove(labe: Tlabel); begin labe.Font.Color:=clbtnface; if labe.Left>buttonspace then begin labe.Left:=labe.Left - 33; end; if labe.Left<=buttonspace then begin Timer1.Enabled:=False; gamestarted:=False; punktetemporär:=0; Label16.Caption:=' 0'; gamestartclick:=0; zeit:=0; zufallslabel:=0; showmessage('Sie haben verloren.'); Speedbutton1.Enabled:=True; Speedbutton1.Caption:='Spiel starten'; image1.Top:=imagetop; Label1.Left:=labelspace; Label2.Left:=labelspace; Label3.Left:=labelspace; Label4.Left:=labelspace; Label5.Left:=labelspace; Label6.Left:=labelspace; Label7.Left:=labelspace; Label8.Left:=labelspace; Label9.Left:=labelspace; Label10.Left:=labelspace; Label11.Left:=labelspace; Label12.Left:=labelspace; Label13.Left:=labelspace; Label14.Left:=labelspace; Label1.Font.Color:=clblack; Label2.Font.Color:=clblack; Label3.Font.Color:=clblack; Label4.Font.Color:=clblack; Label5.Font.Color:=clblack; Label6.Font.Color:=clblack; Label7.Font.Color:=clblack; Label8.Font.Color:=clblack; Label9.Font.Color:=clblack; Label10.Font.Color:=clblack; Label11.Font.Color:=clblack; Label12.Font.Color:=clblack; Label13.Font.Color:=clblack; Label14.Font.Color:=clblack; end; end; end. Vielleicht ist das Thema nicht richtig benannt, aber mir ist dabei nichts anderes eingefallen... Freuen würde ich mich auch auf schnellsten Rat von euch, Vielen Dank |
AW: Programm stoppt
1. Falsches Forum
2. Erwartest Du im Ernst, dass sich jemand durch diesen Spaghetti-Code durchwuselt, in dem nicht einmal anständige Bezeichner verwendet werden und der von DRY nur so strotzt? 3. Der Debugger ist Dein Freund, notfalls eine Log-Datei erstellen und da reinschauen, welche Werte beim Auftreten des Problems gesetzt sind. |
AW: Programm stoppt
Naja, sagen wir mal so: Da wird ein Timer verwendet. Ist das Timerinterval kürzer als die Zeit zum Abarbeiten der bei OnTimer aufgerufenen Routine, kann sowas schon passieren.
Bei der Nutzung von Timern mache ich im OnTimer als erstes immer ein
Delphi-Quellcode:
und am Ende, sofern der Timer weiterlaufen soll, ein
Timer1.Enabled = false;
Delphi-Quellcode:
.
Timer1.Enabled := true;
Dadurch erhöht sich jedoch defakto das Timerinterval um die Laufzeit der Timerroutine. Eventuell suchst Du mal nach "überflüssigem" Code und entfernst ihn. Mir erschließt sich nicht, was z. B. ein
Delphi-Quellcode:
bezwecken soll.
image1.Top := image1.Top;
|
AW: Programm stoppt
Danke für alle Tips...
Aber ich arbeite IMMER mit Standardbezeichnern bei Vcl-Komponenten... Und ich bin extra in dieses Forum eingestiegen, da ich sehr gute Tips erhofft habe (die auch MEISTENS oder FAST IMMER gegeben werden) Und da ist noch etwas: ich programmiere schon mein zweites Jahr mit Delphi (ich bin 14 Jahre alt) und kann doch nicht alles darüber wissen... Daher denke ich immer zuerst nach, wo der Fehler liegt... Da es nach meinen Erkundungen keine Compiler-Fehler gibt, suche ich zunächst im Internet nach Lösungen der Fehler beim Programmcode, und wenn ich überhaupt nicht weiterkomme, besuche ich Delphi-PRAXiS mit meiner Frage... Entschuldigt bitte für die unnützlichen Infos, obwohl sie für Verständnis ziemlich nützlich sein könnten... Ich werde die gegebenen Tipps nun versuchen einzusetzen... DANKE |
AW: Programm stoppt
Tut mir Leid, aber Delphi.Narium's Tipp hat nicht geklappt...
|
AW: Programm stoppt
Ok, mit 14 Jahren muss Du noch nicht allzuviel Erfahrung haben ;-) Das kommt schon mit der Zeit.
Was mich ein bisserl irritiert:
Delphi-Quellcode:
((Image1.Top=imagetop+(50*6)) or (Image1.Top=imagetop+(50*5)) or (Image1.Top=imagetop+(50*4)) or (Image1.Top=imagetop+(50*3)) or (Image1.Top=imagetop+(50*2)) or (Image1.Top=imagetop+(50*1)))) then
50 * 6 ist immer 300 50 * 5 ist immer 250 50 * 4 ist immer 200 50 * 3 ist immer 150 50 * 2 ist immer 100 50 * 1 ist immer 50 und 50 * 0 ist immer 0 Statt jedesmal rechnen zu lassen, schreib dort einfach jeweils die Ergebnisse hin. Spart (vermutlich) Rechenzeit (ein bisserl ;-)) und macht den Quelltext lesbarer. Kannst Dafür aber auch Konstanten definieren, die Du dann im ganzen Programm benutzen kannst. Sollte dann mal eine Änderung nötig sein, so musst Du nur die Konstanten ändern und nicht im ganzen Programm nach den Stellen im Quelltext suchen, in denen Du letztlich immer die gleichen Berechnungen vorgenommen hast. Sollte es also mal erforderlich sein, statt der 50 eine 60 zu nehmen, so kannst Du einfach Deine Konstanten ändern und musst nicht nach "tausenden" 50 im Programm suchen und sie durch 60 ersetzen. Bei der VCL immer de Standardnamen zu verwenden, kann man so machen. Das hab' ich mir aber längst abgewöhnt. Label heißen bei mir z. B. immer lbEineaussagekräftigeBezeichnung. Desgleichen für Edits, Buttons ... Ich will halt beim Lesen des Quelltextes auch bei Controls der VCL immer wissen, wofür sie da sind und nicht erst immer im Formular nachschauen müssen oder mir merken wofür Label1 ist, wofür Label2 ist. Spätestens wenn man mal in mehreren Programmen "unterwegs" ist, kann man sich die Standardnamen und ihren Verwendungszweck nicht mehr merken. Ist jetzt Label1 in diesem Programm für Aufgabe X oder war das in dem anderen Programm so und hier ist es für Aufgabe Y ... Wenn die Labels aufhören sich zu bewegen, ist dann im Taskmanager noch zu sehen, ob das Programm arbeitet oder ist dort die CPU-Last niedrig. Könnte es sein, dass bei den Berechnungen irgendwann ein Punkt erreicht ist, bei dem die Berechnungsergebnisse einfach nicht mehr zu einer Bewegung der Labels führen? |
AW: Programm stoppt
Zitat:
|
AW: Programm stoppt
Ok, keine Rechenzeit gespart (nur (marginal?)) Kompilierzeit ;-)
Aber der Gewinn an Lesbarkeit dürfte erhalten bleiben ;-) |
AW: Programm stoppt
Moin...:P
Zitat:
Du hast es in "Neuen Beitrag zur Code-Library hinzufügen" eingestellt. Besser wäre aber "Programmieren allgemein"...oder so. :wink: Zitat:
DRY: ![]() KISS: ![]() Später SOLID: ![]() |
AW: Programm stoppt
Keine Idee ob das das Problem löst, aber in der Timer-Prozedur fehlt das "labelmove(Label2);" das analog für alle anderen Labels vorhanden ist.
Bist du bereit was zu lernen und für Vorschläge wie man "sauberer" programmiert offen? Dein Code würde kürzer und übersichtlicher werden und solche Fehler würden schneller auffallen. Beispiel: Diesen Block verwendest du (nur mit einem anderen Label) immer wieder im der Timer-Prozedur:
Delphi-Quellcode:
das könnte man in eine Prozedur auslagern und muss dass nicht immer wiederholen:begin Label1.Left:=labelspace; Label1.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end;
Delphi-Quellcode:
und in der TimerProzedur stünde z.B.:procedure ResetLabelAndIncreasePoints(labe:TLabel) begin Labe.Left:=labelspace; Labe.Font.Color:=clblack; punktetemporär:=punktetemporär + 10; Label16.Caption:=' ' + inttostr(punktetemporär); zufallslabel:=random(14)+1; end;
Delphi-Quellcode:
Nur als erster Ansatz einer Verbesserung.
//...
if zufallslabel=1 then begin labelmove(Label1); if ((((Label1.Left <= imagespace) and (Label1.Left >= (imagespace-32)))) and ((Image1.Top=imagetop+(50*8)) or (Image1.Top=imagetop+(50*7)))) then begin ResetLabelAndIncreasePoints(label1) end; end; Noch einfacher würde es im nächsten Schritt, wenn du alle Labels in einer Liste oder einem Array speicherst (bei Programmstart) und dann kannst du über einen Index auf ein Label zugreifen und die TimerProzedur sähe nur noch so aus:
Delphi-Quellcode:
Sorry für das Denglisch
//...
zufallszahl:=random(14)+1; //eigentl. auch neue Prozedur ala GenerateNextZufallszahl //... zufallslabel:=TLabel(ListeMitLabels[zufallszahl]); if movelabel(zufallslabel) then //movelabel wird Funktion die True zurückgibt wenn Spielende noch nicht erreicht begin if SeltsameBedingungErfüllt then begin ResetLabel; IncreasePoints; DisplayPoints; zufallszahl:=random(14)+1; end; end else begin SendGameOverMessage; ResetGame; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz