Autor |
Beitrag |
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Do 17.04.03 23:04
Hallo,
hier mein Snake Tutor.
Bevor du das Tutorial list, musst du unbedingt folgendes Tutorial lesen. Hier kann man die Grundlagen von DelphiX kennen lernen
Also fangen wir an:
Als erstes startest du Delphi und machst ein Neues Projekt auf.
Dann gehst du zur DelphiX-Seite bei den Komponenten und nimmst: TDXdraw, TDXImageListe, DXTimer.
So jetzt bereiten wir die DXImageList vor: du klickst auf Items und fügst 4 Items hinzu, 1 = Body, 2 = Head, 3 = Wand und 4 = Futter und lädst die einzelnen Bilder rein. Nun legen wir eine Struktur (oder wie die Dinger heißen) an:
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:
| const MapX = 39; MapY = 23; None = -1; Wand = 3;
links = 0; rechts = 1; oben = 2; unten = 3;
type MSnkae = record X,Y,richtung,tick:Integer; E:array of TPoint; KeyDown:Bool end;
SFutter = record x,y,punkte,tex:Integer; end;
MGkarte = record Typ,Tex:Integer; Visible:Bool; end;
MGame = record karte: array[0..MapX,0..MapY] of MGkarte; Snake:MSnkae; futter:array of SFutter; FutterIndex:Integer; end; |
Ich habe die Struktur in einer extra unit gespeichert (wegen des Level Editors, den ich gerade schreibe).
a:
MapX und MapY sind die Kartengrößen. Sie geben an: wie groß die einzelnen Felder sind; wir verwenden hier ein Raster. Jeder Kasten ist 16x16 Pixel groß. Wir haben in diesem Fall: Breite 640 und Höhe 480. Jetzt müssen wir einfach 640 durch die Breite der Kästchen teilen also z.b. so:
640 / 16 = 40 -1 da wir von 0 ausgehen und nicht von 1 muss das -1 genommen werden.
Bei der Höhe ist das das Gleiche. 480 / 16 = 30 - 1 Aber hier ist etwas anders. Im Quellcode steht 23 und nicht 30 drin. Das ist aber schnell erklärt: da wir nicht alles für das Spielfeld haben wollen, sondern noch ein Display einblenden wollen, müssen wir 112 von den 480 abziehen; und so kommen wir auf 23 in Y-Richtung.
b:
None sind leere Felder. Wand ist der Index in der DXImageList. Also hier 3.
c:
Sind die Richtungsangaben.
1:
Für die Schlange: x und y die Position, tick ist das Zeitinterval, in der DXTimer* die Funktion MoveSnake(die wir noch schreiben werden) aufrufen soll. Wenn wir das nicht machen, ist die Schlange in 1 Sekunde in der Wand. e ist der "body array", also die Elemente der Schlange. Kurz: der Schwanz. KeyDown wird in Move_Snake genommen(darauf gehe ich später noch ein)
2:
x und y die Futter-Position, Punkte ist klar, tex ist der pattern Index.
3:
Die Karte: in Typ wird der Feld-Typ gespeichert, also ob es nun eine Wand ist. Visible gibt an, ob der Typ angezeigt werden soll.
4:
Der Hauptrecord: in Karte werden die Objekte drinnen gespeichert (wirst du später noch sehen) Snake enthält alle variablen, die für die Schlange gebraucht werden. Futter für das Futter In FutterIndex wird das aktuelle Futter gespeichert, also die Position, welches Futter er von dem FutterIndex anzeigen soll.
Das sind die Vorbereitungen. Sobald du damit fertig bist, kannst du weiterlesen:
So als erstes schreiben wir die Procedure, die die Schlange zum Bewegen bringt
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 SnakeMove; var i:integer; check_c:Bool; begin check_c:=False; with Game.Snake do begin if (X-1 < 0) and (game.Snake.richtung = Links) then check_c:=True; if (Y-1 < 0) and (game.Snake.richtung = Unten) then check_c:=True; if (X+1 > MapX) and (game.Snake.richtung = rechts) then check_c:=True; if (Y+1 > MapY) and (game.Snake.richtung = Oben) then check_c:=True; end;
if (Game.karte[Game.Snake.X+1,Game.Snake.y].typ <> None) and (game.Snake.richtung = rechts) then check_c:=True; if (Game.karte[Game.Snake.X-1,Game.Snake.y].typ <> None) and (game.Snake.richtung = Links) then check_c:=True;
if (Game.karte[Game.Snake.X,Game.Snake.y+1].typ <> None) and (game.Snake.richtung = Oben)then check_c:=True; if (Game.karte[Game.Snake.X,Game.Snake.y-1].typ <> None) and (game.Snake.richtung = Unten) then check_c:=True; if Check_c = False then begin if (Game.futter[Game.FutterIndex].x = Game.Snake.x) and (Game.futter[Game.FutterIndex].y = Game.Snake.y) then begin inc(Game.FutterIndex); SetLength(Game.Snake.e,high(Game.Snake.e)+2); Game.Snake.e[high(Game.Snake.e)]:=Game.Snake.e[high(Game.Snake.e)-1]; end; case Game.Snake.richtung of Rechts: inc(Game.Snake.X); Links: dec(Game.Snake.X); Oben: inc(Game.Snake.Y); Unten: dec(Game.Snake.Y); end; for i:=high(Game.Snake.e) downto 1 do Game.Snake.E[i]:=Game.Snake.E[i-1];
Game.Snake.E[0].x:=Game.Snake.X; Game.Snake.E[0].y:=Game.Snake.Y; end; end; |
Ich denke, die procedure sollte klar sein, oder ?
Weiter geht es: das Wichtigste überhaupt, das Anzeigen der Bilder auf der DXDraw-Komponente:
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:
| procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); var i,m,px,py:Integer; begin DXDraw1.Surface.Fill(0);
for px:=0 to MapX do begin for py:=0 to MapY do begin if (Game.karte[px,py].typ <> None) and (Game.karte[px,py].tex <> None) and (Game.karte[px,py].Visible = True) then DXImageList1.Items[Game.karte[px,py].typ].Draw(DXDraw1.surface,px*16,py*16,Game.karte[px,py].tex); end; end;
inc(Game.Snake.tick); if Game.Snake.KeyDown = True then m:=4 else m:=10; if Game.Snake.tick >= m then begin Game.Snake.tick:=0; SnakeMove; end;
for i:=1 to HIGH(Game.Snake.e) do DXImageList1.Items[1].Draw(DXDraw1.surface,Game.Snake.e[i].x*16,Game.Snake.e[i].y*16,0);
DXImageList1.Items[0].Draw(DXDraw1.surface,Game.Snake.x*16,Game.Snake.y*16,0);
if Game.FutterIndex <> -1 then begin with Game.futter[Game.FutterIndex] do begin if Tex <> -1 then DXImageList1.Items[2].Draw(DXDraw1.surface,x*16,y*16,tex); end; end; DXDraw1.Flip; end; |
Noch Fragen zum Zeichnen ? Nein? Gut;)
Weiter: jetzt wird alles initialisiert.
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:
| procedure TForm1.FormCreate(Sender: TObject); var i,px,py:Integer; begin SetLength(Game.futter,5); SetLength(Game.snake.e,5);
for px:=0 to MapX do begin for py:=0 to MapY do begin Game.karte[px,py].typ:=None; Game.karte[px,py].Tex:=None; Game.karte[px,py].Visible:=False; end; end; for i:=0 to 4 do begin with Game.Futter[i] do begin x:=-1; y:=-1; punkte:=-1; tex:=-1; end; end; Game.Snake.X:=10; Game.Snake.y:=10; Game.Snake.e[0].x:=Game.Snake.X; Game.Snake.e[0].y:=Game.Snake.y; Game.Snake.e[1].x:=11; Game.Snake.e[1].y:=10; Game.Snake.e[2].x:=12; Game.Snake.e[2].y:=10; Game.Snake.e[3].x:=13; Game.Snake.e[3].y:=10; Game.Snake.e[4].x:=14; Game.Snake.e[4].y:=10; Game.Snake.tick:=0; Game.Snake.KeyDown:=False;
Randomize; for i:=0 to 4 do begin with Game.Futter[i] do begin x:=random(MapX); y:=random(MapY); tex:=random(2); end; end; game.FutterIndex:=0;
for px:=0 to MapX do begin Game.karte[px,0].typ:=Wand; Game.karte[px,0].Tex:=0; Game.karte[px,0].Visible:=True; end;
for px:=0 to MapX do begin Game.karte[px,MapY].typ:=Wand; Game.karte[px,MapY].Tex:=2; Game.karte[px,MapY].Visible:=True; end;
for py:=0 to MapY do begin Game.karte[0,py].typ:=Wand; Game.karte[0,py].Tex:=0; Game.karte[0,py].Visible:=True; end;
for py:=0 to MapY do begin Game.karte[MapX,py].typ:=Wand; Game.karte[MapX,py].Tex:=2; Game.karte[MapX,py].Visible:=True; end;
end; |
* Nil kann man hier nicht sagen, sondern hier wird alles auf -1 gesetzt, aber zum klaren Verständnis verwende ich nil. Ich hoffe, die "lange" procedure ist dir auch klar.....
Die Schlange bewegt sich schneller wenn eine Taste gedrückt wurde. Nun kommen wir zu der Steuerung der Schlange:
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:
| procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if key = VK_LEFT then begin Game.Snake.KeyDown:=True; Game.Snake.richtung:=Links; end;
if key = VK_RIGHT then begin Game.Snake.KeyDown:=True; Game.Snake.richtung:=Rechts; end;
if key = VK_DOWN then begin Game.Snake.KeyDown:=True; Game.Snake.richtung:=Oben; end;
if key = VK_UP then begin Game.Snake.KeyDown:=True; Game.Snake.richtung:=Unten; end; end; |
Wenn die Taste losgelassen wurde, Schlange auf normale Geschwindigkeit einstellen.
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin Game.Snake.KeyDown:=False; end; |
So. Das wäre es gewesen. Ich hoffe, ich konnte euch helfen
Moderiert von Klabautermann: Code durch Delphi-Tags ersetzt.
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Lhid
Beiträge: 831
|
Verfasst: Sa 13.12.03 21:26
Meinung und mich grundlegend geändert-> alte beiträge gelöscht
Zuletzt bearbeitet von Lhid am Sa 26.09.09 14:36, insgesamt 1-mal bearbeitet
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 13.12.03 23:27
was für fehler ???
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
CABALxx
Beiträge: 174
D7 Ent
|
Verfasst: Sa 07.02.04 00:24
cooles tut =)
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 07.02.04 22:06
danke
ich werde evtl, noch eins machen aber mit GLXTreem *G*
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Johannes Maier
Beiträge: 173
Win XP
D7 Prof
|
Verfasst: Mi 14.04.04 13:37
edit: hat sich erledigt!
_________________ MfG
Johannes ehem. jbmaier
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 24.10.04 14:22
bei mir sind da auch so um die 10 - 15 fehler
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 24.10.04 14:25
bitte den ganzen SC, plz
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 24.10.04 15:32
> bitte den ganzen SC, plz
was meinst du damit ???
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 24.10.04 17:31
Source Code
Ich denke, dass viele die gleichen Probleme haben ....
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 24.10.04 19:02
den habe ich leider nicht mehr bzw. ich müsste erst auf meine sicherungen schauen. aber was für ein problem habt ihr???
evtl. schreibe ich ein neues(hätte nicht gedacht das delphiX so viel genutzt wird)
ich möchte ja immer noch(mal sehen wann ich dazu komme)
so eine art delphiX Lexikon schreiben da sollen Tutor rein, tipps erfahrungen und sowas
z.b. auch geschiechte und sowas halt, alles was mit DelphiX zu tuen hat
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 25.10.04 15:14
die solln mal den delphix sourcecode rausgeben, damit schlaue leute
den verbessern könn, dieses generve von wegen delphix ist *mist*e geht mir
verdammt auf den sack
ich finde delphix rockt !
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 30.10.04 10:58
delphIX ist openSource und jede kann die Qullcode verändern.
was gefält dir dann an delphiX nicht ?
ich nutze es bestimmt schon seit 2 Jahren wenn nicht mehr *G*
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Sa 30.10.04 12:06
im forum nerven mich alle, dass delphiX fürn *popo* ist,
weil es nicht open source ist und ruckelt wie sau ...
Dabei weiß ich auch das delphi open source ist aber
Sowas macht einen bekloppt im kopf
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 30.10.04 12:52
also ich finde delphiX auch supper gerade für 2D spiele.
ich habe mir eine kleine klasse geschrieben die den zugrief auf delphiX vereinfacht.
naja wie dem auch sei *G*
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Sa 30.10.04 20:35
ich habe auch nichts gegen delphiX, nur wenn man hier im Forum jemadem eine
Frage stellt, dann fragt der benutzt du DelphiX. Antwort: ja !
Dann kommt gleich: Kannste vergessen, mach es lieber ohne DelphiX,
DelphiX ist unzuverlässig, langsam....
Aber ich komm mit Snake auch net weiter, wie gesagt, ich habe um die 10-15 Fehler
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 30.10.04 22:43
was für fehler ?
im grunde ist Snake mit DelphiX sehr einfach, ich überleg mir gerade ob ich nicht ein neues Snake erstellen soll problem ist nur: ich habe leide kein WebSpace mehr und könnte es dann nicht hochladen. ich müste es also bei delphipraxis hochladen.
du musst bei snake im grunde nur folgendes machen(das ist der wichtiges teiel)
du hast ein raster jedes feld hat die gleiche größe(16X16)(die schlange auch) es gibst 2 array ein für die map(map:array[0..40,0..39] of TMap). jetzt kannst du ihn per zufall füllen lassen und bei der schlange gehst jetzt weiter:
Snake:array of TPoint;
jetzt erhöst du immer wenn du zusammen gestoßen bis:
if map[Snake[0].x,Snake[0].y].type = Freesen then
.....
und jetzt musst du einfach denn array um eins erhöhen.
das problem ist nur bei der bewegung du muss alle elemente vom array um einen bestimmten wert veränden z.b. so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| const lings = -1 rechts = +1 oben = -1; unten = +1
richtung:=Lings;
procedure move; var i:Integer; begin for i:=0 to high(Snake) do begin if (richtung = lings) or (richtung = rechts) then Snake[i].x:=Snake[i].x+richtung;
if (richtung = oben) or (richtung = unten) then Snake[i].y:=Snake[i}.y+richtung end; end; |
das müsste normaler weise gehen(ich habst nicht getestet) wenn es nicht geht werde ich morgen ein kleiens Snake schreiben
ich hoffe du kannst damit was anfangen *G*
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 01.11.04 18:17
danke, und wenn du es geschrieben hast, kannst du ja einen kleinen sourcecode
hier reinschreiben :
|
|
mimi
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Mo 01.11.04 18:48
ich weiß aber noch nicht genau wann ich damit anfangen.
ich wollte ersteinmal ein kleines snake Game schreiben. und daraus dann ein tutor entwickeln, dann kann sich aber hinziehen
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Mo 01.11.04 19:24
ich hab zeit
|
|
|