![]() |
[Snake-Spiel] - brauche eure Hilfe
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo erstmal ^^
ich bräuchte mal eure Hilfe. Für die Schule muss ich ein beliebiges Programm schreiben. Als Projekt, dacht ich mir eignet sich ein simples Spiel, wie 'Snake'. Das Spiel läuft zwar, aber gelegendlich wird folgende Fehlermeldungen angezeigt (Zugriffsverletzung) ![]() Das Programm besteht aus 2 Formen. Die 2. Form is einfach nur für den Highscore. Ist aber denk ich hier unwichtig, deshalb post ich hier nur die erste Form, sprich die Main-Form. Nachdem ich den Highscore eingebaut hatte, tauchten die Fehlermeldungen erst auf. Auch das, wenn man sich selbst beist, wird das Spiel beendet, funktioniert nicht mehr. Keine Ahnung an was das liegen könnte ^^ Auch stört mich, dass das schwarze Spielfeld "ausradiert" wird, wenn man z.B. mit der 2.ten Form drübergeht. Ich hoffe ihr habt paar Tips, da das Programm auch nicht wirklich sauber programmiert ist, denke ich. Ich hänge die Project files, als Dateianhang noch an. Hier ist der Code, der ersten Form. Danke schonmal :D
Delphi-Quellcode:
unit Snake1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, MMSystem, inifiles, ComCtrls, Buttons, highscore2; const farben: Array [0..3] of TColor = (clBlack, clLime, clRed, clBlue); raster = 10; //10 Pixel = 1 Feld breite = 24; //0 bis 24 -> 25 * 10(Raster) = Breite von 250 Pixeln hoehe = 24; // '' type TForm1 = class(TForm) PaintBox1: TPaintBox; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; Button5: TButton; Timer1: TTimer; Button6: TButton; Label1: TLabel; Image1: TImage; GroupBox1: TGroupBox; CheckBox1: TCheckBox; Label2: TLabel; Image2: TImage; Label3: TLabel; BitBtn1: TBitBtn; Label4: TLabel; GroupBox2: TGroupBox; BitBtn2: TBitBtn; BitBtn4: TBitBtn; Label5: TLabel; BitBtn3: TBitBtn; GroupBox3: TGroupBox; GroupBox4: TGroupBox; Label9: TLabel; Label6: TLabel; procedure Button1Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button6Click(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure BitBtn1Click(Sender: TObject); procedure FormShow(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure BitBtn4Click(Sender: TObject); procedure BitBtn3Click(Sender: TObject); private { Private-Deklarationen } //Privater Bereich für Prozeduren die für kein anderes Objekt //aufgerufen werden und nicht außerhalb der Form benötigt werden. map: Array [0..breite] of Array [0..hoehe] of Integer; kopf, richtung, futter: TPoint; laenge, punkte: Integer; ende: Boolean; procedure buttons_freigeben(status: Boolean); procedure spiel_ende; procedure neues_futter; procedure spielfeld; procedure schlange; public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} type zaehlertyp = array [1..1] of integer; var einmaligercountdown: zaehlertyp; procedure InIniSchreiben (Filename, Section, Key, Value: string); var ini: Tinifile; begin ini:= tinifile.Create(Filename); try ini.WriteString(section, key, value); finally ini.Free; end; end; function InIniLesen (Filename, Section, Key: string):string; var ini: Tinifile; begin ini:= tinifile.Create(Filename); try result:= ini.ReadString(section, key, ''); finally ini.Free; end; end; procedure Delay (const Milliseconds: DWord); var FirstTickCount: DWord; begin FirstTickCount:= GetTickCount; while ((GetTickCount - FirstTickCount) < Milliseconds) do begin Application.ProcessMessages; Sleep(0); end; end; procedure TForm1.spiel_ende; begin ende:= True; Timer1.Enabled:= False; buttons_freigeben(False); Button1.Enabled:= True; button6.Enabled:= false; end; procedure TForm1.neues_futter; begin futter:= Point(Random(breite), Random(hoehe)); while map[futter.X, futter.Y] <> 0 do futter:= Point(Random(breite), Random(hoehe)); map[futter.X,futter.Y]:= -1; end; procedure TForm1.spielfeld; var i, j: Integer; col: TColor; begin for i := 0 to breite do for j := 0 to hoehe do begin case map[i, j] of -1: col := farben[1]; 0: col:= farben[0]; else col:= farben[2]; end; PaintBox1.Canvas.Brush.Color:=col; PaintBox1.Canvas.FillRect(Rect(i*raster, j*raster, (i+1)*raster, (j+1)*raster)); end; end; procedure TForm1.schlange; var i, j: Integer; begin for i:= 0 to breite do for j:= 0 to hoehe do if map[i, j] > 0 then Dec(map[i, j]); Inc(kopf.X, richtung.X); Inc(kopf.Y, richtung.Y); if checkbox1.Checked= true then begin if (kopf.X < 0) then Kopf.X:= kopf.X + Breite + 1; if Kopf.Y < 0 then Kopf.Y:= kopf.Y + Hoehe + 1; if Kopf.X > Breite then Kopf.X:= Kopf.x - Breite - 1; if Kopf.Y > Hoehe then Kopf.Y:= Kopf.Y - Hoehe - 1; end else if (kopf.X < 0) or (kopf.X > breite) or (kopf.Y < 0) or (kopf.Y > hoehe) then begin spiel_ende; checkbox1.Enabled:= true; if label1.Caption > label5.Caption then begin form1.Enabled:= false; form2.Label3.Caption:= inttostr(punkte-1); form2.Show; end else showmessage('Spiel beendet' + #10#13 + 'Du hast den Rand berührt'); if (map[kopf.X, kopf.Y]>0) and (not ende) then begin spiel_ende; checkbox1.Enabled:= true; if label1.Caption > label5.Caption then begin form1.Enabled:= false; form2.Label3.Caption:= inttostr(punkte-1); form2.Show; end else showmessage('Spiel beendet' + #10#13 + 'Du hadt dich selbst gebissen'); end; end; if (kopf.X = futter.X) and (kopf.Y = futter.Y) then begin Inc(laenge); neues_futter; label1.Caption:= inttostr(punkte); inc(punkte); end; map[kopf.X, kopf.Y] := laenge; end; procedure TForm1.Button1Click(Sender: TObject); var i, j, zaehler: Integer; begin inc(einmaligercountdown[1]); label1.Caption:= '0'; punkte:= 1; zaehler:= 3; spielfeld; label3.Visible:= true; if einmaligercountdown[1]= 1 then begin while zaehler > 0 do begin dec(zaehler); delay(1000); label3.Caption:= inttostr(zaehler); end; end; Button1.Enabled := False; button6.Enabled:= true; checkbox1.Enabled:= false; for i:=0 to breite do for j:=0 to hoehe do map[i, j] := 0; kopf:= Point(1, 1); laenge:= 5; richtung := Point(0, 1); map[kopf.X, kopf.Y]:= laenge; neues_futter; buttons_freigeben(True); ende:= False; Timer1.Enabled := True; end; procedure TForm1.Timer1Timer(Sender: TObject); begin schlange; if not ende then spielfeld; end; procedure TForm1.FormShow(Sender: TObject); var filename: string; begin filename:= extractfilepath(application.ExeName)+'Highscore.ini'; if fileexists(filename) then begin label4.Caption:= InIniLesen(Filename,'Highscore','var1') + ' : '; label5.Caption:= InIniLesen(Filename,'Highscore','var2') + ' Punkte'; end else begin InIniSchreiben(Filename, 'Highscore','var1','keiner'); InIniSchreiben(Filename, 'Highscore','var2','0'); label4.Caption:= InIniLesen(Filename,'Highscore','var1') + ' : '; label5.Caption:= InIniLesen(Filename,'Highscore','var2') + ' Punkte'; end; end; end. |
Re: [Snake-Spiel] - brauche eure Hilfe
Hallo und Willkommen in der DP :dp:,
beschränk den Code doch bitte auf das Wesentliche, zumindest ich habe keine Lust, mir den jetzt komplett anzuschauen. Und zum "Radieren": Zeichenoperationen schreibt man im Allgemeinen ins OnPaint-Ereignis der entsprechenden Komponente (Form, Paintbox, etc.), dann tritt dieser Effekt auch nicht auf. |
Re: [Snake-Spiel] - brauche eure Hilfe
ok, hab ich gemacht.
|
Re: [Snake-Spiel] - brauche eure Hilfe
Zitat:
Delphi-Quellcode:
mit if button1.click hat es nicht funktioniert
procedure TForm1.PaintBox1Paint(Sender: TObject);
var i, j: Integer; col: TColor; begin for i := 0 to breite do for j := 0 to hoehe do begin case map[i, j] of -1: col := farben[1]; 0: col:= farben[0]; else col:= farben[2]; end; PaintBox1.Canvas.Brush.Color:=col; PaintBox1.Canvas.FillRect(Rect(i*raster, j*raster, (i+1)*raster, (j+1)*raster)); end; end; |
Re: [Snake-Spiel] - brauche eure Hilfe
Das Paint wird automatisch aufgerufen, wenn das Control neu gezeichnet werden muss (etwa weil man ein anderes Fenster darübergezogen hat). Wenn Du es von Hand anstoßen willst, kannst Du Paintbox.Repaint aufrufen.
|
Re: [Snake-Spiel] - brauche eure Hilfe
danke, klappt super!
nur das Bild flackert ziemlich, da das Bild dauernd refresht oder neu gezeichnet werden muss. sodass die schlange sich bewegt.
Delphi-Quellcode:
procedure TForm1.Timer1Timer(Sender: TObject);
begin schlange; if not ende then paintbox1.repaint; //paintbox1.Refresh; end; |
Re: [Snake-Spiel] - brauche eure Hilfe
Delphi-Quellcode:
ist deine Lösung ;)
DoubleBuffered:=true;
edit: delphi-tags^^ edit#2: Setz die Zeile in OnCreate deiner Form^^ |
Re: [Snake-Spiel] - brauche eure Hilfe
Liste der Anhänge anzeigen (Anzahl: 1)
danke für die Antworten.
Ich hab jetzt alles wieder übeareitet. Nun funktioniert auch alles, außer 2 Dinge. 1. gelegentlich taucht plätzlich folgende Fehlermeldung auf: ![]() 2. der Highscore funktioniert nicht immer ^^ hier eine kurze erklärung, wie der Highscore in meinem Programm funktionieren soll. --- wenn das Programm gestartet wird, wird ein .ini Datei estellt, falls diese noch nicht vorhanden ist. in die .ini Datei wird die Punktzahl '0' reingeschreiben, die dann in ein label-feld in der Form abgespeichert wird. wenn man das Spiel beendet, bzw verloren hat, wird die aktuell erreichte Punktzahl mit der aus diesem label-feld verglichen. wenn die gerade erreichte Punktzahl größer, als die im label (in der ini datei) ist, dann wird die 2. Form geladen, inder man dann seinen Namen einträgt und dieser dann, mit der erreichten Punnktzahl in die ini datei geschreiben wird. hier mal der Code:
Delphi-Quellcode:
2. Form:procedure InIniSchreiben (Filename, Section, Key, Value: string); var ini: Tinifile; begin ini:= tinifile.Create(Filename); try ini.WriteString(section, key, value); finally ini.Free; end; end; function InIniLesen (Filename, Section, Key: string):string; var ini: Tinifile; begin ini:= tinifile.Create(Filename); try result:= ini.ReadString(section, key, ''); finally ini.Free; end; end; procedure Delay (const Milliseconds: DWord); var FirstTickCount: DWord; begin FirstTickCount:= GetTickCount; while ((GetTickCount - FirstTickCount) < Milliseconds) do begin Application.ProcessMessages; Sleep(0); end; end; procedure TForm1.spiel_ende; begin ende:= True; Timer1.Enabled:= False; buttons_freigeben(False); Button1.Enabled:= True; button6.Enabled:= false; end; procedure TForm1.schlange; var i, j: Integer; filename: string; begin for i:= 0 to breite do for j:= 0 to hoehe do if map[i, j] > 0 then Dec(map[i, j]); Inc(kopf.X, richtung.X); Inc(kopf.Y, richtung.Y); if checkbox1.Checked= true then begin if (kopf.X < 0) then Kopf.X:= kopf.X + Breite + 1; if Kopf.Y < 0 then Kopf.Y:= kopf.Y + Hoehe + 1; if Kopf.X > Breite then Kopf.X:= Kopf.x - Breite - 1; if Kopf.Y > Hoehe then Kopf.Y:= Kopf.Y - Hoehe - 1; end else if (kopf.X < 0) or (kopf.X > breite) or (kopf.Y < 0) or (kopf.Y > hoehe) then begin spiel_ende; showmessage('Spiel beendet' + #10#13 + 'Sie haben den Rand berührt'); checkbox1.Enabled:= true; if label10.Caption > label17.Caption then begin form2.Label3.Caption:= inttostr(punkte-1); form2.Show; end; end; if (map[kopf.X, kopf.Y]>0) and (not ende) then begin spiel_ende; showmessage('Spiel beendet' + #10#13 + 'Sie haben sich selbst gebissen'); checkbox1.Enabled:= true; if label10.Caption > label17.Caption then begin form2.Label3.Caption:= inttostr(punkte-1); form2.Show; end; end;
Delphi-Quellcode:
Danke schonmal.procedure InIniSchreiben (Filename, Section, Key, Value: string); var ini: Tinifile; begin ini:= tinifile.Create(Filename); try ini.WriteString(section, key, value); finally ini.Free; end; end; function InIniLesen (Filename, Section, Key: string):string; var ini: Tinifile; begin ini:= tinifile.Create(Filename); try result:= ini.ReadString(section, key, ''); finally ini.Free; end; end; procedure TForm2.Button1Click(Sender: TObject); var filename: string; begin filename:= extractfilepath(application.ExeName)+'Highscore.ini'; InIniSchreiben(Filename, 'Highscore','var1',edit1.Text); InIniSchreiben(Filename, 'Highscore','var2',label3.Caption); if fileexists(filename) then begin form1.label15.Caption:= InIniLesen(Filename,'Highscore','var1'); form1.label17.Caption:= InIniLesen(Filename,'Highscore','var2'); end; end; |
Re: [Snake-Spiel] - brauche eure Hilfe
Zitat:
zu 1. kannst Du gelegentlich eingrenzen, tritt der Fehler bei einer bestimmten Aktion auf? zu 2. "funktioniert nicht immer" ist eine recht bescheidene Fehlerbeschreibung. Was passiert wenn der Highscore nicht richtig funktioniert? Wann funktioniert er nicht richtig? Gibt es einen Zusammenhang zu Punkt 1? Grüße Klaus |
Re: [Snake-Spiel] - brauche eure Hilfe
Zitat:
zu 1. wenn man das Spiel verloren hat und erneut auf Start klickt, um ein neues Spiel zu starten, taucht der Fehler MANCHMAL auf. zu 2. mit "der Highscore funktioniert nicht richtig" mein ich, dass die 2. Form nicht gezeigt wird und auch nichts in die .ini Datei geschreiben wird, wenn ein neuer Highscore aufgestellt wird ^^ aber das ist auch, wie beim 1. Problem nur manchmal der Fall :confused: wenn man die .ini Datei manuell löscht, funktionierts auch wieder, aber nur solange bis man das Programm schließt. mfg |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:07 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