Сегодня закончил работу по генерации игрового мира, карты на 1 000 000 ячеек (100 на 100 километров). Последовательность была не простой и у меня на ее создание ушло около 10-12 часов суммарного времени. Ниже пересказ, как это было.
Попытка заставить Python скрипт сделать карту
Изначально я решил заставить скрипт написанный на Python мною генерировать карту с учетом параметров:
- Количество биомов
- Их процентное соотношение в игровом мире
- Их логическое расположение (север, юг, восток и запад)
И вот первые два пункта скрипту были очень простые, а с последним просто невероятные проблемы. Что я только не делал, переписывал скрипты наверное раз 10. А он постоянно генерировал какую-то дичь! Ниже один из примеров такого мира)))
Как видите карта есть, биомы все 10 штук есть, логики к реальному миру НИКАКОЙ!!! Это заставило меня на второй день мучений поискать альтернативное решение, а именно пойти от обратного.
Я начал мучить всякие нейронки по генерации игрового мира, чтобы мне сделали карты игрового мира для MMORPG. Использовал я три вида AI
- DALL-E (от Openai)
- Gemini (от Google)
- Stable Diffusion (Локально на ПК установлено с оболочкой Fooocus)
Наилучшим образом себя показала AI от OpenAi, а именно платная версия GPT4 и в ней DALL-E. Вот некоторые варианты, что получилось выжать с нее, примерно после 10 минут экспериментов с различными запросами(промтами):
Согласитесь варианты делает достойные!
Как я получил игровой мир в базу SQL
Итак я взял ту карту, которую нагенерировал AI и закинул ее в Photoshop. Далее перевел в режим: Image-Mode-Indexed Color со значением цветов 10. Это значит что весь рисунок сгенерированный нейронкой стал теперь всего с 10 цветами. Но он конечно не был пятнами и не был таким, какой есть в финале.
Я брал пипетку тыкал в место например, где горы и потом на зуме, пиксель за пикселем обрисовывал все горы, и так все 9, девять биомов! А это 1 000 000 пикселей. То еще развлечение скажу я вам))
Получилось в финале в фотошопе вот такая карта, моей ручной работы:
Где-то я просто пиксели тыкал, где-то брал кисточку и делал пятна, короче как мог изощрялся. И вот после этих приключений пришло время делать с картинки SQL данные для таблицы игрового мира.
Я Начал писать скрипт на Python который имеет такую логику работы:
Пошаговое описание работы скрипта:
1. Импорт библиотек:
from PIL import Image
— используется для работы с изображениями.import pymysql
— используется для работы с MySQL.
2. Функции:
connect_to_db()
: устанавливает соединение с базой данных.rgb_to_hex(rgb)
: преобразует RGB-значение в шестнадцатеричный формат.
3. Переменные:
image_path
: путь к файлу изображения.connection
: объект подключения к базе данных.cursor
: курсор для выполнения запросов к базе данных.BIOMES
: словарь для хранения информации о биомах.width
: ширина изображения.height
: высота изображения.pixel_counter
: счетчик обработанных пикселей.unique_id
: уникальный ID для новых биомов.
4. Обработка изображения:
- Удаление существующей таблицы
images
и создание новой. - Открытие изображения с помощью
Image.open(image_path)
. - Проход по всем пикселям изображения:
- Получение цвета пикселя и преобразование в RGB.
- Добавление новых цветов в словарь
BIOMES
с уникальным ID. - Получение ID биома и преобразование RGB в шестнадцатеричный формат.
- Добавление записи в таблицу
images
с информацией о пикселе (x, y, цвет, ID биома).
5. Завершение:
- Применение изменений в базе данных (
connection.commit()
). - Вывод информации о количестве обработанных пикселей и найденных биомов.
- Закрытие курсора и соединения (
cursor.close()
,connection.close()
).
from PIL import Image import pymysql def connect_to_db(): return pymysql.connect(host='localhost', user='root', password='', db='mmorpg', charset='utf8mb4') def rgb_to_hex(rgb): return '#' + ''.join(['{:02x}'.format(x) for x in rgb]) image_path = "Bioms_map.png" connection = connect_to_db() cursor = connection.cursor() cursor.execute("DROP TABLE IF EXISTS images;") cursor.execute(""" CREATE TABLE IF NOT EXISTS images ( id INT PRIMARY KEY AUTO_INCREMENT, x INT, y INT, color_hex VARCHAR(7), biome_id INT ); """) BIOMES = {} image = Image.open(image_path) width, height = image.size pixel_counter = 0 unique_id = 1 for x in range(width): for y in range(height): pixel_counter += 1 if pixel_counter % 50000 == 0: print(f"Обработано {pixel_counter} пикселей.") rgb = image.getpixel((x, y)) if rgb not in BIOMES: BIOMES[rgb] = unique_id unique_id += 1 biome_id = BIOMES[rgb] color_hex = rgb_to_hex(rgb) cursor.execute("INSERT INTO images (x, y, color_hex, biome_id) VALUES (%s, %s, %s, %s)", (x, y, color_hex, biome_id)) connection.commit() print(f"Обработка пикселей завершена. Всего обработано пикселей: {pixel_counter}. Найдено уникальных биомов: {len(BIOMES)}.") cursor.close() connection.close()
В результате я получаю в MySQL базе таблицу с данными под игровой мир:
P.S.
Далее будет идти программирование логики различных NPC и событий в игровом мире! Чтобы не упустить события и развитие проекта, подписывайтесь на нашу группу в телеграм:
wild world info и добавьте сайт себе в избранное. До встречи!