Räume generieren (z.B. per Zufall)

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

    • Räume generieren (z.B. per Zufall)

      Da man keine "Rooms" vom Programm erstellen lassen kann, habe ich ein einfaches System von Pseudo-Rooms gemacht, genannt Areas. Verläßt der Spieler den Rand, wird die entsprechende Area aufgerufen, d.h. alle zugehörigen Objekte aktiviert. Ist die Area nocht nicht vorhanden, wird sie generiert. Hier ist die dritte Version des Beispiels "Zufallslabyrinth". Das Programm ist noch in der Entwicklung und insofern nur bedingt als Vorlage nutzbar.
      Bilder
      • Neu Bitmap.jpg

        50,91 kB, 700×526, 996 mal angesehen
      Dateien
      • randomcave.zip

        (525,83 kB, 370 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von Melancor ()

    • Hallo Melancor,

      Vielen Dank für Deinen Beitrag. Ich habe mir dein Beispiel mal herunter geladen und es sieht für mich als Anfänger sehr interessant aus. Ich verstehe zwar noch nicht viel von GML, aber später wird mir das sicherlich sehr nützlich sein.
      Ich habe bei Computerspielen bisher immer am meisten Spaß gehabt wenn so viel wie nur irgend möglich zufallsgeneriert ist, da vorgefärtigte Karten z.B. für mich bei den meisten Spielen keinen wiederspielwert besitzen. Deshalb habe ich Spiele wie Master of Orion 2 oder Civilization immer sehr gemocht. Jedes Spiel ist da anders wegen der zufallsgenerierten Karte.

      Von daher nochmals vielen Dank. Fals Du das noch weiter entwickeln solltest halte uns doch bitte auf dem Laufenden. ;)
      Viele Grüße.
      UPUAUT
    • Im zweiten Beispiel werden die Leveldaten aus einer Datei geladen. Diesmal sind keine Tiles zu sehen, dafür aber eine Minimap. Auch dieses Programm ist noch nicht fertig, aber ich halte Dich auf dem laufenden :D

      Ich bin davon abgekommen, Areas im Laufe des Spiels zu würfeln. Stattdessen arbeite ich an einer Methode, das gesamte Level am Anfang zu generieren.
      Ich habe vor, die Map so ähnlich aufzubauen, wie in dem Bild.
      Dabei muß genau wissen, was für Zufallselemente in welchen Gebieten auftreten sollen. Oben die Bäume, in der Mitte die Höhle und unten eine Art Stadt.
      Dann gibt es Objekte. Diese müssen plaziert werden, wobei natürlich das Zufallslabyrinth die entsprechenden Zuzänge offen lassen muß.
      Diese Objekte sind z.B. Übergänge, Schalter, Gegenstände oder Gegner. Ich neige dazu, erstmal ein Standard-Objekt zu erstellen was wiederum für die Generierung von Gegnern etc. zuständig ist. Das erlaubt weitere Möglichkeiten wie z.B. "respawn", also daß zerstörte Objekte wieder erscheinen. Außerdem kann so ein Standard-Objekt ein komplettes Gebiet definieren. Die Bäume werden z.B. so aufgebaut sein.
      Edit: Nein, gerade die Bäume nicht. Ich habe beschlossen, die Bäume als Backgrounds zu zeichnen. Dabei greife ich übrigens auf dieses sehr interessante Example zurück
      Bilder
      • map_klein.gif

        6,98 kB, 200×200, 839 mal angesehen
      Dateien
      • mapfile.zip

        (40,82 kB, 212 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 13 mal editiert, zuletzt von Melancor ()

    • natürlich gewachsen

      Höhlen lassen sich genau wie Bäume sehr gut durch Pfade darsetellen.
      In dem folgenden Programm habe ich die draw-path-textured-Methode angewandt (siehe Link im letzten Post) um riesige, grotesk verbogene Bäume zu erzeugen. Beim Betreten einer Area werden allen sichtbaren Pfade auf eine Surface gezeichnet, die als Hintergrund und als Kollisions-Sprite dient. Außerdem stehen die Pfade immer noch zur Verfügung um z.B. Ameisen den Baum langlaufen oder Monster die Höhlengänge patroullieren zu lassen. Und wenn ich will, kann ich jederzeit die Textur ändern oder den Pfad verformen Der Aufbau ist relativ einfach (wenn auch kaum kommentiert) und kommt mit wenig Speicher aus. Nur beim wechseln der Area entsteht etwas CPU-Last.
      Die GM6-Datei ist nur 50kB klein, erstellt aber ein potentiell gigantisches Cave aus zufälligen Gängen. Es werden zwar über 50 Objekte angezeigt, die dienen aber nach einmaligem Erstellen nur noch als Speicher für den Pfad, der bei Betreten des Raumes neu gebraucht wird. Das deaktivieren habe ich mir mal gespart.
      Bilder
      • Neu Bitmap.gif

        28,45 kB, 404×317, 782 mal angesehen
      Dateien
      • treecave.zip

        (32,11 kB, 193 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von Melancor ()

    • Hallo Melancor,

      Das sieht wirklich sehr vielversprechend aus. Du hast Dich da wirklich gut in das Thema eingearbeitet. :)
      Das läßt hoffen so etwas vielleicht zukünftig öfters in Spielen vor zu finden. Entwickelst du das Ganze um es später selbst in einem Spiel zu verwenden? Oder aus Spaß an der Sache?
      Viele Grüße.
      UPUAUT
    • Das hört sich sehr gut an... hab im gerade keine Zeit mir die Programme anzusehen und zu gucken wie genau sie arbeiten... (korrigiere... habs gerade getan und es sieht grandios aus)
      ich stimme euch zu, dass es den Wiederspielwert ungemein fördert, wenn die Level zufallsgeneriert sind...

      Wenn mein Projekt das Beta-Stadium erreicht hat, werde ich mich vermutlich (nach Ansicht definitiv) nochmal an dich wenden und mir ein paar Tipps geben lassen...

      Hab mir den Code noch nicht angesehen (das konnt ich dann doch verhindern ;) ) aber nachdem was ich sehe, scheint er mir Genre-unabhängig einsetzbar zu sein.

      Naja... damit ich mich endlich vom PC lösen kann, mach ich nun mal schluss... aber unabhängig davon, ob du das für eins deiner Spiele nutzt oder nicht, ich finds voll klasse, dass du uns hier deine gmk zur verfügung stellst, denke da können viele was mit anfangen und gute Spiele noch besser machen. THX

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

    • Original von Upuaut
      Entwickelst du das Ganze um es später selbst in einem Spiel zu verwenden? Oder aus Spaß an der Sache?

      Eigentlich eher aus Spaß am Programmieren. Ich hab schon mehrere Spiele angefangen und dann auf die lange Bank geschoben. Eigentlich könnte ich die erstmal fertig machen... aber da fehlt mir dann meist der Reiz (zumal ich kein guter Grafiker bin). Deshalb versuche ich, hier Sachen zu posten von denen ich denke, daß sie anderen nützen könnten.
    • Fortschritte

      Ich gehe nicht davon aus, daß Ihr Euch die Mühe macht, alles zu verstehen. Die Bäume z.B. benötigen 5 Objekte mit Alarm-Events und 7 verschiedene Skripte, und der Code ist recht speziell...
      Die Blätter etc. müssen noch angepaßt werden, aber ich finde das Ergebnis jetzt schon so hübsch, daß ich es Euch nicht vorenthalten will. Es gibt auch bunte Blumen, Vögel und Schmetterlinge zu sehen. Und eine Hütte (klickt die mal an)

      Außerdem würde ich mich freuen, wenn jemand Ideen zum Spielinhalt oder Monstern / Gegnern beisteuern könnte. Ganz unten ist eine Art Tempelstadt geplant.

      Die Steuerung ist diesmal mit der Maus geregelt , und mit D kann man die Karte vom noch provisorischen Höhlenlabyrinth anzeigen lassen.

      Diese Version hat nicht mehr den Bug vom letzten Mal. Jetzt funktioniert das Cave.

      EDITam 16.11.07:

      Ich verlinke hier mal auf die aktuelle Version, zu finden in diesem Thread
      Das hier ist ja schon recht veraltet:
      Bilder
      • b1.gif

        21,19 kB, 311×128, 566 mal angesehen
      • wald.jpg

        60,61 kB, 700×525, 593 mal angesehen
      • Neu GIMP image.jpg

        31,95 kB, 700×525, 451 mal angesehen
      Dateien

      Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von Melancor ()

    • Perfektes Labyrinth

      Von einem "perfekten Labyrinth" spricht man, wenn jede Zelle (von jeder anderen Zelle aus) erreichbar ist. So eine Art Labyrinth zu erstellen, ist viel einfacher, als man vielleicht denkt.

      Quelle

      Meine Umsetzung in GML sieht vielleicht nicht ganz so simpel aus, paßt aber immer noch bequem auf eine Seite. Das Skript erstellt ein ds_grid, indem alle Zellen mit den dazugehörigen Wänden gespeichert sicht.
      Ich habe mir erlaubt, keine While-Schleife zu verwenden, sondern das ganze als Alarm-Event zu gestalten. So kann man den Prozeß beobachten. In Wirklichkeit läuft der Algorithmus viel schneller.
      Außerdem habe ich auf "Backtrack" und "Solution" (sie Quelle) verzichtet.

      In der Kurzform sieht diese Kleine Schmankerl so aus (create-event):

      GML-Quellcode

      1. mh=40; mv=30 // Größe des Labyrinths
      2. cell=10 // Zellengröße in Pixel
      3. maze= ds_grid_create (mh,mv);stack_x=ds_stack_create();stack_y=ds_stack_create()
      4. ds_grid_add_region(maze,0,0,mh-1,0,16)
      5. ds_grid_add_region(maze,mh-1,0,mh-1,mv-1,32)
      6. ds_grid_add_region(maze,0,mv-1,mh-1,mv-1,64)
      7. ds_grid_add_region(maze,0,0,0,mv-1,128)
      8. total=mh*mv;visit=1;cx=floor(mh/2);cy= floor(mv/2)
      9. while visit < total {
      10. if (ds_grid_get(maze,cx,cy)&16) a[0]=1 else a[0]= (ds_grid_get(maze,cx,cy-1))
      11. if (ds_grid_get(maze,cx,cy)&32) a[1]=1 else a[1]= (ds_grid_get(maze,cx+1,cy))
      12. if (ds_grid_get(maze,cx,cy)&64) a[2]=1 else a[2]= (ds_grid_get(maze,cx,cy+1))
      13. if (ds_grid_get(maze,cx,cy)&128) a[3]=1 else a[3]= (ds_grid_get(maze,cx-1,cy))
      14. if (a[0]&15=0)||(a[1]&15=0)||(a[2]&15=0)||(a[3]&15=0)
      15. { r=floor(random(4)); while (a[r]&15!=0) r=floor(random(4))
      16. ds_stack_push(stack_x,cx); ds_stack_push(stack_y,cy)
      17. ds_grid_set(maze,cx,cy,ds_grid_get(maze,cx,cy)|power(2,r))
      18. visit +=1;cx+=(r=1)-(r=3); cy+=(r=2)-(r=0);s=1*(r=2)+2*(r=3)+4*(r=0)+8*(r=1)
      19. ds_grid_set(maze,cx,cy,ds_grid_get(maze,cx,cy)|s) }
      20. else { cx=ds_stack_pop(stack_x); cy=ds_stack_pop(stack_y) }
      21. }
      22. ds_stack_destroy(stack_x); ds_stack_destroy(stack_y)
      Alles anzeigen


      Zum Visualisieren kann man diesen Code benutzen (draw-event):

      GML-Quellcode

      1. for (h=0;h<mh;h+=1) for (v=0;v<mv;v+=1)
      2. {
      3. f=ds_grid_get(maze,h,v)
      4. if !(f&1) draw_line (h*cell,v*cell,h*cell+cell-1,v*cell)
      5. if !(f&2) draw_line (h*cell+cell-1,v*cell,h*cell+cell-1,v*cell+cell-1)
      6. // theoretisch überflüssig, zeichnet die jeweils andere Seite der jeweiligen Doppelwand
      7. //if !(f&4) draw_line (h*cell,v*cell+cell-1,h*cell+cell-1,v*cell+cell-1)
      8. //if !(f&8) draw_line (h*cell,v*cell,h*cell,v*cell+cell-1)
      9. }
      Dateien
      • laby.zip

        (2,63 kB, 201 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 10 mal editiert, zuletzt von Melancor ()