вторник, 20 марта 2018 г.

Снова здравствуйте...


И вот я снова дома. Вроде отоспался, выпил беларуской водки, поел нашего хлеба с нашей же колбасой, вкусно... Включил комп, и стал вспоминать, где какая клавиша для чего в Блендере нужна, а самый лучший способ вспомнить — что-нибудь сделать. Решил сделать пример полосы загрузки уровня и расстановки объектов, благо об этом когда-то просили, понимаю что давно это было, но лучше поздно, чем никогда. Ну и чтобы тупо не дублировать пост типа «вот скачайте пример, кому надо» попробую расписать работу примера поподробнее. Тем более, что склероз не дремлет, могу и сам забыть. Да, версия Блендера в примере 2.78а, более поздние у меня не идут, надо обновления на мой Линь поставить, но мне лень. Да и интернет у меня не сказать, что хорошего качества и не дешевый. Из-за качества интернета и общего устаревания системы этот пост решил набрать в LibreOffice, а потом просто скопипастить текст, чтобы избежать постоянных предпросмотров в самом Блоггере, тоже эксперимент получается.



С чего бы начать? Пожалуй, с того, как оно всё будет выглядеть. Конечно будет полоса прогресса, но будут и два текстовых поля, одно с описанием того, что происходит, вроде «Идет загрузка библиотек...» или «Расстановка объектов...» и еще одно поле, в котором будет показан процент выполнения. Как-то так:
Идет загрузка библиотек...
«//walls.blend...»
||||||||||||||||||||||||||-----------------------------| 32%
Кстати полосу загрузки можно и текстом сделать. Вся эта красота, ответственная за отображение прогресса загрузки-расстановки будет находится на оверлейной сцене, которая должна по идее полностью закрывать происходящее на экране. Теперь понятно какое содержимое надо в файл писать, что надо будет загружать, как его вообще организовать и как он будет читаться. Это будет просто текстовый файл, как в первой Дюне, которая II. Конечно можно было бы использовать какой-нибудь json или просто закинуть в файл содержимое в виде последовательности байтов, а то и зашифровать, но зачем? Это же просто пример. Тем более что в таком файле удобно что-нибудь править ручками, правда у игрока будет соблазн подправить что-нибудь в свою пользу, с другой стороны кто-нибудь может свой ландшафт в миссию сделать или персонажей... Чтобы было удобно править файл, нужно чтобы он хорошо читался, так что всё надо будет расположить по порядку, да и комментарии не помешают. Кто читал мой пост про парсер, например тут , тот может пропустить дальнейшее описание чтения файла, ничего нового я не опишу. Замечу, что файл нужно создавать в каком-нибудь простом текстовом редакторе, никаких офисов, они всякое разное и ненужное добавляют, так что создаем в Блокноте, или gedit простой .txt. Или в редакторе Блендера. Итак, функция Python open() позволяет нам прочитать содержимое файла, причем разными способами, но нам надо прочитать его построчно, так будет удобнее. Причем не просто читать, а сохранить в памяти в виде списка строк, для последующего использования. Конечно можно было бы за один вызов скрипта прочитать строку, сразу загрузить содержимое, прочитать следующую, снова загрузить что надо и т.д., но вот полосы загрузки не получится, потому что всё выполнится за один проход скрипта, выглядеть это будет сперва как зависание компьютера, а потом сразу развернется картинка с готовой миссией. Так что создадим в объекте (тоже создать надо), который будет читать файл, а может в GlobalDict или еще где пустой список, примерно так:
own['listString'] = []
Из этого списка будем каждый запуск скрипта доставать по одному объекту и выполнять нужные действия, таким образом мы избежим как бы зависания и сможем полюбоваться полосой загрузки. После создания пустого списка откроем файл, примерно так:
file = open(path, 'r') # здесь path — это переменная с путем к файлу, подробнее про функцию     # open можно прочитать здесь.
Если мы теперь циклом прочитаем с помощью file.readlines() наш файл и поместим все прочитанные строки с помощью .append() в наш пустой список то получим прямо-таки замечательную кашу, потому что там у нас будут и комментарии, и какие бленды подгружать, и какие объекты куда ставить, а может еще что. Так что нам нужно как-то отличать прочитанные строки по типу, поэтому введем символ-метку, по которой будем понимать, что делать с этой строкой. Поскольку строка это последовательность символов, по сути список, и поддерживает взятие элемента по индексу, делаем метку самым первым символом в каждой строке. Самой первой сделаем метку комментария: «#» , прямо как в Питоне, можно и любой другой символ использовать, конечно. Вроде так:

# Ну как будто вы комментария в Питоне не видели.

«P» — это будет метка пути(Path) к файлу, который надо загрузить, «M» — метка, что строка содержит сообщение(Message), которое надо вывести на экран, «A» - добавить объект со скрытого слоя(AddObject) и разместить в указанных координатах. Как будут выглядеть строки в файле:
M_Загрузка библиотек..._\n
P_Walls.blend_\n
P_Trees.blend_\n
P_Lights.blend_\n
#_Названия блендов тут я взял от балды\n
M_Расстановка объектов..._\n
A_wall.001_0.0:2.0:0.0_\n
A_wall.001_0.0:4.0:0.0_\n
A_wall.002_0.0:6.0:0.0_\n
Сразу замечу, что символ «\n» является сиволом перевода строки и в текстовом редакторе от него никак не избавится, но Питон его прекрасно видит, поэтому его надо убирать, как и метку. Вытаскивать ценное содержимое будем с помощью функции split(), которая разделяет строку на список подстрок, используя указанный символ, или даже целую строку, как границу. Подробнее. То есть строку « A_wall.002_0.0:6.0:0.0_\n» она вернет в виде списка ['A', ' wall.002', '0.0:6.0:0.0', '\n']. Обратите внимание, что координата также записана в виде строки и для использования в привычном виде её тоже надо будет разделить, но в качестве границы используется другой символ — двоеточие. Хотя можно было бы не городить огород с лишним символом разделения и просто брать координаты по индексу, скажем х координата имеет индекс 2. Думаю понятно. Единственно с чем нет проблем, так это с комментариями, поскольку содержимое строки после символа «#» игнорируется, то после него можно писать как вздумается. Ну и символов -разделителей не должно быть в имени бленда или объекта, который засветится в нашем файле.
Теперь надо будет в теле цикла чтения строк добавить условие проверки метки, примерно так:

currentIndex = 0 # а это будет переменная — счетчик, для удобства подсчета прогресса и вообще длинны списка
for currentString in file.readlines():
    if currentString[0] == '#':
        continue # читаем следующую строку, игнорируя эту
    elif currentString[0] == 'P': # а если метка такая, то значит тут записан путь к бленду, который надо подгрузить.
        currentPath = currentString.split('_')[1] # выковыриваем путь с помощью функции от метки и символа перевода строки
        own['listString'].append(['P', currentPath, currentIndex]) # отправляем в виде кортежа, для удобства первый элемент снова метка
        currentIndex = currentIndex + 1 # знаю, что есть специальный оператор
    elif currentString[0] == 'M': # а такая метка означает, что тут записан текст сообщения, выводимого на экран
        currentMessage = currentString.split('_')[1] # опять выковыриваем сообщение и добавляем в         # список
        own['listString'].append(['M', currentMessage])
    elif currentString[0] == 'A': # вроде AddObject
        currentObject = currentString.split('_')[1]
        x, y, z = currentString.split('_')[2].split(':') # не очень красивая распаковка списка
        currenKoord = [float(x), float(y), float(z)] # собираем координату в список, и преобразуем числа из строки
        own['listString'].append(['A', currentObject, currentKoord, currentIndex])
        currentIndex = currentIndex + 1

    Ну а дальше понятно, что открываем этот список и за один вызов скрипта с помощью функции list.pop() достаем из начала нашу строку и в зависимости от того какая там метка выполняем или подгрузку файла, или расставляем объекты как у нас записано. Параллельно с помощью сообщений или еще как общаясь между сценами отправляем на оверлейную сцену информацию о проценте загрузки и текстовые сообщения для отображения на экран.
    Технически возможно не связываться с созданием списка, а читать по одной строчке из файла, правда как тогда прогресс рассчитать? Не по количеству же строк, в самом деле.
КДПВ:


Скачать тут:
loadingBar.blend.7z (~114 kB)

А в html — редакторе писать всё же неудобно, все равно много править приходится уже после написания, там цвет шрифтов и прочее, отступы теряются, наверное потому что LibreOffice старый. Хотя есть проверка орфографии. Надо будет еще в Gedit попробовать текст набить как — нибудь.
Да, проклятый склероз — чуть не забыл про лицензию, берите и пользуйтесь, как хотите, но если вдруг сделаете игру или какое другое приложение с использованием этого примера, напишите тут в комментах, мол пригодилось. Денег не потребую, так что не стесняйтесь. ))) Сам пример тоже распространяйте, если есть где, но давайте ссылку на блог. Хотя я по интернету шукать не буду, кто там его выложил, оно мне надо?

Комментариев нет:

Отправить комментарий