Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mo Jul 14, 2025 23:45

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Nur erstes Tile wird gezeichnet
BeitragVerfasst: So Mär 30, 2008 18:46 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Hi,

ich erstelle mir eine simple 2D-Karte. Alle Tiles sind 32x32 Pixel groß. Die Informationen werden in folgender Form gespeichert:
Code:
  1.  
  2. X:Y=Textur
  3.  

Beispieldatei:
Code:
  1.  
  2. 0:0=img\tile1.jpg
  3. 32:32=img\tile2.jpg
  4. 64:64=img\tile3.jpg
  5.  

Also gehe ich die Datei durch und lese X, Y und die Textur aus. Dabei werden die drei Arrays MapX (X-Wert), MapY (Y-Wert) und MapTex (Textur) befüllt. Sie haben grundsätzlich alle drei die gleiche Länge. Am Ende wird noch die Kartengröße berechnet und in MapWidth und MapHeight gespeichert.
Code:
  1.  
  2.   private
  3.     MapX, MapY : Array of Integer;
  4.     MapTex     : Array of gluInt;
  5.   public
  6.     MapWidth  : Integer;
  7.     MapHeight : Integer;
  8.  
  9. var i, pSep1, pSep2 : Integer;
  10.     sl              : TStrings;    
  11. begin
  12.   sl := TStringList.Create;
  13.   with sl do
  14.   begin
  15.     LoadFromFile(f);
  16.     for i := 0 to sl.Count-1 do
  17.     begin
  18.       pSep1 := Pos(':', sl[i]);
  19.       pSep2 := Pos('=', sl[i]);
  20.       SetLength(MapX, Length(MapX)+1);
  21.       MapX[High(MapX)] := StrToInt(Copy(sl[i], 1, pSep1-1));
  22.       SetLength(MapY, Length(MapY)+1);
  23.       MapY[High(MapY)] := StrToInt(Copy(sl[i], pSep1+1, pSep2-(pSep1+1)));
  24.       SetLength(MapTex, Length(MapTex)+1);
  25.       LoadTexture(Copy(sl[i], pSep2+1, Length(sl[i])), MapTex[High(MapTex)], False);
  26.     end;
  27.     Free;
  28.   end;
  29.   MapWidth  := High(MapX)*32;
  30.   MapHeight := High(MapY)*32;
  31.  

Dass alle Arrays die gleiche Länge haben erleichtert das Zeichnen extrem, ich kann einfach ein Array nehmen und von diesem auf die anderen schließen. Ich sehe keinen Grund dafür: Wieso wird nur der erste Eintrag der Datei und somit der Arrays gezeichnet ? Seht ihr einen Grund dafür ?
Code:
  1.  
  2. procedure DrawQuad(pX, pY, pZ, pWidth, pHeight : Single);
  3. begin
  4.   glBegin(GL_QUADS);
  5.     glTexCoord2f(0, 0);
  6.     glVertex3f(pX, pY, -pZ);
  7.     glTexCoord2f(1, 0);
  8.     glVertex3f(pX + pWidth, pY, -pZ);
  9.     glTexCoord2f(1, 1);
  10.     glVertex3f(pX + pWidth, pY + pHeight, -pZ);
  11.     glTexCoord2f(0, 1);
  12.     glVertex3f(pX, pY + pHeight, -pZ);
  13.   glEnd;
  14. end;
  15.  
  16. var i : Integer;
  17. begin
  18.   for i := 0 to High(MapX) do
  19.   begin
  20.     glBindTexture(GL_TEXTURE_2D, MapTex[i]);
  21.     if (MapPos.X + MapX[i]*32 >= -16*MapScale) and (MapPos.X + MapX[i]*32 <= MapWidth /MapScale+16) and
  22.        (MapPos.Y + MapY[i]*32 >= -16*MapScale) and (MapPos.Y + MapY[i]*32 <= MapHeight/MapScale+16) then
  23.       DrawQuad(MapX[i], MapY[i], 0, 32, 32);
  24.   end;
  25. end;
  26.  


Mal abgesehen davon: Ist das nicht ziemlich performancelastig ?

_________________
Meine Musik: spiker-music.net


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 30, 2008 20:00 
Offline
DGL Member

Registriert: Mo Aug 15, 2005 19:29
Beiträge: 38
Hallo,
ich kann zwar nicht wirklich sagen, weshalb das nicht gezeichnet wird, aber ich hätte das sowieso komplett von Grund auf anders programmiert.

Folgender Vorschlag sollte eigentlich Recht in Ordnung sein, dann hättes du beim Auslesen auch nicht soviel Auswertearbeit und deine Mapdateien bleiben kleiner:
Ich habe bei meinem Game ein zweidimensionales statisches Array mit 32x24 Feldern genommen (1 Feld = 1 Tile = 32x32px = 1024x768px insg. :-)) und weise jedem Feld im Mapeditor die ID für die Textur zu. Beispielsweise würde in MapArray[0][0] dann 1 stehen, was dann den Boden darstellen würde. Dazu habe ich zuerst den MapEditor programmiert, der mir eben entsprechend mein Array füllt und habe das komplette Array dann per Stream mit
Code:
  1. f.Write(MapArray,sizeof(MapArray));

in eine Datei gespeichert. Somit hättest du deine Mapdaten nicht im Klartext in der Datei stehen und du müsstest auch nicht jedesmal den kompletten Pfad zu Textur mit reinschreiben -> Platz gespart (sind zwar nur ein paar Byte, aber es kann sich letztendlich doch noch summieren \";-)\")

Beim Starten des Spiels lese ich das Array wieder mit
Code:
  1. f.Read(MapArray,        sizeof(MapArray));

ein und schon ist das Array gefüllt und das Zeichnen kann losgehen.

Die Map render ich dann so:

Code:
  1.     // Map rendern
  2.     i:=0;
  3.     u:=0;
  4.     v:=0;
  5.     for x := 0 to MapSizeX - 1 do begin
  6.       for y := 0 to MapSizeY - 1 do begin
  7.         case MapArray[x][y] of
  8.           0..255: begin
  9.             i:=MapArray[x][y];
  10.             textures[0].Bind();
  11.           end;
  12.           256..511: begin
  13.             i:=MapArray[x][y]-256;
  14.             textures[1].Bind();
  15.           end;
  16.           512..767: begin
  17.             i:=MapArray[x][y]-256-256;
  18.             textures[2].Bind();
  19.           end;
  20.         end;
  21.         case i of
  22.           0..31: begin
  23.             u:=(i*32)/1024;
  24.             v:=0;
  25.           end;
  26.           32..63: begin
  27.             u:=((i-32)*32) / 1024;
  28.             v:=0.125;
  29.           end;
  30.           64..95: begin
  31.             u:=((i-64)*32) / 1024;
  32.             v:=0.25;
  33.           end;
  34.           96..127: begin
  35.             u:=((i-96)*32) / 1024;
  36.             v:=0.375;
  37.           end;
  38.           128..159: begin
  39.             u:=((i-128)*32) / 1024;
  40.             v:=0.5;
  41.           end;
  42.           160..191: begin
  43.             u:=((i-160)*32) / 1024;
  44.             v:=0.625;
  45.           end;
  46.           192..223: begin
  47.             u:=((i-192)*32) / 1024;
  48.             v:=0.75;
  49.           end;
  50.           224..255: begin
  51.             u:=((i-224)*32) / 1024;
  52.             v:=0.875;
  53.           end;
  54.         end;
  55.         glBegin(GL_QUADS);
  56.           glTexCoord2f(u,v);                glVertex3i(x*32,y*32,0);
  57.           glTexCoord2f(u+0.03125,v);        glVertex3i(x*32+32,y*32,0);
  58.           glTexCoord2f(u+0.03125,v+0.125);  glVertex3i(x*32+32,y*32+32,0);
  59.           glTexCoord2f(u,v+0.125);          glVertex3i(x*32,y*32+32,0);
  60.         glEnd;
  61.       end;
  62.     end;
  63.  


(Ich passe die UV-Werte je nach Texture-ID an, weil ich mehrere Sprites in einer Datei habe).


Ich denke mal, dass dieser Weg einfacher und schneller sein sollte, als deiner. Und funktionieren wirds anschließend mit Sicherheit auch. Falls du jedoch von der Idee nichts wissen willst: einfach den Post ignorieren ;)



Im Anhang siehst du noch ein Bild von meinem MapEditor. Links erkennst du bei den Sprites die roten Zahlen. Jeder dieser Zahl steht für eine Texture ID und wird dann eben entsprechend in der Position im Array eingetragen, in der sich gerade der Cursor befindet.

So, hoffe ich konnte behilflich sein. Wie gesagt, falls du bei deiner Methode bleiben willst ignorier diesen Post und warte, bis jemand anders helfen kann. :)
gruß
Spessi


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Mein aktuelles Projekt: *klick*


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 31, 2008 09:14 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Okt 03, 2007 14:22
Beiträge: 388
Das ist ja recht interessant, aber kann es sein, dass bei dir eine Karte auch wegen dem Rendervorgang nur eine bestimmte Größe haben darf ? Das wollte ich nämlich eigentlich verhindern, denn ich will nicht ständig Karten nachladen. Die Idee mit den Indizes ist an sich recht gut.

_________________
Meine Musik: spiker-music.net


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 31, 2008 13:25 
Offline
DGL Member

Registriert: Mo Aug 15, 2005 19:29
Beiträge: 38
Hallo,
ja, meine Maps haben immer eine feste Größe von 32x24 Tiles (Quasi "fullscreen" 1024x768px). Folgedessen musst du die Maps eben entsprechend nachladen, sobald dein Charakter außerhalb des Bildschirmrandes ist. Ich erstelle dann für die Maps eine Indexdatei, in dem ich schreibe, wo welche Map ist (ein Array). Durch das Array lokalisiere ich In-Game den Charakter und kann somit problemlos nen Mapwechsel hervorrufen. Im Anhang kannst du sehen, wie meine Maps aneinandergereiht sind. Jede Map wird eben dynamisch nachgeladen, sobald der Spieler über den Rand tritt. Ist vermutlich nicht die eleganteste Lösung, aber für meine Verhältnisse tut sie's.
Aber eigentlich sollte das ganze auch mit dynamischen Arrays und nen bissl Code für's Scrollen der Map funktionieren. Musst dann halt deinen Map-Editor entsprechend anpassen. Sprich: Größe der Map beim Erstellen einer neuen Map gleich festlegen (setlength(array,width,height);) und width und height (am besten als byte oder smallint) an den Anfang deiner Map Datei, wenn du speicherst, schreiben. Somit hättest du in den ersten 2 Bytes (sofern du Datentyp byte nutzt) die Breite und Höhe deines Arrays. Das liest du beim Auslesen deines Games wieder aus, weist deinem dynamischen zweidimensionalen Array ebenfalls wieder mit setlength die Werte zu und lässt das Array eben füllen.



Gruß Spessi
PS: Ok, für'n Anhang ist das Bild zu groß, deshalb hier der Link: http://www.abload.de/img/mapbersichto3xd4s.jpg
(die schwarzen Kästchen = Kollision. Nicht beachten ;))

_________________
Mein aktuelles Projekt: *klick*


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 15 Queries | GZIP : On ]