Entwickler-Ecke
Delphi Tutorials - DelphiX - Snake Tutor
mimi - Do 17.04.03 23:04
Titel: DelphiX - Snake Tutor
Hallo,
hier mein Snake Tutor.
Bevor du das Tutorial list, musst du unbedingt folgendes
Tutorial [
http://www.delphi-treff.de/content/tutorials/delphixkurs/index.php4?kat=1] 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:
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:
| 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
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:
| 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:
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:
| 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.
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:
| 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.
Lhid - Sa 13.12.03 21:26
Meinung und mich grundlegend geändert-> alte beiträge gelöscht
mimi - Sa 13.12.03 23:27
was für fehler ???
CABALxx - Sa 07.02.04 00:24
Titel: Re: DelphiX - Snake Tutor
cooles tut =) :lol:
mimi - Sa 07.02.04 22:06
danke :)
ich werde evtl, noch eins machen aber mit GLXTreem *G*
Johannes Maier - Mi 14.04.04 13:37
edit: hat sich erledigt!
F34r0fTh3D4rk - So 24.10.04 14:22
bei mir sind da auch so um die 10 - 15 fehler :?
F34r0fTh3D4rk - So 24.10.04 14:25
bitte den ganzen SC, plz 8)
mimi - So 24.10.04 15:32
> bitte den ganzen SC, plz
was meinst du damit ???
F34r0fTh3D4rk - So 24.10.04 17:31
SourceCode
Ich denke, dass viele die gleichen Probleme haben .... :?
mimi - 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
F34r0fTh3D4rk - 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 :evil:
ich finde delphix rockt ! :wink:
mimi - 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*
F34r0fTh3D4rk - 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 :autsch:
mimi - 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*
F34r0fTh3D4rk - 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 :nixweiss:
mimi - 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*
F34r0fTh3D4rk - Mo 01.11.04 18:17
danke, und wenn du es geschrieben hast, kannst du ja einen kleinen sourcecode
hier reinschreiben : :eyecrazy:
mimi - 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
F34r0fTh3D4rk - Mo 01.11.04 19:24
ich hab zeit :)
mimi - Mo 08.11.04 17:57
ich habe mich jetzt für ein Sokubahn tutor entschieden vom primzip das gleiche nur das bei Snake eine Schlange da ist und bei Sokubahn nur ein einfacher spiel stein *G*
wenn du glück hast und ich zeit finde könntes es in ca 2 wochen fertig sein(habe aber noch nicht angefangen)
ich wollte nämlich zuers denn qullcode schreiben und den dann im tutor vorstellen und nicht umekehrt *G* (so habe ich es beim Snake Tutor gemacht *G*)
F34r0fTh3D4rk - Mo 08.11.04 21:45
bei manchen snake varianten kommt man ja auch links ins spiel rein, wenn man rechts
rausgeht.
thepaul - Sa 04.12.04 20:43
wo ist denn das tutorial von delphi-treff? kann er irgendwie nich finden! Hoffentlich heben sie das nich bei der zusammenlegung versehentlich gelöscht!
mimi - So 13.02.05 12:25
habe gestern angefangen ein DelphiX tutor projekt zu schreiben.
Evtl. werde ich es gleich noch weiter schreiben, ber hier mal mein inhaltzverzeichnis
Zitat: |
Inhaltverzeichnis
- Einführung
Was muss/sollte ich wissen bevor ich DelphiX downloade ?
Wo gibt es DelphiX zum Downloaden ?
Wie installiere ich es, richtig ?
- Erstes DelphiX Projekt
DXDraw
DXImageList
DXTimer
- Erstes Beispiel Sokubahn(Zusammenfassung)
Speichern und verwalten von Objekten ?
Verschieben und Drehen von Objekten
löschen von Objekten
der PatternIndex
- Verschiende Techniken
Scrollen
Minikarte
Levelformat
|
leider habe ich keinen WebSever wo ich die Beispiel hochladen kann, deshalb müsst ihr(wenn es dann da ist, und ihr das auch wollt*G*) die beispiel einfach selbst schreiben....
Wenn ihr noch vorschläge habt..... Nehme ich sie gerne mit auf
mimi - So 13.02.05 15:17
Da DelphiX eine sehr bekannte und bliebte Komponenten samlung
für 2D Spiele geworden ist, hier mal mein "Tutorial-Projekt".
Es gibt verschiende Thmen jedes Thema ist in unter thmen unterteilet.
Inhaltverzeichnis
- Einführung
Was muss/sollte ich wissen bevor ich DelphiX downloade ?
Wo gibt es DelphiX zum Downloaden ?
Wie installiere ich es, richtig ?
- Erstes DelphiX Projekt
DXDraw
DXImageList
DXTimer
- Erstes Beispiel Sokubahn(Zusammenfassung)
Speichern und verwalten von Objekten ?
Verschieben von Objekten
der PatternIndex
- Verschiende Techniken
Scrollen
Minikarte
Levelformat
Drehen von Objekten
Einführung
Es wird kein DelphiX wissen vorrausgesetzt, aber Delphi solltes du schon können z.b.
was Schleifen oder IF anweisungen sind ebenfalls sollte bekanntt sein was Array sind
(da ist ein sehr wichtiger bestanteil jeder(Fast) anwendung von delphiX sein wird).
Ich werde nicht jede Komponenten beschreiben, es ist ja klar was die
DXTimer oder die DXImageList machen......
Da DelphiX nicht mehr weiter Entwicklet wird verwende ich unDelphiX
http://turbo.gamedev.net/undelphix.asp
das ist der nach fogler von delphiX das ist gleich für die neusten Delphi versionen ausgelegt.
Das Zip Archiv muss entpacken werden( verzeichnis nach wahl) und dieses verzeichnis muss in
Delphi unter dem Menupunkt: "Tools" und auf der Registerkarte "Bibliothek" bei "Bibliothekpfad"
eingetragen werden damit findet Delphi auch die komponenten
Erstes DelphiX Projekt
Jetzt beginen wir mit dem ersten delphiX Projekt:
Als allererstes werden drei Komponenten von DelphiX auf das Form gepackt:
DXDraw, DXTimer, DXImageList
Jetzt wird die DXImageList mit der DXDraw Komponenten verknüpft und zwar mit der Eigenschaft:
DXImageList1.DXDraw:=DXDraw1(geht auch im OI).
Nun muss der Intervall von der DXTimer Komponenten auf 0 gestellt werden.
In normalen Delphi anwendungen ist ja 1 das schnellste bei DelphiX ist 0 das schnellste(jede ms wird
ein Ereignis ausgelöst: das DXTimer Ereignis).
Damit wir nun auch was auf dem Bildschrim sehen müssen wir auch etwas code schreiben.
Du wälst jetzt die DXTimer komponenten aus und dort fügst du ein ereignis hinzu,
OI:ereignise, onTimer(Letztes ereignis). Anschließend wird der Code Editor geöffnet und folgede zeilen werden geschriben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); begin DXDraw1.Surface.Fill(0); DXImageList1.Items[0].Draw(DXDraw1.Surface,0,0,0); DXDraw1.flip end; |
Damit die DXImageListe auch was zeichnen kann muss sie Bilder haben. Bilder werden so hinzugefügt:
Im OI auf Items klicken auf das Dialog was kommt auf das + Symbol klicken und ein Bild duswählen.
Zur Parameter erlärung von der DXImageList:
Items[index].Draw(Dest: TDirectDrawSurface; X, Y,PatternIndex: Integer)
Es gibt auch nach indexOf bei Items dort kannst du einen Namen eingeben das hat den vorteil,
wenn sich die liste verändern musst du nicht alles nach bessern.
Dest: damit DelphiX weißt auf welchen Surface gezeichnet werden soll
X,Y: Die position auf der DXDraw Komponente es geht Oben Linx los
PatternIndex: du verwendes eine Grafik mit mehren gleichgroßen Bildern auch Tiles gennant.
Das geht aber nur wenn du vohrer in der DXImageList unter items die PatternWith und PatternHeight
mit werden fütterst.
Damit die ImageList auch mit jpeg arbeiten kann(wie im beispiel) muss der uses die unit Jpeg hinzugefügt werden.
Zur der Flip Funktion: es wird ein Bild in einen Backpuffer geschriben und mit der Flip Funktion auf
den Fornbuffer gezeichnet(jetzt sehen wir das Bild) so wird der Flimmer effegt vermiden der da ist
wenn nicht DoubleBuffered auf True steht.
So damit währe die erste DelphiX Anwendung zu ende jetzt solltes du ein bild sehen.
Erstes Beispiel Sokubahn(Zusammenfassung)
So damit wir das Spiel Sokubahn auch Schreiben können müssen wir und darüber gedanken machen
wie wir die Objekte auf der Karte verwalten die beste und einfachste möglichkeit ist ein 2D Array
da Sokubahn ja nur gleichgroße Objkekte verwendet.
Jetzt muss eine großer der Tiles und der Karter ausgewählt werden.
Ich nehme mal 640 X 480 Pixl(Standart größe vom kleinen Spielen).
Damit wir ein Raster enhalten sollten wir ein gerade Zahl nehmen z.b. 20:
640 div 20 = 32-1(weil die Array fangen ja bei 0 an)
480 div 20 = 24-1
Dies ergbnis Speichern wir in den Konstanten Variablen
MapX = 31
MapY = 23
MapS = 20 // Raster größe
So jetzt fängt das eigentliche Spiele Programieren an. Es geht damit los die Grafiken zusammen zustellen
die man benötigt und wie sollen sie verwaltet werden ?
Ich mache das einfach so:
bei meinen Projekten gibt es im verzeichnis: Image eine datei namens image.txt
dort stehen alle Image drinen die gebraucht weren die Datei ist so aufgebaut:
background.bmp; Verzeichnis namen(muss sich im gleichen verzeichnis befinden wie die datei)
0,0; Die Pattern Größe
B; Der Alias(jedes Item kann ein Namen haben)
clNone Trantzparent Farbe
das ganze sieht jetzt so aus
background.bmp;0,0;B;clNone
Ich habe ein kleines tools geschrieben was diese Dateien erstellen kann.
Jetzt muss dieses Datei geladen werden: DelphiX hat zwar sein eigens Grafik archiv format
nur da ist der Nachteil das dies Dateien immer neu erstellt werden müssen sobalt sich eine Datei ändern
das ist in meinem Format nicht der fall nur du musst es selbst laden d.h. die funktion dafür schreiben.
Wir werden eine Unit erstellen um nützliche funktionen abzuspeichern die nennen wir dann: DX_Tools
So könnte die Funktion aussehem zum laded der Grafiken aussehen damit diese unit auch funktioniert musst du noch folgende
funktion als erstes hinzufügen(die werde ich nicht beschreiben, da sie nichts mit delphiX zu tuen hat).
Ich hoffe du weißst wie man Units erstellt und Funktionen hinzufügt, weil dies werde ich nicht erklären.
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:
| function GetToken(aString: String; SepChar: Char; TokenNum: Byte):String; var Token : String; StrLen : Byte; TNum : Byte; TEnd : Byte;
begin StrLen := Length(aString); TNum := 1; TEnd := StrLen; while ((TNum <= TokenNum) and (TEnd <> 0)) do begin TEnd := Pos(SepChar,aString); if TEnd <> 0 then begin Token := Copy(aString,1,TEnd-1); Delete(aString,1,TEnd); Inc(TNum); end else Token := aString; end;
if TNum >= TokenNum then Result := Token else begin Result := Format('Fehler: Tokennummer (%s) ist größer als token !',[aString]); MessageBox(0,pchar(Result),nil,MB_OK or MB_ICONEXCLAMATION); end; end;
procedure LoadImageToListe(FileName:TFileName; DXImageList:TDXImageList); var i:integer; bilder:TStringList; str:String; begin bilder:=TStringList.create; bilder.LoadFromFile(FileName);
for i:=0 to bilder.count-1 do begin DXImageList.Items.Add; with DXImageList.Items[i] do begin Picture.LoadFromFile(ImageDir + GetToken(Bilder.Strings[i],';',1)); str:=GetToken(bilder.strings[i],';',2);
PatternHeight:=StrToInt(GetToken( str,',',1));; PatternWidth:=StrToInt(GetToken( str,',',2));;
Name:=GetToken(bilder.Strings[i],';',3); Transparent:=True; TransparentColor:=StringToColor(GetToken(bilder.Strings[i],';',4) );
end; end; end; |
Die Funktion sollte verstäntlich sein. Die Kommt nun in die DX_Tools.pas rein. So jetzt geht es weiter, erstelle
ein Verzeichnis Image da drint erstellt du die Dateien
Delphi-Quelltext
1: 2: 3: 4:
| steine.bmp(40 X 20 also zwei Bilder) ziele.bmp(20 X 20 also zwei Bilder) kasten.bmp(20 X 20 also zwei Bilder) ziele.bmp(20 X 20 also zwei Bilder) |
und jetzt erstellt du eine Datei names image.txt und schreibst dort folgendes rein:
Delphi-Quelltext
1: 2: 3: 4:
| steine.bmp;20,20;S;clNone player.bmp;20,20;p;clNone kasten.bmp;20,20;k;clNone ziele.bmp;20,20;z;clNone |
damit wir auch was sehen werden wir das erste Projekt neu abspeichern und zwar unter Kap2. Wir löschen das
Image aus der DXimageList(Items\ - Symbole und auf OK) und fügen beim erstellen das Formlaures die funktion
LoadImageToList, die sieht dann so aus:
Delphi-Quelltext
1: 2: 3: 4:
| procedure TForm1.FormCreate(Sender: TObject); begin LoadImageToListe(GetExeDir + '\Image\image.txt',GetExeDir + '\Image\',DXImageList1); end; |
Complier jetzt mal dein Projekt und Starte es wenn alles gut geht dürftes du jetzt nichts sehen
Jetzt kommt der eignentliche teiel, das Zeichnen von mehren grafiken:
Du füghst ein 2D Array hinzu bei den goblaen variabeln
Map:array[0..MapX,0..MapY] of Integer;
zur bessern übersicht erstellen wir unter const(muss noch hinzugefügt werden über den Typs) die variabeln:
// Wenn die index stimmem kannst du sie so übernehmen ansonst musst du sie anpassen
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| const MapX = 31; MapY = 23; MapS = 20; None = -1; Stein = 0; Kasten = 2; Ziel = 3;
Lings = -1; Rechts = +1; Oben = -1; Unten = +1; |
jetzt fügst du folgende sachen unter private der Forms class hinzu:
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:
| Map:array[0..MapX, 0..MapY] of TMap;
Player:TPlayer;
c:string;
procedure ClearMap;
procedure CreateMap;
procedure AddMapRand;
procedure MovePlayer(x,y:Integer);
procedure CreateObj(x,y,typ,tex:Integer); |
und so sehen die "sachen" mit leben gefühlt aus
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:
| procedure TForm1.CreateObj(x,y,typ,tex:Integer); begin Map[x,y].Typ1:=Typ; Map[x,y].Tex1:=Tex; if typ = Stein then Map[x,y].frei:=False; end;
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer); var x,y:Integer; begin DXDraw1.Surface.Fill(0); for x:=0 to MapX do begin for y:=0 to MapY do begin if Map[x,y].Typ1 <> None then DXImageList1.Items[Map[x,y].typ1].Draw(DXDraw1.Surface,x*MapS,y*MapS,Map[x,y].tex1); end; end;
DXImageList1.Items[1].Draw(DXDraw1.Surface,player.x*MapS,player.y*MapS,player.Tex);
DXDraw1.flip end; procedure TForm1.MovePlayer(x,y:Integer); var px,py:Integer; begin px:=player.x+x; py:=player.y+y; if Map[px,py].frei = True then begin if Map[px,py].typ1 = Kasten then begin if Map[px+x,py+y].frei = True then begin Map[px+x,py+y].Typ2:=Map[px+x,py+y].Typ1; Map[px+x,py+y].Tex2:=Map[px+x,py+y].Tex1;
Map[px+x,py+y].Typ1:=Map[px,py].Typ1; Map[px+x,py+y].Tex1:=Map[px,py].Tex1;
if Map[px,py].Typ2 = Ziel then begin Map[px,py].Typ1:=Map[px,py].Typ2; Map[px,py].Tex1:=Map[px,py].Tex2; end else begin Map[px,py].Typ1:=None; Map[px,py].Tex1:=0; end;
Map[px,py].frei:=True; Player.x:=px; Player.y:=py;
end; end else begin Player.x:=px; Player.y:=py; end; end; Form1.Caption:=c +' ' + IntToStr(px) + '\' + IntToStr(py);
end;
procedure TForm1.AddMapRand; var x,y:Integer; begin Randomize; for x:=0 to MapX do CreateObj(x,0,stein,0);
for x:=0 to MapX do CreateObj(x,MapY,stein,0);
for y:=0 to Mapy do CreateObj(0,y,stein,0);
for y:=0 to MapY do CreateObj(Mapx,y,stein,0); end;
procedure TForm1.CreateMap; var x,y:Integer; begin AddMapRand; for x:=5 to 20 do CreateObj(x,5,stein,1); for x:=5 to 20 do CreateObj(x,20,stein,1);
for y:=5 to 20 do CreateObj(20,y,stein,1);
CreateObj(10,11,Kasten,0); CreateObj(11,11,Kasten,0); CreateObj(10,12,Kasten,0);
CreateObj(28,5,Ziel,0); CreateObj(27,20,Ziel,0); CreateObj(22,12,Ziel,0);
Player.x:=2; Player.y:=12; Player.Tex:=0; end;
procedure TForm1.ClearMap; var x,y:Integer; begin for x:=0 to MapX do begin for y:=0 to MapY do begin map[x,y].Typ1:=None; map[x,y].Typ2:=None; map[x,y].Tex1:=None; map[x,y].Tex2:=None; map[x,y].Frei:=True; end; end; end;
procedure TForm1.FormCreate(Sender: TObject); begin c:='Erste DelphiX anwendung'; LoadImageToListe(GetExeDir + 'Image\image.txt',GetExeDir + '\Image\',DXImageList1); ClearMap; CreateMap; end; |
Wenn du alles richtig gemacht hast soltles du eine Karte sehen mit einem Rand und einem C in etwa sollte es so aussehen
(habe wie gesagt leider keinen Server so muss ich es halt mit assci zeichen da stellen)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| ------------------ - z - - ------ - - .. - z - - . - - - ------ z - ------------------ |
Ich hoffe das wahr verständlich.
Vorschläge, Verbesserungs wünsche und sowas in der art sind erwünscht(bitte nicht über die rechtschreibung reden nur einfach
wenn nötig fehler melden dann kann ich sie beheben)
dieses Totur habe ich in zwei Tagen erstellt wobei ich heute den meisten Teil geschrieben habe ich hoffe es hilft jemmanden weiter
mimi - So 13.02.05 15:18
der letzte Teil kommt später(wenn ich wieder lust dazu habe *G*)
Chris Maslowski - Di 22.02.05 13:56
könntest du mir viellecht mal den ganzen quelltext per e-mail schicken?(chris.maslowski@freenet.de) Das wäre sehr nett. Schon mal danke im voraus
mimi - Di 22.02.05 18:19
kann ich leider erst am wochenende weil ich kein webserver habe sonst könnte ich ihn eifach hochladen *G*
F34r0fTh3D4rk - Mo 28.02.05 17:48
kann jemand mal das tutorial non-dx machen ? EDIT: Bin gerade dabei
noch nefrage: woher krieg ich delphiX für delphi6 ?
mimi - Sa 05.03.05 15:58
das unDelphiX ist dafür auch geiengent, es unterstützt meines wissen 5-7 ....
non-dx ?
ohne delphiX ? ist auch nicht weiter schwirig... so habe ich angefangen bei der spiele entwicklung bei delphi.
Mal sehen ob ich dafür auch ein tutor schreibe
F34r0fTh3D4rk - Sa 05.03.05 15:59
der code ist schon fertig (hier im forum)
mimi - Sa 05.03.05 16:09
und wo ?
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!