Generación aleatoria de mapas al estilo de Zelda

9

Estoy tratando de generar aleatoriamente un mapa de habitaciones conectadas por puertas, y he logrado generar uno usando este código:

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;
        }
    } 

Sin embargo, esto no me permite averiguar qué puertas tiene la habitación dada. Necesito ser capaz de resolver eso para poder colocar las puertas en los lugares correctos para que puedan usarse para unir habitaciones. ¿Es posible este tipo de "mapa inteligente" con mi algoritmo actual, o debería comenzar de nuevo? ¿Qué pasos puedo tomar para que esto funcione?

Estoy usando Slick2d y Java para esto

Gracias.

usuario1500452
fuente
¿Por qué no juntas las habitaciones primero y creas las puertas según sea necesario para unirlas?
petervaz 18/03/2013
Eso es lo que quiero hacer, pero no creo que pueda hacerlo con este algoritmo porque no habría forma de dar cuenta de las habitaciones que aparecen junto a las habitaciones existentes que no son su origen, lo que podría significar que la puerta no allí. Estoy seguro de que en este momento necesitaré escribir algo completamente nuevo. Estoy buscando un sistema de mapas como The Binding of Isaac's, si eso ayuda.
user1500452
Parece que necesita tener las habitaciones fácilmente consultables por su posición. Sugeriría un Mapa <Vector2d, Room> para que sea rápido y sucio, pero es posible que desee armar una matriz ordenada de matrices ordenadas.
tirones
Eche un vistazo aquí: pcg.wikidot.com/pcg-algorithm:dungeon-generation (no responde a su pregunta, pero puede ayudar)
tigrou
Puede que esta no sea una opción, pero podría intentar algo como: Generar cada habitación con 4 espacios abiertos (1 para cada pared) y luego colocar aleatoriamente una puerta abierta, una puerta cerrada, una pared, etc. en cada una de las conexiones de la habitación.
Supericy

Respuestas:

1

Creo que esta pregunta es bastante abierta, ya que hay algunas piezas de código que necesitará antes de poder vincular las habitaciones correctamente y cómo codifica eso depende mucho de cómo las cosas tengan sentido para usted.

Dicho esto, puedo hacer algunas recomendaciones para ayudarlo a ir en la dirección correcta.

En primer lugar, si el tamaño de las habitaciones es constante, recomendaría hacer un sistema de coordenadas de nivel superior para las habitaciones. Algo que se vería así:

 _____ _____ _____ _____ _____
|     |     |     |     |     |
|-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 |
|_____|_____|_____|_____|_____|

La idea es que cuando haces espacio (0,0) preguntas habitaciones (-1,0) (0, -1) (1,0) y (0,1) donde están las puertas contiguas. Si necesita coords de pantalla, debería ser bastante fácil agregar un método GetScreenCoords o una matriz de transformación si le gustan esos.

A continuación, querrá poder consultar la lista de habitaciones. Revisar todas las habitaciones de tu lista (¡hasta 5000!) Solo para encontrar las habitaciones vecinas será costoso. Para una forma rápida de poner las cosas en marcha, recomiendo usar un HashMap<coord, Room> roomslugar. De esta manera, cuando está haciendo espacio (0,0), solicita habitaciones vecinas existentes, simplemente solicita, rooms.get((1,0))etc. y agrega su habitación recién generada a (0,0) que haría rooms.put((0,0), newroom) Si esto se vuelve demasiado lento, podría Vale la pena mirar las listas ordenadas. Quizás una lista ordenada (x) de listas ordenadas (y).

Finalmente, necesitará agregar alguna forma de obtener la posición de la puerta desde las habitaciones vecinas. Un nuevo método como int GetSouthDoor()debería hacer el truco.

Estoy seguro de que habrá mucho más trabajo para codificar una solución completa. Espero que esto te ayude a comenzar.

remolcadores
fuente
Extremadamente útil, la información sobre los hashmaps es exactamente lo que necesitaba para empujarme en la dirección correcta. ¡Gracias!
user1500452
2

Dos cosas:

1) En tu comentario, dices que quieres algo como The Binding of Isaac. Ese juego tiene puertas en el medio de cada pieza, lo que garantiza que se alineen. Si sigue su ejemplo, solo se trata de decidir con qué tipo de puerta conectarlas (abierta, bloqueada, bowall, etc.).

2) Parece que su código comienza en una ubicación y genera nuevos mosaicos en una sola dirección. En su sentencia switch, sin embargo, no estás representando la dirección que está viniendo de . Si continúa con ese algoritmo, considere realizar un seguimiento de la última ubicación también, para que los mosaicos no se sobrescriban entre sí.

Clintonmonk
fuente
0

Usa un algoritmo de generación de laberintos

Usa una forma modificada del algoritmo de Prim para crear un laberinto básico de 20 habitaciones más o menos. Elija dos salas para ser salas de inicio y final, asegurando que siempre se pueda llegar al final. Bloquee puertas aleatorias con diferentes tipos de puertas y agregue aleatoriamente puertas donde dos habitaciones adyacentes no estén conectadas (con baja probabilidad)

Carne de res
fuente