Генерация случайных карт в стиле Zelda


9

Я пытаюсь случайным образом сгенерировать карту комнат, соединенных дверями, и мне удалось сгенерировать одну из них, используя этот код:

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

Однако это не позволяет мне выяснить, какие двери имеет данная комната. Мне нужно уметь это выяснить, чтобы я мог расположить двери в правильных местах, чтобы их можно было использовать в соседних комнатах. Возможна ли такая «умная карта» с моим текущим алгоритмом, или я должен начать все сначала? Какие шаги я могу предпринять, чтобы заставить это работать?

Я использую Slick2d и Java для этого

Спасибо.


Почему бы вам сначала не собрать комнаты и создать двери, необходимые для их соединения?
Петерваз

Это то, что я хочу сделать, но я не думаю, что смогу с этим алгоритмом, потому что не было бы способа учесть комнаты, появляющиеся рядом с существующими комнатами, которые не являются его источником, что может означать, что дверь не там. На данный момент я уверен, что мне нужно написать что-то совершенно новое. Я стремлюсь к картографической системе, такой как «Привязка Исаака», если это поможет.
user1500452

Похоже, вам нужно, чтобы комнаты легко запрашивались по их положению. Я бы порекомендовал карту <Vector2d, Room> для быстрой и грязной работы, но вы можете собрать отсортированный массив отсортированных массивов.
буксиры

посмотрите здесь: pcg.wikidot.com/pcg-algorithm:dungeon-generation (не отвечает на ваш вопрос, но может помочь)
tigrou

Это может быть не вариант, но вы можете попробовать что-то вроде: создать каждую комнату с 4 открытыми точками (по 1 на каждую стену), а затем просто случайным образом разместить открытую дверь, закрытую дверь, стену и т. Д. В каждом из подключений комнаты.
Supericy

Ответы:


1

Я думаю, что этот вопрос довольно открытый, так как вам понадобится несколько кусков кода, прежде чем вы сможете правильно связать комнаты, и то, как вы их кодируете, во многом зависит от того, как все это имеет смысл.

Сказав это, я могу дать несколько рекомендаций, которые помогут вам идти в правильном направлении.

Прежде всего, если размеры комнат постоянны, я бы рекомендовал создать систему координат более высокого уровня для комнат. Нечто похожее на это:

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

Идея в том, что когда вы делаете комнату (0,0), вы спрашиваете комнаты (-1,0) (0, -1) (1,0) и (0,1), где находятся смежные двери. Если вам нужны координаты экрана, должно быть достаточно просто добавить метод GetScreenCoords или матрицу преобразования, если вы в них.

Далее вы захотите запросить список номеров. Просматривать все комнаты в вашем списке (до 5000!), Чтобы найти соседние комнаты, будет дорого. Для быстрого начала работы я бы рекомендовал использовать HashMap<coord, Room> roomsвместо этого. Таким образом, когда вы делаете комнату (0,0), вы запрашиваете существующие соседние комнаты, которые вы просто просите rooms.get((1,0))и т. Д., И добавляете свою новую сгенерированную комнату в (0,0), которую вы сделаете. rooms.put((0,0), newroom) Если это станет слишком медленным, это может стоит посмотреть отсортированные списки. Возможно отсортированный список (x) отсортированных списков (y).

Наконец, вам нужно добавить какой-нибудь способ получить положение двери из соседних комнат. Новый метод вроде int GetSouthDoor()должен сделать свое дело.

Я уверен, что вам будет еще много работы, чтобы написать полное решение. Я надеюсь, что это поможет вам начать.


Чрезвычайно полезная информация о хэш-картах - это именно то, что мне нужно, чтобы подтолкнуть меня в правильном направлении. Спасибо!
user1500452

2

Две вещи:

1) В своем комментарии вы говорите, что хотите что-то вроде Привязки Исаака. Эта игра имеет двери в середине каждой части, гарантируя, что они выстраиваются. Если вы следуете этому примеру, то все сводится к тому, чтобы решить, с какой дверью их соединить (открытая, запертая, боулла и т. Д.).

2) Ваш код, кажется, начинается в одном месте и процедурно генерирует новые плитки в одном направлении. В вашем заявлении переключателя, однако, вы не учет для направления вы наступающие из . Если вы продолжите работу с этим алгоритмом, попробуйте также отслеживать последнее размещение, чтобы плитки не перезаписывали друг друга.


0

Используйте алгоритм генерации лабиринта

Используйте модифицированную форму алгоритма Прима, чтобы создать базовый лабиринт из 20 комнат или около того. Выберите две комнаты, чтобы быть начальной и конечной комнатами, гарантируя, что конец всегда достижим. Заблокируйте случайные двери с различными типами дверей и случайным образом добавьте двери, где две смежные комнаты не соединены (с низкой вероятностью)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.