Zufällige Kartengenerierung im Zelda-Stil

9

Ich versuche zufällig eine Karte von Räumen zu erstellen, die durch Türen verbunden sind, und es ist mir gelungen, eine mit diesem Code zu erstellen:

public void generate(GameContainer gc) {
        rooms = new ArrayList<Room>();
        startingRoom = new Room(0);
        startingRoom.setPosition(viewport.getCenterX(), viewport.getCenterY());
        lastRoom = startingRoom;
        rooms.add(startingRoom);
        int roomsize = 25;

        for (int i = 0; i <= (1000 + Math.random() * 4000); i++) {
            Room room = new Room(i + 1);
            int direction = (int) (Math.random() * (4));

            switch (direction) {
                case 0:
                    room.setPosition(lastRoom.x, lastRoom.y - roomsize);
                    break;
                case 1:
                    room.setPosition(lastRoom.x, lastRoom.y + roomsize);
                    break;
                case 2:
                    room.setPosition(lastRoom.x + roomsize, lastRoom.y);
                    break;
                case 3:
                    room.setPosition(lastRoom.x - roomsize, lastRoom.y);
                    break;
                default:
                    room.setPosition(lastRoom.x, lastRoom.y - roomsize);
                    break;
            }
            rooms.add(room);
            lastRoom = room;
        }
    } 

Dies erlaubt mir jedoch nicht herauszufinden, welche Türen der gegebene Raum hat. Ich muss in der Lage sein, das herauszufinden, damit ich die Türen an den richtigen Stellen platzieren kann, damit sie für angrenzende Räume verwendet werden können. Ist diese Art von "Smart Map" mit meinem aktuellen Algorithmus möglich oder sollte ich von vorne beginnen? Welche Schritte kann ich unternehmen, um dies zum Laufen zu bringen?

Ich benutze dafür Slick2d und Java

Vielen Dank.

user1500452
quelle
Warum setzen Sie die Räume nicht zuerst zusammen und erstellen die Türen nach Bedarf, um sie zu verbinden?
Petervaz
Das ist es, was ich tun möchte, aber ich glaube nicht, dass ich es mit diesem Algorithmus kann, da es keine Möglichkeit gibt, Räume zu berücksichtigen, die neben vorhandenen Räumen erscheinen, die nicht die Quelle sind, was bedeuten könnte, dass die Tür nicht vorhanden ist Dort. Ich bin mir an dieser Stelle sicher, dass ich etwas völlig Neues schreiben muss. Ich strebe ein Kartensystem wie The Binding of Isaacs an, wenn das hilft.
user1500452
Es sieht so aus, als müssten die Räume nach ihrer Position leicht abfragbar sein. Ich würde eine Map <Vector2d, Room> für schnell und schmutzig vorschlagen, aber Sie möchten vielleicht ein sortiertes Array von sortierten Arrays zusammenstellen.
Schlepper
Schauen Sie hier: pcg.wikidot.com/pcg-algorithm:dungeon-generation (beantwortet Ihre Frage nicht, kann aber helfen)
Tigrou
Dies ist möglicherweise keine Option, aber Sie können Folgendes ausprobieren: Generieren Sie jeden Raum mit 4 offenen Stellen (1 für jede Wand) und platzieren Sie dann nach dem Zufallsprinzip entweder eine offene Tür, eine geschlossene Tür, eine Wand usw. in jeder der Raumverbindungen.
Supericy

Antworten:

1

Ich denke, dass diese Frage ziemlich offen ist, da Sie einige Codeteile benötigen, bevor Sie die Räume richtig verknüpfen können, und wie Sie das codieren, hängt stark davon ab, wie die Dinge für Sie sinnvoll sind.

Trotzdem kann ich Ihnen einige Empfehlungen geben, die Ihnen helfen, in die richtige Richtung zu gehen.

Wenn die Raumgrößen konstant sind, würde ich zunächst empfehlen, ein übergeordnetes Koordinatensystem für die Räume zu erstellen. Etwas, das so aussehen würde:

 _____ _____ _____ _____ _____
|     |     |     |     |     |
|-2,-1|-1,-1| 0,-1| 1,-1| 2,-1|
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|-2,0 |-1,0 | 0,0 | 1,0 | 2,0 |
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|-2,1 |-1,1 | 0,1 | 1,1 | 2,1 |
|_____|_____|_____|_____|_____|

Die Idee ist, dass Sie beim Erstellen von Raum (0,0) die Räume (-1,0) (0, -1) (1,0) und (0,1) fragen, wo sich die angrenzenden Türen befinden. Wenn Sie Bildschirmkoordinaten benötigen, sollte es einfach genug sein, eine GetScreenCoords-Methode oder eine Transformationsmatrix hinzuzufügen, wenn Sie sich für diese interessieren.

Als nächstes möchten Sie die Liste der Räume abfragen können. Das Durchsuchen aller Zimmer in Ihrer Liste (bis zu 5000!), Um nur die benachbarten Zimmer zu finden, wird teuer. Für eine schnelle Möglichkeit, die Dinge zum Laufen zu bringen, würde ich empfehlen, HashMap<coord, Room> roomsstattdessen eine zu verwenden. Auf diese Weise fragen Sie beim Erstellen von Raum (0,0) nach vorhandenen benachbarten Räumen, nach denen Sie einfach fragen rooms.get((1,0))usw., und fügen Ihren neu generierten Raum bei (0,0) hinzu, rooms.put((0,0), newroom) wenn dies zu langsam wird, kann dies der Fall sein einen Blick auf sortierte Listen wert sein. Vielleicht eine sortierte Liste (x) von sortierten Listen (y).

Schließlich müssen Sie eine Möglichkeit hinzufügen, um die Türposition von den benachbarten Räumen zu erhalten. Eine neue Methode wie int GetSouthDoor()sollte den Trick machen.

Ich bin mir sicher, dass Sie noch viel mehr Arbeit haben werden, um eine vollständige Lösung zu programmieren. Ich hoffe, dies wird Ihnen beim Einstieg helfen.

Schlepper
quelle
Sehr hilfreich, die Informationen zu Hashmaps sind genau das, was ich brauchte, um mich in die richtige Richtung zu bewegen. Vielen Dank!
user1500452
2

Zwei Dinge:

1) In deinem Kommentar sagst du, du willst so etwas wie die Bindung von Isaac. Dieses Spiel hat Türen in der Mitte jedes Stücks, die garantieren, dass sie in einer Reihe stehen. Wenn Sie diesem Beispiel folgen, kommt es nur darauf an, zu entscheiden, mit welcher Art von Tür sie verbunden werden sollen (offen, verschlossen, Bowall usw.).

2) Ihr Code scheint an einer Stelle zu beginnen und prozedural neue Kacheln in eine Richtung zu generieren. In Ihrer Switch - Anweisung, jedoch sind Buchhaltung Sie nicht für die Richtung Sie kommen aus . Wenn Sie mit diesem Algorithmus fortfahren, sollten Sie auch die letzte Platzierung verfolgen, damit sich die Kacheln nicht gegenseitig überschreiben.

Clintonmonk
quelle
0

Verwenden Sie einen Labyrinth-Generierungsalgorithmus

Verwenden Sie eine modifizierte Form des Prim-Algorithmus , um ein grundlegendes Labyrinth von etwa 20 Räumen zu erstellen. Wählen Sie zwei Räume als Start- und Endräume aus, um sicherzustellen, dass das Ende immer erreichbar ist. Blockieren Sie zufällige Türen mit unterschiedlichen Türtypen und fügen Sie zufällig Türen hinzu, bei denen zwei benachbarte Räume nicht verbunden sind (mit geringer Wahrscheinlichkeit).

Beefster
quelle