Entwickler-Ecke

Open Source Projekte - Snake


Schalla - Do 19.03.09 20:10
Titel: Snake
Hallo Delphi-Community,

ich weiss, dieses Thema wurde schon häufiger gepostet und angesprochen und ja ich habe die Suchfunktion genutzt.
Trotz dessen wollte ich einfach mal unser Snake-Projekt online stellen und fragen was Ihr davon haltet. Was kann man am Code "an sich" verbessern?
Wie kann man eventuell den Code noch verkürzen?

Kurz zum Programm an sich:
Dieses Snake ist, fast wie jedes andere auch. Eine kleine Schlange ist in einem Raum und kann mit den Pfeiltasten gesteuert werden. Die Schlange muss das Futter essen um größer zu werden und man darf weder sich selbst beißen noch gegen die Wand laufen.
Die Highscores werden auf meinen Server hochgeladen und dort in eine MySQL-Datenbank eingetragen, sodass man jederzeit, von überall den Highscore im Spiel einsehen kann - insofern man mit dem Internet verbunden ist. An Einstellungen kann man nur wenig vornehmen. Der Sound ist an und abschaltbar und die Geschwindigkeit kann man auf 5 Stufen regulieren.

Ich weiss, ich könnte noch sehr viel mehr einbauen... Aber das sind nicht die Antworten/Hinweise die ich haben möchte. Es sind weitere "Maps" geplant, aber mir gehts hier wirklich in erster Linie darum, meinen Programmier-Stil zu verbessern :-)

Achso: Die Kommentare könnt ihr ignorieren ;-) Ich schreib ab und an auch mal nen Code-Fetzen dazu der eigentlich keine wirkliche Beudeutung hat xD

Download der Exe Datei(v. 2.0) [http://rapidshare.com/files/211151737/Snake.exe]
EDIT: Download der Exe Datei(v. 2.3) [http://rapidshare.com/files/211817501/Snake_-_2.3.exe]
EDIT2: Download der Exe Datei(v. 2.5) [http://rapidshare.com/files/226787102/Snake_-_2.5.exe]

Vielen Dank fürs Lesen.

Grüße - Kevin


Delphi-Quelltext
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:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
unit snake;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, startsetting, MMSystem, IdHTTP;

const
  farben: Array [0..2of TColor = (clBlack, clLime, clRed);
  raster: integer = 10;
  breite: integer = 32;
  hoehe: integer = 32;
type
  TForm1 = class(TForm)
  start: TButton;
  hoch: TButton;
  links: TButton;
  rechts: TButton;
  runter: TButton;
  Timer1: TTimer;
  PaintBox1: TPaintBox;
    Panel1: TPanel;
    ptext: TLabel;
    punkte: TLabel;
    Edit1: TEdit;
    sendscore: TButton;
    showscore: TButton;
    settings: TButton;
  procedure startClick(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure hochClick(Sender: TObject);
  procedure linksClick(Sender: TObject);
  procedure rechtsClick(Sender: TObject);
  procedure runterClick(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  procedure settingsClick(Sender: TObject);
  procedure showscoreClick(Sender: TObject);
  procedure sendscoreClick(Sender: TObject);
private
  map: Array [0..32of Array [0..32of Integer;
  kopf,
  richtung,
  futter: TPoint;
  laenge: Integer;
  ende: Boolean;
  procedure game_over;
  procedure new_food;
  procedure draw_map;
  procedure snake;
  procedure PaintFromFile;
public
  function SendPostData(Ahttp: TIdHTTP; const AtoURL: string;
  const aParams: TStrings): string;
end;

var
  Form1: TForm1;
  p:integer;

implementation

uses score;

{$R *.dfm}
{$R source.RES}     //(BRC32 -r datei.rc) zur Erstellung der Resourcen-Datei

//Anfang functions

function ShowMessageNew(const AText, ACaption: stringconst ResID: Integer; Style: Cardinal = MB_OK): Cardinal;
var
  lpMsgBoxParams : MsgBoxParams;
begin
with lpMsgBoxParams do
begin
  cbSize             := SizeOf(lpMsgBoxParams);
  hwndOwner          := Application.Handle;
  hInstance          := SysInit.hInstance;
  lpszText           := PChar(AText);
  lpszCaption        := PChar(ACaption);
  dwStyle            := MB_USERICON or MB_TOPMOST or Style;
  lpszIcon           := MAKEINTRESOURCE(ResID);
  dwContextHelpID    := 0;
  lpfnMsgBoxCallback := nil;
  dwLanguageId       := LANG_ENGLISH;
end;
  Result := Cardinal(MessageBoxIndirect(lpMsgBoxParams));
end;

function TForm1.SendPostData(Ahttp: TIdHTTP; const AtoURL: string;
const aParams: TStrings): string;
  //Ahttp: Die HTTP Komponente von Indy 9.0
  //AtoURL: An diese URL werden die Informationen gesendet
  //Result: HTML-Antwort
Var
  lStream: TMemoryStream; //HTML-Result des PHP-Scripts
  lParams: TStringStream;
  I: Integer;
begin
  Result:='';
if not Assigned(aHttp) then
  exit;
  lStream := TMemoryStream.create;
  lParams := TStringStream.create('');
try
  AHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
for I:=0 to aParams.Count-1 do
  lParams.WriteString(aParams[I] + '&');       //Streamdaten erzeugen
try
  AHTTP.Post(AtoURL, lParams, lStream);        //Stream mit php verknüpfen
except
  MessageBox(Self.Handle, 'Es konnte nicht auf die Online ' +
  'Highscoreliste zugegriffen werden. Bitte stellen sie sicher, ' +
  'das eine Verbindung zum Internet besteht.''Fehler', MB_OK or MB_ICONSTOP);
end;
  SetLength(Result,lStream.Size);
  lStream.Position:=0;
  lStream.ReadBuffer(Result[1],lStream.Size);
finally
  lParams.Free;
  lStream.Free;
end;
end;

//Ende Functions - Anfang procedures

procedure TForm1.FormCreate(Sender: TObject);
begin
  randomize;
  sound := True;
  Form1.Color:=RGB(83,126,7);
  Panel1.Color:=RGB(201,126,7);
  ptext.Color:=RGB(201,126,7);
  punkte.Color:=RGB(201,126,7);
  speed:=100;
  end;

procedure TForm1.draw_map;
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.snake;
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 (kopf.X<0or (kopf.X>breite) or (kopf.Y<0or (kopf.Y>hoehe) then
begin
  game_over;
  ShowMessageNew('Du bist gegen die Wand gestoßen!''Game over!'101);
end;
if (map[kopf.X, kopf.Y]>0and (not ende) then
begin
  game_over;
  ShowMessageNew('Du hast dich selbst gebissen!''Game over!'101);
end;
if (kopf.X=futter.X) and (kopf.Y=futter.Y) then begin
  Inc(laenge);
  new_food;
  p:=p+1;
  punkte.Caption:=inttostr(p);
  ptext.Caption:='   Punkte hast du'+#13+'schon gefressen!';
end;
  map[kopf.X, kopf.Y] := laenge;
end;

procedure TForm1.game_over;
begin
if p>=20 then begin
  sendscore.Enabled := True;
  showscore.Enabled := True;
  Edit1.Enabled := True;
end;
if sound = True then begin
  PlaySound(PChar('down'), hInstance, snd_ASync or snd_Resource);
end;
  //PlaySound(nil, 0, 0);   -> Kein Sound bzw anhalten?!
  ende := True;
  Timer1.Enabled := False;
  start.Enabled := True;
  settings.Enabled := True;
  showscore.Enabled := True;
  PaintFromFile();
end;

procedure TForm1.new_food;
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.Timer1Timer(Sender: TObject);
begin
  snake;
if not ende then
  draw_map;
end;

procedure TForm1.startClick(Sender: TObject);
var
  i, j: Integer;
begin
  timer1.interval := speed;
if sound = True then begin                                                      //Einstellungen und so...

  PlaySound(PChar('tetris'), hInstance, snd_ASync or snd_Resource or SND_Loop);   //Einstellungen und so...
  end;                                                                            //Einstellungen und so...
  //-----------------------
  settings.Enabled := False;
  start.Enabled := False;
  showscore.Enabled := False;
  sendscore.Enabled := False;
  Edit1.Enabled := False;
for i:=0 to breite do
for j:=0 to hoehe do
  map[i, j] := 0;
  kopf := Point(11);
  laenge := 5;
  richtung := Point(01);
  map[kopf.X, kopf.Y] := laenge;
  new_food;
  draw_map;
  ende := False;
  Timer1.Enabled := True;
  p:=0;
  punkte.Caption:=inttostr(p);
  ptext.Caption:='   Punkte hast du'+#13+'schon gefressen!';
end;

procedure TForm1.hochClick(Sender: TObject);
begin
if richtung.Y=0 then
  richtung :=Point(0,-1);
end;

procedure TForm1.linksClick(Sender: TObject);
begin
if richtung.X=0 then
  richtung:=point(-1,0);
end;

procedure TForm1.rechtsClick(Sender: TObject);
begin
if richtung.X=0 then
  richtung:=Point(1,0);
end;

procedure TForm1.runterClick(Sender: TObject);
begin
if richtung.Y=0 then
  richtung:= Point(0,1);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
if (Key = VK_LEFT) then
  links.Click();
if (Key = VK_RIGHT) then
  rechts.Click();
if (Key = VK_UP) then
  hoch.Click();
if (Key = VK_DOWN) then
  runter.Click();
if (Key = VK_DELETE) then
  start.Click();
end;

procedure TForm1.PaintFromFile;
var
  bmp: TBitmap;
begin
  bmp := TBitmap.create;
  bmp.LoadFromResourceName(hinstance, 'picsnake');
  PaintBox1.Canvas.Draw(0,0, bmp);
  bmp.free;
end;

procedure TForm1.settingsClick(Sender: TObject);
begin
  Form2.ShowModal;
end;

procedure TForm1.sendscoreClick(Sender: TObject);
var
  sList: TStringlist;
  Antwort: string;
  MyIdHTTP: TIdHTTP;
begin
  sList:=TStringList.Create;
  MyIdHTTP:= TIdHTTP.Create(nil);
try
  sList.Add('n=' + Edit1.Text);
  sList.Add('p=' + inttostr(p));
  sendscore.Enabled := False;
  Edit1.Enabled := False;
  Antwort:=(SendPostData(MyIdHTTP, 'url',sList));
finally
  sList.Free;
  MyIdHTTP.Free;
end;
if Antwort = '3' then begin
  Form3.Show;
end
else begin
  MessageBox(Self.Handle, PChar('Es ist ein Fehler bei der übertragung ' +
  'der Punkte aufgetreten. Fehler: ' + Antwort), 'Fehler', MB_OK or MB_ICONSTOP);
end;
end;

procedure TForm1.showscoreClick(Sender: TObject);
begin
  Form3.Show;
end;

end.


Delphi-Quelltext
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:
unit startsetting;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm2 = class(TForm)
  Label3: TLabel;
  Label4: TLabel;
  TrackBar1: TTrackBar;
  Button1: TButton;
  Label5: TLabel;
  cbsound: TCheckBox;
  procedure Button1Click(Sender: TObject);
private
  { Private-Deklarationen }
public
  { Public-Deklarationen }
end;

var
  Form2: TForm2;
  speed: integer;
  sound: Boolean;

implementation

uses snake;

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin

if cbsound.State = cbChecked then begin
  sound := True;
end
else begin
  sound := False;
end;

case Trackbar1.Position of
  1 : speed:=100;
  2 : speed:=80;
  3 : speed:=60;
  4 : speed:=40;
  5 : speed:=20;
end;
  Form2.Close;
end;

end.

Delphi-Quelltext
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:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
unit score;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, INIFiles, IdHTTP, StdCtrls, ShellAPI;

type
  TForm3 = class(TForm)
  lb_Info1: TLabel;
  lb_Info10: TLabel;
  lb_Info11: TLabel;
  lb_Info12: TLabel;
  lb_Info13: TLabel;
  lb_Info2: TLabel;
  lb_Info3: TLabel;
  lb_Info4: TLabel;
  lb_Info5: TLabel;
  lb_Info6: TLabel;
  lb_Info7: TLabel;
  lb_Info8: TLabel;
  lb_Info9: TLabel;
  lb_Name1: TLabel;
  lb_Name10: TLabel;
  lb_Name2: TLabel;
  lb_Name3: TLabel;
  lb_Name4: TLabel;
  lb_Name5: TLabel;
  lb_Name6: TLabel;
  lb_Name7: TLabel;
  lb_Name8: TLabel;
  lb_Name9: TLabel;
  lb_Punkte1: TLabel;
  lb_Punkte10: TLabel;
  lb_Punkte2: TLabel;
  lb_Punkte3: TLabel;
  lb_Punkte4: TLabel;
  lb_Punkte5: TLabel;
  lb_Punkte6: TLabel;
  lb_Punkte7: TLabel;
  lb_Punkte8: TLabel;
  lb_Punkte9: TLabel;
  Button1: TButton;
  Button2: TButton;
  procedure FormShow(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  procedure Button2Click(Sender: TObject);
private
  { Private-Deklarationen }
  procedure Top10Eintragen;
public
  { Public-Deklarationen }
end;

var
  Form3: TForm3;

implementation

uses snake;

{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
begin
  Form3.Close;
end;

procedure TForm3.Button2Click(Sender: TObject);
begin
  ShellExecute(Application.Handle, 'open''url'nilnil,SW_ShowNormal);
end;

procedure TForm3.FormShow(Sender: TObject);
begin
  Top10Eintragen;
end;

procedure TForm3.Top10Eintragen;
var
  sList: TStringlist;
  lStream: TFileStream;
  i: Integer;
  ini: TIniFile;
  MyIdHTTP: TIdHTTP;
begin
  // top10.php erstellt eine ini-Datei auf dem Serber mit den Top10. Diese Datei wird geloadet und angezeigt.
  MyIdHTTP:= TIdHTTP.Create(nil);
  sList:=TStringList.Create;
  lStream:=TFileStream.Create
  (ExtractFilePath(ParamStr(0)) + 'highscore.ini', fmCreate or fmShareDenyWrite);
try
  sList.Add('art=top10');
try
  Form1.SendPostData(MyIdHTTP,'url',sList);
  MyIdHTTP.Get('http://url',lStream);
except
  Close;
end;
finally
  lStream.Free;
  sList.Free;
end;
if FileExists(ExtractFilePath(ParamStr(0)) + 'highscore.ini'then begin
  ini:= TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'highscore.ini');
try
for I := 1 to 10 do begin
  TLabel(findcomponent('lb_Name'+inttostr(i))).Caption:= ini.ReadString(
  IntToStr(i), 'name''');
  TLabel(findcomponent('lb_Punkte'+inttostr(i))).Caption:= ini.ReadString(
  IntToStr(i), 'punkte''');
end;
finally
  ini.Free;
end;
end;
end;
end.



Moderiert von user profile iconKha: Topic aus Freeware Projekte verschoben am Sa 21.03.2009 um 14:57


Bergmann89 - Fr 20.03.09 21:14

HI,

gefällt mir, der Sound is das geilste xD
Fehler hab ich auch keine gefunden, gute Arbeit :zustimm:

MfG Bergmann.

p.s.: wie hast du den Direktdownload bei Papidshare hinbekommen?


FinnO - Fr 20.03.09 21:18

Ich krieg beim Zweiten mal immer ne Zugriffsverletzung, wenn das Viech durch einen Punkt läuft.


JayEff - Fr 20.03.09 21:50

user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
Ich krieg beim Zweiten mal immer ne Zugriffsverletzung, wenn das Viech durch einen Punkt läuft.
Den Fehler kann ich nicht reproduzieren. An sonsten, cooles Spiel :zustimm: Du könntest die Melodie noch so abändern, dass sie eine endlose Schleife bildet, sollte ja mit einem einfachen Audioprogramm kein Problem sein, das wär ziemlich cool :)
Pause mit P oder der Pause-Taste wär noch sehr praktisch.


thepaine91 - Fr 20.03.09 23:59

hi

Snake :P Das beste Spiel überhaupt aber hab ich einen Bug wenn ich schnell hintereinander left up / left down / oder mit rechts Drücke sagt er mir selbst gefressen obwohl ich damit nur die Richtung wechseln würde.

mfg


JayEff - Sa 21.03.09 00:10

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
hi

Snake :P Das beste Spiel überhaupt aber hab ich einen Bug wenn ich schnell hintereinander left up / left down / oder mit rechts Drücke sagt er mir selbst gefressen obwohl ich damit nur die Richtung wechseln würde.
stimmt, reproduzierbar. klappte bei mir nicht immer - vermtl muss man das tatsächlich in einem frame machen oder so.
kleiner schönheitsfehler: unter vista mit aero werden scrollbalken angezeigt da die Rahmenbreite wohl anders ist ... irgendso eine API Funktion müsste die Breite zurückgeben können aber das geht sicherlich einfacher - etwas großzügiger mit dem Platz sein :)


Webo - Sa 21.03.09 10:35

Gefällt mir ... die Sounds sind amüsierend ;-)
Klasse find ich die HighscoreTabelle im Internet.
Was du noch ändern könntest (bzw. was ich mir wünschwn würde):
- Die Hintergrundfarbe des Panel rechts auf eine angenehmere, freundliche Farbe ändern


klausiemausie - Sa 21.03.09 12:14

an sich cool gemacht, hab nur ein kleines detail gefunden, was mich stört, nämlich die variable breite des fensters. kam bei mir nämlich vor, dass das fenster zu klein war, und ich dan grünen punkt nicht gesehen habe. ansonsten top. ich hab in info mal snake mit turbopascal programmiert, deswegen interessiert mich das wie du das mit delphi gemacht hast. könntest du evtl mir die projektdateien zukommen lassen?, dass mich mir das mal angucke, wie man sowas mit delphi löst? keine angst, ich will das programm nicht klauen. wäre nett, danke
klaus


Schalla - Sa 21.03.09 16:59

Hallo liebe Delphi-Community,
zu allererst einmal ein großes Dankeschön für eure Antworten :-)
Dachte schon es wäre zu schlecht für euch, da anfangs keine Antworten kamen ^^

Jetzt zum Programm:
mittlerweile hab ich (da ich irgendwie gerade wiedermal nen Programmier-Flash habe) das Programm soweit erweitert, dass man die Außenwände ab/zuschalten kann und separate Highscore-Listen eingebaut. Zusätzlich habe ich die Punkteanzeige angepasst, das heisst die Geschwindigkeitsstufe ist jetzt gleichzeitig ein Multiplikator.

Wens interessiert: Load it :-) [http://rapidshare.com/files/211817501/Snake_-_2.3.exe]

Und nun zu euren Beträgen(für die ich mich nochmals bedanken möchte):

user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
Ich krieg beim Zweiten mal immer ne Zugriffsverletzung, wenn das Viech durch einen Punkt läuft.


Ich weiss, was du meinst. "Zugriffsverletzung bei Adresse 0046FAF2 in Modul'Snake - 2.0.exe'. Lesen von Adresse 00000007." So oder so ähnlich müsste die Violation aussehen. Ich bin leider nur in Sachen Delphi, Java, C++, PHP und den etwas einfacheren Sprachen versiert, dass heisst ich habe absolut keine Ahnung warum diese Violation ab und zu auftaucht. Das größte Problem ist, dass sie urplötzlich auftaucht und nicht reproduzierbar ist >.<

Das Gute: Seit ich von Version 2.0 weggekommen bin und die 2.1, 2.2 und 2.3 gebaut hab, hatte ich nie wieder ne Violation :D

user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
hi

Snake :P Das beste Spiel überhaupt aber hab ich einen Bug wenn ich schnell hintereinander left up / left down / oder mit rechts Drücke sagt er mir selbst gefressen obwohl ich damit nur die Richtung wechseln würde.

mfg


Ist wirklich reproduzierbar und werde versuchen das noch zu beheben, Vielen lieben Dank ;-)


user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:

kleiner schönheitsfehler: unter vista mit aero werden scrollbalken angezeigt da die Rahmenbreite wohl anders ist ... irgendso eine API Funktion müsste die Breite zurückgeben können aber das geht sicherlich einfacher - etwas großzügiger mit dem Platz sein :)


Die Breite wird auf jeden Fall noch angepasst - habs bis jetzt nur unter WinXP getestet ^^ Danke auch dafür.


user profile iconWebo hat folgendes geschrieben Zum zitierten Posting springen:
Gefällt mir ... die Sounds sind amüsierend ;-)
Klasse find ich die HighscoreTabelle im Internet.
Was du noch ändern könntest (bzw. was ich mir wünschwn würde):
- Die Hintergrundfarbe des Panel rechts auf eine angenehmere, freundliche Farbe ändern


Die Farben sind ein wenig verrückt - das muss ich zugeben ;-)
Das liegt unter anderem daran, dass das Info-Projekt eigneltich von 5 Leuden bearbeitet werden sollte. Das tolle daran ist nur: Ich bin der Einzige dessen Hobby es ist, zu programmieren. Draus folgt: Die anderen haben keinen Plan - Damit die aber am Ende auch sagen können, sie hätten was gemacht, hab ich sie die Bilder machen und die Farben bestimmen lassen xD

Wird aber noch geändert - versprech ich Dir =)

user profile iconklausiemausie hat folgendes geschrieben Zum zitierten Posting springen:
an sich cool gemacht, hab nur ein kleines detail gefunden, was mich stört, nämlich die variable breite des fensters. kam bei mir nämlich vor, dass das fenster zu klein war, und ich dan grünen punkt nicht gesehen habe. ansonsten top. ich hab in info mal snake mit turbopascal programmiert, deswegen interessiert mich das wie du das mit delphi gemacht hast. könntest du evtl mir die projektdateien zukommen lassen?, dass mich mir das mal angucke, wie man sowas mit delphi löst? keine angst, ich will das programm nicht klauen. wäre nett, danke
klaus


Wie schon oben gesagt, werde ich die variable breite noch verändern bzw auf "konstant" setzen ;-)
Selbstverständlich lasse ich dir die Daten zukommen ;)
Schreib mir dafür bitte eine PM mit deiner eMail-Addy - das Programm liegt schon gepackt auf gmail (4MB inkl. exe und .RES-Datei).

user profile iconBergmann89 hat folgendes geschrieben Zum zitierten Posting springen:
HI,

gefällt mir, der Sound is das geilste xD
Fehler hab ich auch keine gefunden, gute Arbeit :zustimm:

MfG Bergmann.

p.s.: wie hast du den Direktdownload bei Papidshare hinbekommen?


Hab nen Premium-Account auf Rapidshare. Dort kann man unter Einstellungen "Direkte Downloads, angeforderte Dateien werden ohne Umweg über RapidShare gespeichert" festlegen und den Download als "TrafficShare" laufen lassen. Als TrafficShare-Download ist es FreeUsern möglich das Programm zu loaden ohne den dämlichen Captcha-Code eingeben und 30 Sekunden warten zu müssen =)

user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
[...] An sonsten, cooles Spiel :zustimm: Du könntest die Melodie noch so abändern, dass sie eine endlose Schleife bildet, sollte ja mit einem einfachen Audioprogramm kein Problem sein, das wär ziemlich cool :)
Pause mit P oder der Pause-Taste wär noch sehr praktisch.


Hab beides mal aufgeschrieben - nachdem ich nächste Woche mein Abitur hinter mir hab setz ich mich wieder ran und werds direkt ändern - Danke für den Tipp ;)

Nochmals vielen Dank an alle ;-)

freundliche Grüße

Kevin


Sinspin - Sa 21.03.09 17:55

Hallo, schöne Umsetzung des Spiels.

Aber könntest du bitte den Link zu der aktualisierten Version auch in deinen ersten Post schreiben? Sonst muss man immer den gesammten auf der Suche nach der neusten Version durchlesen :wink:


Webo - So 22.03.09 10:55

user profile iconSchalla hat folgendes geschrieben Zum zitierten Posting springen:
Wird aber noch geändert - versprech ich Dir =)

Das ist super ;-)

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Aber könntest du bitte den Link zu der aktualisierten Version auch in deinen ersten Post schreiben? Sonst muss man immer den gesammten auf der Suche nach der neusten Version durchlesen :wink:

*Zustimm*


2009sharp - So 29.03.09 18:10

tolles Spiel macht spass!
wirklich gut ;)


Sylvus - So 29.03.09 21:03

super Spiel, kannst meinen Highscore auch wieder löschen, aber netter Schutz, dass man nicht mehr spielen kann wenn der focus weg ist ;)
Variable ist aber trotzdem gefunden ;) (474F14)

Sonst schaff ich nur so um die 400 Punkte, find ich aber auch schon ganz gut :D
Weiter so!!!
Viele Grüße Sylvus


Schalla - Do 02.04.09 18:57

user profile iconSylvus hat folgendes geschrieben Zum zitierten Posting springen:
super Spiel, kannst meinen Highscore auch wieder löschen, aber netter Schutz, dass man nicht mehr spielen kann wenn der focus weg ist ;)
Variable ist aber trotzdem gefunden ;) (474F14)
[...]


Hallo Sylvus, ich frage mich wie du das gemacht hast, denn die Server-Daten habe ich ja alle aus dem Quelltext herausgelöscht und man kann doch nicht in einem laufenden Programm einfach eine implenetierte Variable nach Lust und laune verändern, oder?

Wäre Dir dankbar für eine Antwort.

Grüße

Kevin


JayEff - Do 02.04.09 19:06

user profile iconSchalla hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Sylvus, ich frage mich wie du das gemacht hast, denn die Server-Daten habe ich ja alle aus dem Quelltext herausgelöscht und man kann doch nicht in einem laufenden Programm einfach eine implenetierte Variable nach Lust und laune verändern, oder?
Also erstmal: Doch, das geht. Aber viel einfacher geht's doch so: Per Packetsniffer mitsniffen und herausfinden, was genau gesendet wird, dann ein bisschen damit rumprobieren. Im schlimmsten Fall sendest du die Highscore verschlüsselt, big deal, dann kennst du als "Angreifer" trotzdem den plain text (Known-Plaintext attack) und kannst Rückschlüsse auf die Verschlüsselung ziehen.

Wie überträgst du denn die Daten? Per php-skript und post/get? Da sollte es einfach sein, die entsprechende URL mitzusniffen. Und nicht wundern: Da kannst du noch so tolle Verfahren zum Schutz einsetzen, wenn du sowas hier im DF postest, dann ist das Spiel nicht das, was uns am meisten Spaß macht :rofl:

Du könntest, wenn du das besser absichern willst, den Highscore asynkron verschlüsseln (Kanonen auf Spatzen: Suche in Wikipedia RSA ) und zur verifikation einen gesalzenen Hash ausrechnen und mitschicken. Dann Serverseitig prüfen, ob der Hash passt... :mrgreen:


Schalla - Do 02.04.09 19:28

user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
Also erstmal: Doch, das geht.

Wie ?

user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
Aber viel einfacher geht's doch so: Per Packetsniffer mitsniffen und herausfinden, was genau gesendet wird, dann ein bisschen damit rumprobieren. Im schlimmsten Fall sendest du die Highscore verschlüsselt, big deal, dann kennst du als "Angreifer" trotzdem den plain text (Known-Plaintext attack) und kannst Rückschlüsse auf die Verschlüsselung ziehen.


Das ist schon klar, dass man bei der Übertragung da einiges machen kann. Aber das waren nicht meine Fragen.
Ich fragte lediglich wie er es gemacht hat und wunderte mich ob er evtl. Variablen einfach so ändern konnte.

Das Spiel ist bzw. war für mich auch net das, worum es mir bei dem ganzen ging xD
Ich wollte einfach mal bissl was ausprobieren um nen Proggi mit ner mysql-db zusammenzubringen, da ich schon Jahre nichts mehr mit Delphi oder C gemacht hatte :>

Verschlüsselungen will ich sicher nicht einbauen... Wie gesagt das Proggi ist nur ne gute Note in Info ;-)

Grüße - Kevin


JayEff - Do 02.04.09 20:11

user profile iconSchalla hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
Also erstmal: Doch, das geht.

Wie ?
Ich weiß nicht genau, was du mit einer "Implementierten Variable" meinst, aber es gibt diverse Möglichkeiten, ein Programm nach der Kompilierung zu ändern. Zum Beispiel auf assembler ebene. Oder indem man den Speicher des Programms genauer untersucht, ich vermute, das hat Sylvus gemacht.
Wie genau das funktioniert, weiß ich nicht, aber es würde mich auch mal interessieren ... Slyvus ... ? :mrgreen:


FinnO - Do 02.04.09 22:20

macht man das nicht mit... nem Programm á la Memhack?


Sylvus - Fr 03.04.09 00:06

:) jaaa also Memhack kenn ich nicht, und pakete sniffen wäre ja auch mal ne Variante - vll morgen :D
Aber in dem Fall habe ich mir einfach den Speicher angeschaut und die Variable rausgesucht ;)
Das Problem war nur, dass es in deinem Spiel ziemlich viel Variablen gab und wenn man den Fokus weggenommen hat, um z.B. Variablen zu suchen, ging das Spiel nicht mehr weiter zu spielen!
Hab die Variable dann aber doch noch über nen paar Tricks gefunden -

Wer sich allgemein dafür interessiert, also bei laufenden Programmen Variablen zu ändern (Auch sehr sinnvoll bei Testzeiten und Wartezeiten^^) kann mir ja ne PN schreiben oder er lädt sich einfach "T-Search" runter und probiert auf gut Glück was aus!

Die dritte und wahrscheinlich aufwändigste Methode wäre aber man den Code in Assembler zu durchwühlen und dort den Zähler etwas zu verändern :) Leider kenn ich mich in Assembler nur so gut aus, wie mein Vater sich im Internet, also dürfte das noch etwas dauern, aber wir haben ja hier viele Spezialisten :D

Bei Fragen, einfach fragen :)

Viele Grüße Sylvus


//edit
Vielleicht wichtig zu erwähnen: du kannst nur den WERT, einer Variable im Speicher, für eine bestimmte Zeitdauer ändern!
Dazu brauchst du aber die Adresse im Speicher...und die musst du halt finden :)

und ich hab mich mal als 2. eingeordnet, hoffe das ist ok :D


jaenicke - Fr 03.04.09 06:21

Ja, das Spiel ist nett gemacht, nur nicht so richtig für Vista. Einerseits wegen den Scrolleisten, andererseits weil es ins eigene Verzeichnis schreibt. Bei so einem kleinen Spiel ist das aber auch nicht schlimm.

Du solltest einfach etwas mehr Rand lassen, dann ist das auch unter Vista in Ordnung.

Also das gefällt mir ganz gut und es funktioniert auch gut.

Wegen dem Manipulieren von Variablen im Speicher usw.:
Was ihr euch für Mühe macht... Ich habe nur die Exe im Hexeditor angeschaut, das reicht schon. Dazu nen HTML-Editor und schnell ne HTML-Seite mit zwei Formularen fürs Eintragen auf die Seite geschmissen, fertig. Das waren vielleicht 5 Minuten. :mrgreen:

Diese Seite poste ich hier jetzt natürlich nicht, aber ich habe sie dir (@user profile iconSchalla) gerade per PN geschickt. ;-)


Schalla - Fr 03.04.09 10:43

Hehe nice... wieder was gelernt ;)

Also @ user profile iconjaenicke

Sone Seite gibts bereits xD
Ich habe Sie gleichzeitig mit auf den Server geladen um zu testen ob das Eintragen in die MySQL-Db überhaupt funktioniert... Machich bei fast jeder Datenbank die ich erstelle als erstes... wundert euch net^^

Vielmehr fand ich eure anderen Antwort interessant. Mit dem Hexeditor habe ich erst 2-3 mal gearbeitet, dann aber recht schnell die Hoffnung aufgegeben ... zu unübersichtlich ohne "logische" Erklärung. Und diese anderen Methoden á la Memhack oder T-Search find ich sehr nice :>

EDIT: Nein user profile iconSylvus, leider muss ich dich direkt wieder herauslöschen xD
Ich hoffe du strengst dich mal an und versucht nen "echten" 600er Score zu schaffen... is ganz schön schwer ;)
Die Scores, die da drin stehen sind alle "echt"... die Leute wüssten nicht ansatzweise wie man sowas manipuliert, weder mit HTML Script noch mit einem noch komplizierteren Programm.

Vielen Dank für Eure Antworten ;-)

Grüße - Kevin


jaenicke - Fr 03.04.09 14:39

user profile iconSchalla hat folgendes geschrieben Zum zitierten Posting springen:
Mit dem Hexeditor habe ich erst 2-3 mal gearbeitet, dann aber recht schnell die Hoffnung aufgegeben ...
Ok, anders: Nimm Notepad oder einen anderen normalen Editor, öffne damit die Exe und such nach http:// ;-)


Schalla - Fr 03.04.09 14:47

oh lawl.... -.-"

Das is ja wirklich zu einfach O_o

Danke dir, jaenicke ;)

Grüße - Kevin


jaenicke - Fr 03.04.09 15:16

Du kannst zum Beispiel einfach eine einfache Verschlüsselung benutzen. Schon Cäsar oder sowas reicht ja. Das ist zwar leicht knackbar, man muss aber erstmal den richtigen String finden und der sieht ja dann nicht mehr nach einer Internetadresse aus. Nach http oder so suchen geht also nicht mehr.

Natürlich kann man es trotzdem finden oder eben auf anderem Wege manipulieren, aber zumindest ist es nicht mehr ganz so einfach. Eine andere Idee wäre einen Schlüssel vom Server anzufordern, der dann auf bestimmte Weise manipuliert und an das Skript mit übergeben wird. Dieser kann z.B. auf der aktuellen Serverzeit basieren.

All das sind nebenbei auch nette Übungen. :D


Marc. - Fr 10.04.09 21:05

Hey!
Tolles Spiel, gefällt mir.

Ich habe die dritte Variante verwendest, um den Highscore zu manipulieren:
Programm disassembliert, entsprechende Variablen-Adresse herausgesucht ($473F00) und anschließend deren Startwert geändert. Fertig. :)
Gefunden habe ich die Variable allerdings nur über den Text "Du hast schon ... gefressen", wäre der so nicht lesbar gewesen, wäre es um Längen schwerer geworden.
Aber dieses Lücke wurde ja bereits angesprochen.

Grüße


Schalla - Di 28.04.09 18:33

Hallo nochmal liebe Delphi-Community,
ich muss euch hier und jetzt direkt nochmal nerven xD

Und zwar geht es darum, dass ich ein großes Problem festgestellt habe in dem Programm, welches ich tunlichst noch beheben möchte vor der Abgabe.
Ich habe auch schon in sehr vielen Foren und natürlich auch hier die Suchfunktion genutzt, jedoch keine gnaue Antwort auf mein Problem gefunden, da nach meinem Wissenstand alles richtig gemacht ist.

Es geht um folgendes Problem:
Wenn ich die Snake.exe starte, jedoch keine Internetverbindung besteht, und versuche über das Programm mir den Highscore anzeigen zu lassen oder einen Highscore einzutragen, dann spuckt das System einen schwerwiegenden Fehler aus:
Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.

Der Fehler wird in Zeile 21 der folgenden function ermittelt.


Delphi-Quelltext
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:
function TForm1.SendPostData(Ahttp: TIdHTTP; const AtoURL: string;
const aParams: TStrings): string;
  //Ahttp: Die HTTP Komponente von Indy 9.0
  //AtoURL: An diese URL werden die Informationen gesendet
  //Result: Allgemein: Rückgabe/Resultat - Hier: die HTML-Antwort
Var
  lStream: TMemoryStream; //HTML-Result des PHP-Scripts
  lParams: TStringStream;
  I: Integer;
begin
  Result:='';
if not Assigned(aHttp) then
  exit;
  lStream := TMemoryStream.create;
  lParams := TStringStream.create('');
try
  AHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
for I:=0 to aParams.Count-1 do
  lParams.WriteString(aParams[I] + '&');       //Streamdaten erzeugen
try
  AHTTP.Post(AtoURL, lParams, lStream);        //Stream mit php verknüpfen
except
  MessageBox(Self.Handle, 'Es konnte nicht auf die Online ' +
  'Highscoreliste zugegriffen werden. Bitte stellen sie sicher, ' +
  'das eine Verbindung zum Internet besteht.''Fehler', MB_OK or MB_ICONSTOP);
end;
  SetLength(Result,lStream.Size);
  lStream.Position:=0;
  lStream.ReadBuffer(Result[1],lStream.Size);
finally
  lParams.Free;
  lStream.Free;
end;
end;


Nun die Frage: Warum zur Hölle, fängt der den Fehler nicht ab. Ich hab da ja nicht umsonst try/except/finally benutzt. Und soviel wie ich jetzt mitlerweile erfahren habe, ist das genau die richtige Art und Weise einen solchen fehler zu catchen und eine Fehlermeldung entsprechend auszugeben.

Ich hoffe ihr könnt mir weiterhelfen.

Achso: Wer den fehler einmal reproduzieren möchte einfach eine der lten exen nehmen (müsste in jeder so sein) oder HIER [http://rapidshare.com/files/226787102/Snake_-_2.5.exe] die neuste Version herunterladen.

Grüße - Kevin


//EDIT: Habe auch gerade probiert unter uses IdException mit einzubinden und dann mittels "on EIdSocketError do" den Fehler abzufangen -> Ohne erfolg :(
Ich dachte ich wäre stark eingeschränkt mit meinen -16 Diopthrin aber das Programm is ja noch schlimmer wennichs doch sogar vorhersage welcher Fehler kommen wird xD

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Sorry für den Doppelpost - aber ich war so dreist und habe um die Übersicht ein wenig zu behalten kein edit machen wollen.

Problem ist gelöst und weil ich es selbst hasse wenn jemand so nen Problem postet und die Lösung nirgends steht erklär ich meinen Fehler schnell:

Die Exception wurde vom Debugger der IDE (in meinem Fall Delphi 7) gefunden bevor das Programm die Exception überhaupt erst abfangen konnte. Kompiliert als exe datei funktioniert es (fast) einwandfrei.(-> Fehler an anderer Stelle gemacht)

Grüße - Kevin


>M@steR< - Sa 09.05.09 14:01

Gelöscht


Hidden - Sa 09.05.09 15:20

Hi :)

Wie soll das denn funktionieren? :gruebel: Jemand, dem das unbekannt ist, würde dann einfach einen um 34 falschen Score bekommen - was bei 600 Punkten ja nicht so schmerzhaft wäre :?

mfG,


>M@steR< - Sa 09.05.09 15:51

Gelöscht


jakobwenzel - Sa 09.05.09 16:41

Aber man kann immer noch gefakede Scores an den Server senden: Einfach die URL mitschneiden und selber senden :wink:


>M@steR< - Sa 09.05.09 19:12

Gelöscht