Tile_maps unter Draw3D richtig umgesetzt ?
Übersicht

![]() |
DottakopfBetreff: Tile_maps unter Draw3D richtig umgesetzt ? |
![]() Antworten mit Zitat ![]() |
---|---|---|
HI Blitzer!
In meinem Post habe ich eher ein Anliegen, als eine technische Frage. Ich bin seit kurzem Draw3D einsteiger und möchte die mitgebrachte 3D Power von Draw3D in meinem 2D RPG nutzen. Da Draw3D den Koordinatenursprung in der Mitte hat und nicht links oben habe ich mir eine Funktion geschrieben die die 3D koordinaten auf "links-oben" umrechnet, damit ich mit meiner Tile Map bzw. Arrys keine Probleme bekomme. ( Beispiel: negative pixel position umgerechnet auf negative tile position, und abgefragt in einem arry = MAV.) Die Funktion ist eigentlich total simel. Ich füttere die Funktion mit meinen "gedachten alten 2D positionen ursprung links oben" und diese Funktion spuckt dann die umgerechnete "reale" Draw3D Position aus. Das ganze funktioniert auch recht wunderbar, aber ich wollte euch einfach mal Fragen, ob ich Tile maps total falsch oder viel zu umständlich unter Draw3D realisiere.. Vielleicht gibts ja einen viel simpleren /schnelleren weg das zu machen. Naja wäre toll wenn Ihr mal einen Blick drauf werfen könntet: (evt. auch eure FPS zahlen und co.) Hier die Funktion die die Umrechnung macht Code: [AUSKLAPPEN] ;errechnet die verschiebung vom mittleren koordinatenursprung in die linke ecke oben bzw. zurück ;mode gibt an was genau umgewandelt werden soll ;mode = 1 x tile koordinate wird in 3D pixelkoordinate umgewandelt ;mode = 2 y tile Koordinate wird in 3D Pixelkoordinate umgewandelt ;mode = 3 3D Pixelkoordinate(x) in x tile koordinate umwandeln ;mode = 4 3D Pixelkoordinate(y) in y tile koordinate umwandeln Function new2Dpos(pos%,size%,mode%) Select mode Case 1 Return ((pos%*size-SCREEN_WIDTH/2)+size/2);x tile Posi to 3DPixel Case 2 Return ((pos%*size+SCREEN_HEIGHT/2)-size/2);y tile Posi to 3DPixel Posi Case 3 Return (SCREEN_WIDTH/2)/size + Floor(pos/Float(size));3DPixel Posi to x tile Posi Case 4 Return (SCREEN_HEIGHT/2)/size - Ceil(pos/Float(size));3DPixel Posi to y tile posi End Select End Function ist eigentlich recht simpel in der hand habung, möchte ich z.B. meine Mausposition in eine Tileposition umwandeln muss ich nur schreiben. Code: [AUSKLAPPEN] tile_x = new2Dpos( mousex3D , tile_size , 1 ) tile_y = new2Dpos( mousey3D , tile_size , 2 ) Um die Funktion richtig testen zu können, habe ich einen mini Map Editor geschrieben. Das ganze gibts auch hier gezippt. https://www.blitzforum.de/upload/file.php?id=6754 (ca 680 KB) Und hier nur der Source: (leider unschöne umbrüche) Code: [AUSKLAPPEN] ;Geschrieben in IDIAL Graphics3D 1024,768,0,2 SetBuffer BackBuffer() Local Timer=CreateTimer(60) Local Camera=CreateCamera() CameraClsColor Camera,64,64,64 Include "Includes\Draw3D2.bb" DrawInit3D(Camera) Origin3D(1024,768) ;--------------------------------------------------------------- Const ------------------------------------------------------------------- Const SCREEN_WIDTH% = 1024 Const SCREEN_HEIGHT%= 768 ;--------------------------------------------------------------- Locals ------------------------------------------------------------------ Local TILECOUNT_X%=2;tiles im tile_set Local TILECOUNT_Y%=2 ;--------------------------------------------------------------- Globals ----------------------------------------------------------------- Global TILE_SIZE%=32 Global CURRENT_TILE%=1 ;--------------------------------------------------------------- ARRY -------------------------------------------------------------------- Dim tile_map(50,50) ;karte aus data feld laden Restore mapdata For y = 0 To 17 For x = 0 To 17 Read tile_map(x,y) Next Next ;---------------------------------------------------------------- Grafik ------------------------------------------------------------------ Global TILE_SET=LoadImage3D("gfx\tile_set.bmp",1,1,0);tiles aus tile_set lesen/schneiden For y = 0 To TILECOUNT_Y-1 For x = 0 To TILECOUNT_X-1 GrabImage3d(TILE_SET,x*32,y*32,32,32) Next Next ;/////////////////////////////////////////////////////////////// MAIN LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ Repeat Cls draw_map() set_tiles() WaitTimer(Timer) RenderWorld Clear3D() show_infos() ;fps ermitteln..... loops = loops+1 If MilliSecs() - fpstime > 1000 Then fpsrate = loops loops = 0 fpstime = MilliSecs() End If ;.................. Text 0,0,"fps "+fpsrate Flip 0 Until KeyHit(1) ;//////////////////////////////////////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ;zeichnet alles Function draw_map() ;zeichnet die karte For x = 0 To 17 For y = 0 To 17 If tile_map(x,y)<>0 Then DrawImage3d(TILE_SET,new2Dpos(x,TILE_SIZE,1) ,new2Dpos(-y,TILE_SIZE,2) ,0,0,1,tile_map(x,y)) Next Next plot3d(TILE_SET,0,0,2);markiert nur punkt 0 0 (kleiner fixpunkt) End Function ;errechnet die verschiebung vom mittleren koordinatenursprung in die linke ecke oben bzw. zurück ;mode gibt an was genau umgewandelt werden soll ;mode = 1 x tile koordinate wird in 3D pixelkoordinate umgewandelt ;mode = 2 y tile Koordinate wird in 3D Pixelkoordinate umgewandelt ;mode = 3 3D Pixelkoordinate(x) in x tile koordinate umwandeln ;mode = 4 3D Pixelkoordinate(y) in y tile koordinate umwandeln Function new2Dpos(pos%,size%,mode%) Select mode Case 1 Return ((pos%*size-SCREEN_WIDTH/2)+size/2);x tile Posi to 3DPixel Case 2 Return ((pos%*size+SCREEN_HEIGHT/2)-size/2);y tile Posi to 3DPixel Posi Case 3 Return (SCREEN_WIDTH/2)/size + Floor(pos/Float(size));3DPixel Posi to x tile Posi Case 4 Return (SCREEN_HEIGHT/2)/size - Ceil(pos/Float(size));3DPixel Posi to y tile posi End Select End Function ;simples tile setzen Function set_tiles() If MouseHit(2) Then CURRENT_TILE = CURRENT_TILE+1 If CURRENT_TILE>4 Then CURRENT_TILE=1 If MouseDown(1) Then tile_map(new2Dpos(mousex3d,TILE_SIZE,3), new2Dpos(mousey3d,TILE_SIZE,4)) = CURRENT_TILE End Function ;zeigt die werte die die funktion zurück gibt Function show_infos() Text 600,0,"Linke Maus um Tiles zu setzen" Text 600,15,"rechte Maus um das aktuelle Tille zu wechseln" Text 600,45,"maus tile_x position " + new2Dpos(mousex3d,TILE_SIZE,3) Text 600,60,"maus tile_y postion " + new2Dpos(mousey3d,TILE_SIZE,4) Text 600,75,"----------------------------------" Text 600,90,"maus reale tile position x" + mousex3d/32 Text 600,105,"maus reale tile position y" + mousey3d/32 End Function .mapdata;18x18 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;~IDEal Editor Parameters: ;~F#58#70#7F#88 ;~C#Blitz3D Eure Meinung dazu oder Tipps wäre mir echt wichtig, da ich jetzt darauf meinen ganzes RPG stützen möchte. Danke für eure Hilfe!! Gruß Dottakopf |
||
Rechtschreibfehler gelten der allgemeinen Belustigung! |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du hast doch die Draw3Dz.bb von mir bekommen. Diese hat einen Koordinatenursprung links/oben wie von dir gewünscht. Du solltest allerdings nur noch in dieser DRAWOFFSET auf ''0'' stellen. Sonst hast du eine unscharfe Ausgabe der einzelnen Tiles.
Die DrawSGG liesse sich auch mir relativ wenigen Handgriffen kompatiebel zu der Draw3Dz.bb machen. Edit1: Wenn man vom Editor absieht, kannst du auch eine Map einzeichnen und dann das Surface über ClearOff3D ![]() Edit2: Ich hab mir jetzt mal dein Code genauer angesehen und feststellen müssen, dass einige das ''Problem'' mit dem Koordinatenursprung irgendwie sehr schwer nehmem. Im Grunde ist es ganz einfach, man benötigt nichts anderes als nur bei der Darstellung ein X/Y-Offset. Der Rest bleibt im Grunde gleich. Um nun noch über einen Editor ein Tile aus einem Array auswählen zu können, kann man auf die Draw3D-Button-Funktion zurück greifen. Diese ist nicht nur sehr schnell (habe ich mit einer Riesenmap getestet), sondern auch sehr präzise (habe ich ebenfall durch ewig viele Tests durchzogen). Der ganze Code reduziert sich fast auf die Hälfte und ist zudem einfach zu verstehen/verändern. Mit der Draw3D2 arbeitest, dann kannst du zudem auch auf die nervige Grab-Schleife verzichten und dir das automaisch durch GrabAnimImage3D erledigen lassen. Code: [AUSKLAPPEN] Const SCREENWIDTH%=1024
Const SCREENHEIGHT%=768 Graphics3D SCREENWIDTH,SCREENHEIGHT,0,2 SetBuffer BackBuffer() Local Timer=CreateTimer(60) Local Camera=CreateCamera() CameraClsColor Camera,64,64,64 Include "Includes\Draw3D2.bb" DrawInit3D(Camera) Origin3D(1024,768) Const TILESIZE%=32 Const MAPSIZE%=17 Const XOFFSET%=TILESIZE/2-512 Const YOFFSET%=TILESIZE/2-192 Dim TileMap(MAPSIZE,MAPSIZE) Global CurrentTile%=0 Local X,Y Restore MapData For Y=0 To MAPSIZE For X=0 To MAPSIZE Read TileMap(X,Y) Next Next Local TileSetMain=LoadImage3D("gfx\tile_set.png",1,1,0) Global TileSet=GrabAnimImage3D(TileSetMain,TILESIZE,TILESIZE,0,4,1,1) Repeat ;Kein CLS bei 3D-Programmen notwendig!! If MouseHit(2) Then CurrentTile=(CurrentTile+1) Mod 4 Draw_Map() WaitTimer(Timer) RenderWorld Clear3D() Flip 0 Until KeyHit(1) Function Draw_Map() Local X,Y For X=0 To MAPSIZE For Y=0 To MAPSIZE DrawImage3D(TileSet,XOFFSET+X*TILESIZE,YOFFSET+Y*TILESIZE,1,0,1,TileMap(X,Y)) If MouseDown3D=1 Then TileMap(X,Y)=CurrentTile Next Next End Function .MapData Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 Data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 Ich hab mir erlaubt ein paar Variablennamen zu ändern. Irgendwie hat mich die zum Teil ewige GROßSCHREIBWEISE bei NICHT Konstanten verwirrt, worauf ich dann losging und alles umbenannte und dabei auch ein ''_'' in diesen gelöscht. Die Map sieht nun so aus, dass das erste Tile einer Tilemap ein komplett transparentes sein sollte. Daher erstellst du dir am besten eine neue Tilemap gespeichert als PNG. |
||
![]() |
Dottakopf |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke Hectic für deine Hilfe! Finde ich Großartig das du mir mit so viel geduld weiterhilftst.
Auf die wirklich einfache Lösung mit dem Offset hätte ich wirklich selber kommen können und warum ich die Globals auf Großgeschrieben habe weis ich nicht, das habe ich noch nie gemacht gehabt. Das mit dem Surface klingt super interesannt, das wäre ja eine hammer speed optimierung! Leider bin ich da in diesem Gebiet absolut nicht fit, ich weis leider noch nicht einmal genau was ein surface ist(stelle mir dieses als ein einzelnes für sich geschlossenes objekt vor) ![]() ![]() Des weiterem stelle ich mir die Frage ob es dann noch möglich ist in dieses Surface etwas in die einzelnen Layer zu zeichnen. (z.B. ein soldat der unter einer hängebrücke steht/bewegt). Auch verwirrt mich der Zugriff über die Button Funktion auf ein Tile in der Tilemap. Ich habe mir die mitgelieferten Beispiele zur Gui angesehen(Menu.bb). Scheinbar beziehen sich die Befehle ( MousePit3D , MouseOver3D , Mousehit3d) immer auf das zuletzt erstelle Element. Das ist aber nur sinnvoll wenn ich weis was das letze element war, und dass ist bei meiner Tilemap doch unbekannt?(vorallem bei x Layern). Meinen Zugriff auf einzelne tiles im Tileset erhalte ich ,wie üblich, durch diese codezeile: Code: [AUSKLAPPEN] If MouseDown(1) Then TileMap(mousex3d/32-XOFFSET/32+1,mousey3d/32-YOFFSET/32+1) = Current_tile Also danke nocheinmal für deine Hilfe! Wenn das mit dem surface inclusive layer usw. funtzen würde wäre das einfach geil. Gruß Dottakopf |
||
Rechtschreibfehler gelten der allgemeinen Belustigung! |
![]() |
hecticSieger des IS Talentwettbewerb 2006 |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da du anscheinend mit IDEal arbeitest, werden dir die Parameter einer jeden Funktion auf der Statuszeile angezeigt. Das Worldpivot ist der vorletzte Parameter von LoadImage3D in der Draw3D2. Da kann man statt ''0'' auch ein Bezugsentity angeben. In den meisten Fällen wäre es dann ein freistehendes Pivot im 3D-Raum. Dann kann man mit der Kamera um das Teil rumfliegen und bewegt sich also nicht mehr als HUD-Element mit der Kamera mit.
Da du nun jedem Surface (das ist unter Blitz3D mindestens jede geladene Textur) ein eigenes ''Order'' vergeben kannst, kannst du auch die Zeichenreihenfolge auch so wählen, dass jede Ebene sich unterschiedlich verhält. Also auch dann, wenn immer neu eingezeichnete Objekte (z.B. Spieler) sich unter bestimmte Sachen aufhalten sollen. Beachte aber, dass eine große Tilemap welche über mehrere Surfaces festgesetzt wird (mit ClearOff3D) dann auch viel Grafikspeicher verschlucken. Es lohnt sich also nur in bestimmten Fällen. Wenn du dir da unsicher bist, dann macht die Tilemap wie gewohnt, ist kein Problem. Wirklich. Mit den Buttons beim Tile-Editor habe ich nun in deinem Code es so gemacht, dass jedes Tile ein Button ist. Wenn nun mit der Maus da drückend drüber gefahren wird, werden die entsprechenden Tiles geändert. Das umrechnen kann man sich hierbei sparen, da die Arrayposition ja bereits vorliegt, da eben das selbe Tile ja gerade gezeichnet wurde. Mit einem Geschwindigkeitstest habe ich ein Versuch gemacht und festgestellt, das der rechen-Mehraufwand sehr gering ist. Von daher sehe ich da kein Problem jedes Tile in einem Editor als Button zu deklarieren, damit man sich ein eigenes Umrechnen mit den Offsets spart. |
||
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D |
![]() |
Dottakopf |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ah danke jetzt leuchtet mir so einiges ein. Sehr aufschlussreiches Posting!
Nochmal danke für deine Mühe! Gruß Dottakopf |
||
Rechtschreibfehler gelten der allgemeinen Belustigung! |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group