Speichern und Ladene eines Isometrischen Spielfeld.

  • GM 8

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Speichern und Ladene eines Isometrischen Spielfeld.

    Ich hab ein Problem und zwar würde ich gerne wissen wie man eine Isometrische Map speichern und laden könnte und das mit hilfe eines ds_grid.

    Stellen wir uns mal vor ich hätte 0 - leeres Feld, 1 - Wände ( Ihre Maske besteht aus einer Raute mit einer Spritegröße von 8p x 8p).

    Die Darstellung der Isometrischen Sicht funktioniert, jedoch hab ich echt kein Plan wie ich die Objekte beim laden so erstellen kann das sie auf zwei diagonalen Achsen liegen.
    Bei einer normalen 2D Map habe ich sowas schon oft geschaft doch ich hab kein Plan wie die Platzierung sowie die einlesung berechen soll.

    Wüsste jemand wie ich das anstellen könnte. Das komplete Grid um 45* drechen und platzieren oder ähnliches..

    MFG: Mar96K
  • Naja, Isometrie hin oder her, letztendlich sind die Koordinaten der Tiles weiterhin normal auf der X- und Y-Achse festgelegt, nur dass jede zweite Zeile versetzt ist, oder? Die Grid kann die Koordinaten doch behandeln als seien sie in einem normalen quadratischen Raster. Das isometrische Schema kannst Du ja vor dem Speichern an die normale Grid anpassen, beim Lesen dann wieder ans isometrische Raster (also je nachdem bei jeder zweiten Zeile ein Paar Px draufzählen oder abziehen).

    Es sei denn natürlich Du machst isometrische Maps, die im Grunde tatsächlich riesige Quadrate sind, die bei der Darstellung einfach schräg liegen (was etwa in schwarzen Kanten in der Spielansicht resultiert - gibts bei vielen Spielen). Dann musst Du die Koordinaten aus dem Grid tatsächlich etwas aufwändiger umrechnen.

    Hängt halt davon ab was Du vorziehst.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von F4LL0UT ()

  • GML-Quellcode

    1. for (yy=0;yy<room_height/8;yy+1)
    2. {
    3. for (xx=0;xx<room_width/8;xx+1)
    4. {
    5. //Create Event:
    6. ds_grid_add(grid,xx,yy,choose(0,1));
    7. //Draw Event:
    8. if ds_grid_get(grid,xx,yy) == 1 then draw_sprite(sp_wall,-1,xx*8,yy*8+Konstante);
    9. }
    10. }
    Alles anzeigen


    Wäre es so möglich bzw. richtig würde ich gerne wissen welche Konstante ich benutzten soll wenn die Länge und Breite eines Sprite 8x8p beträgt?
  • Ich bin grad nicht voll auf der Spur, aber ich vermute mal +4. Um sicher zu sein: Platzier doch einfach Mal ein Paar Objekte im Grid des Editors, welches an deine Einstellungen angepasst ist und prüf dann welche Koordinaten der GM ihnen automatisch verpasst. Daraus kannst Du dann definitiv erschließen, wieviel Du selbst draufrechnen musst.
  • Ich hab das ganze noch überarbeitet und hab zwei grids erstellt das zweite ist einfach um -4 x und -4 y versetzt. Jedoch bekomme ich einen sehr starken FPS einbruch obwohl ich mit nur Zwei Objekten arbeite und es sich nur zwei Instanzen auf dem Feld befinden ( Durchscnitt: 4 FPS )

    Code:

    Create
    Spoiler anzeigen

    GML-Quellcode

    1. Width = room_width/8;
    2. Height = room_height/8;
    3. mouse = instance_create(mouse_x,mouse_y,obj_mouse);
    4. grid = ds_grid_create(room_width,room_height);
    5. grid2 = ds_grid_create(room_width,room_height);
    6. for(yy=0;yy<Height;yy+=1)
    7. {
    8. for (xx=0;xx<Width;xx+=1)
    9. {
    10. ds_grid_add(grid,xx,yy,0);
    11. ds_grid_add(grid2,xx,yy,0);
    12. }
    13. }
    14. sf = surface_create(view_wview[0],view_hview[0]);
    15. surface_set_target(sf);
    16. draw_clear_alpha(0,0);
    17. surface_reset_target();
    Alles anzeigen


    Step:
    Spoiler anzeigen

    GML-Quellcode

    1. for(yy=0;yy<Height;yy+=1)
    2. {
    3. for(xx=0;xx<Width;xx+=1)
    4. {
    5. if collision_ellipse(x+xx*8,y+yy*8,x+xx*8+8,y+yy*8+8,obj_mouse,false,false)
    6. {
    7. if mouse_check_button(mb_left) then ds_grid_set(grid,xx,yy,1);
    8. if mouse_check_button(mb_right) then ds_grid_set(grid,xx,yy,0);
    9. }
    10. if collision_ellipse(x+xx*8-4,y+yy*8-4,x+xx*8+8-4,y+yy*8+8-4,obj_mouse,false,false)
    11. {
    12. if mouse_check_button(mb_left) then ds_grid_set(grid2,xx,yy,1);
    13. if mouse_check_button(mb_right) then ds_grid_set(grid2,xx,yy,0);
    14. }
    15. }
    16. }
    17. //Surface:
    18. surface_set_target(sf);
    19. draw_clear_alpha(0,0);
    20. for(yy=0;yy<Height;yy+=1)
    21. {
    22. for(xx=0;xx<Width;xx+=1)
    23. {
    24. if (ds_grid_get(grid,xx,yy) == 0)
    25. {
    26. draw_sprite(sp_floor,0,x+xx*8,y+yy*8);
    27. }
    28. if (ds_grid_get(grid2,xx,yy) == 0)
    29. {
    30. draw_sprite(sp_floor,0,x+xx*8-4,y+yy*8+-4);
    31. }
    32. if (ds_grid_get(grid,xx,yy) == 1)
    33. {
    34. draw_sprite(sp_wall,0,x+xx*8,y+yy*8);
    35. }
    36. if (ds_grid_get(grid2,xx,yy) == 1)
    37. {
    38. draw_sprite(sp_wall,0,x+xx*8-4,y+yy*8+-4);
    39. }
    40. }
    41. }
    42. draw_text(1,1,string(fps));
    43. draw_set_blend_mode(bm_normal);
    44. surface_reset_target();
    Alles anzeigen


    Draw:
    Spoiler anzeigen

    GML-Quellcode

    1. draw_surface(sf,0,0);


    Die Engine ist schon sehr langsam. Kann es möglich sein das er versucht Sprites zu zeichnen und darüber auch noch mal Sprites und die drunterliegenden trotzdem gezeichnet werden? Was ich aber nicht
    glauben kann weil sprites selber keine depth haben bzw. die von unten nach oben eingelesen wird.

    MFG: Mar96k
  • Moment, geht es jetzt um's Speichern und Laden oder Darstellen?

    Ich glaub Du missverstehst das Konzept von Surfaces. Eine Surface ist im Grunde eine Textur, auf der Du rumkritzelst - zuvor draufgepackte Sprites bleiben bestehen bis Du nochmal draufmalst. Es besteht kein Bedarf so eine Schleife zu durchlaufen so lange keine Veränderungen im Level stattfinden und schon garnicht eine, die die gesamte Map abdeckt (mich wundert, dass Du überhaupt noch auf 4 FPS kommst). Und selbst wenn Veränderungen stattfinden, sollten sie kontrollierter sein und nur den Bereich abdecken, wo sich etwas verändert hat - je nach Größe der Map ist schon das Alleinige durchlaufen der gesamten Grids samt Kollisionsabfrage ein fetter Brocken Berechnungsarbeit.

    Btw würde ich eher auf Tiles setzen als auf eine riesige Surface. Ab einer gewissen Größe sind Surfaces aus meiner Erfahrung ziemliche Performancekiller.
  • Ich hatte es auch probiert das ganze normal zudrawen und auch das ergab viel Rechenzeit und zwar genausoviel wie mit surface. Also am Surface kann das nicht liegen ich schau mal ob ich es mit tiles besser bzw. schneller hinkriege und dann würde mein problem mit der depth auch wegfallen weil man die bei einem tile ja festlegen kann. Ich bin dir sehr dankbar für deine Hilfe, eig hätte ich ja auch selbst drauf kommen können aber manchmal hat man eben ein Brett vorm Kopf zumindest ich.

    Edit: Unabhängig davon ob es tile/sprite ist und ob es normal gezeichnet wird oder über ein surface es läuft zu langsam. Naja 8x8p sprites die gezeichnet werden und das zwei mal so viel wie im raumreinpaasst weil es ja zwei grids sind sorgt schon für die schlechte performance.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von mar96k ()

  • Hallo! Hab mir die Woche dein Problem angesehen aber hatte erst heute Zeit eine Antwort darauf zu geben. Ich hatt ein ähnliches Problem. Und zwar wollte ich riesiege Karten generieren lassen (5120*5120, 10240*10240, usw.) und diese mit 32*32 Blöcken füllen. Hatte es mit Objekten versucht (ging aber voll daneben), dann mit nur dem View zeichnen (schon besser) und dann mal mit tiles (war aber auch nicht besonders), so und zum Schluss hab ich, was für mich die Beste Lösung war, geproggt.
    Und zwar lief das so ab:
    Ich zeichnete meine aktuelle View auf ein Surface. Sobald ich mich nach rechts oder links oder oben bzw. unten bewegte, Zeichnete ich das Surface verschoben und den Rand neu. So musste ich immer nur den Rand zeichnen und nicht das ganze Fenster. Und falls sich ein Tile in der View sich veränderte, lies ich nur dieses Tile neu zeichnen und nicht alles. Der einzige Fall wo man alles neu zeichnen musste, war am Anfang und falls sich das Fenster komplett wo anders hinbewege. (Hatte eine Minikarte, auf der man sich bewegen hatte können).
    Leider finde ich den Code gerade nicht, bzw. das Projekt. Aber du könntest es mal selber versuchen, falls du Probleme hast kannst du ja gerne hier wieder Fragen. Falls du das System aber nicht verstanden hast, kannst du natürlich auch nochmal fragen.

    MfG Rodrog

    Edit: 500 Beiträge ;DD
    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Ergo: Je mehr Käse, desto weniger Käse.
  • Rodrog schrieb:

    Hallo! Hab mir die Woche dein Problem angesehen aber hatte erst heute Zeit eine Antwort darauf zu geben. Ich hatt ein ähnliches Problem. Und zwar wollte ich riesiege Karten generieren lassen (5120*5120, 10240*10240, usw.) und diese mit 32*32 Blöcken füllen. Hatte es mit Objekten versucht (ging aber voll daneben), dann mit nur dem View zeichnen (schon besser) und dann mal mit tiles (war aber auch nicht besonders), so und zum Schluss hab ich, was für mich die Beste Lösung war, geproggt.
    Und zwar lief das so ab:
    Ich zeichnete meine aktuelle View auf ein Surface. Sobald ich mich nach rechts oder links oder oben bzw. unten bewegte, Zeichnete ich das Surface verschoben und den Rand neu. So musste ich immer nur den Rand zeichnen und nicht das ganze Fenster. Und falls sich ein Tile in der View sich veränderte, lies ich nur dieses Tile neu zeichnen und nicht alles. Der einzige Fall wo man alles neu zeichnen musste, war am Anfang und falls sich das Fenster komplett wo anders hinbewege. (Hatte eine Minikarte, auf der man sich bewegen hatte können).
    Leider finde ich den Code gerade nicht, bzw. das Projekt. Aber du könntest es mal selber versuchen, falls du Probleme hast kannst du ja gerne hier wieder Fragen. Falls du das System aber nicht verstanden hast, kannst du natürlich auch nochmal fragen.

    MfG Rodrog
    Verstanden habe ich das Problem schon allerdings war mein Raum nur 800x600p groß und ich habe es auch schon mit tiles versucht, dass machte es jedoch nur schlimmer. Es liegt warscheinlich daran das ich größe hätte ändern soll jedoch brauch ich diese 8x8 größe um schön dünne wände zuzeichnen und keine bunkerklötze. Aber mir fällt da grad eine Idee ein. Ich könnte abfragen ob sich bereits ein Tile auf der Position befindet und wenn nicht dann zeichnet er eins. Sollte es sich um ein falsches Tile handeln lösche ich es und erstell an der stelle das richtige. Außerdem müsste das doch funktionieren wenn ich die SurfaceGröße
    der view_wview[0] und view_hview[0] übergebe oder nicht. Wobei der view auch 800*600p groß sein sollte und der raum vielleicht 4mal so groß. Da ich eigentlich keine Objekte benutze außer bis jetzt für die generierung und sonst befindet sich auch nur diese instanz im raum. Er wird warscheinlich versucht haben ein Tile 1*10²²²²² mal zu zeichnen. Mal kucken ob ich es vielleicht doch hinbekomme.

    Rodrog schrieb:

    Edit: 500 Beiträge ;DD
    Herzlichen Glückwunsch und vielen Dank für deine Hilfe ;) - Schade das man sich nicht für alle Beiträge mit einen Button bedanken kann.