Показаны сообщения с ярлыком weapon. Показать все сообщения
Показаны сообщения с ярлыком weapon. Показать все сообщения

пятница, 30 сентября 2016 г.

Повторение пройденного. повторение - мать учения...

Работа идет не шибко торопясь. Приходится иногда прямо на ходу придумывать новые схемы или вносить коррективы в уже существующее. Тем не менее, было сделано следующее:
1. Заработали цифровые и буквенные символы ИЛС.
2. Были подчищены скрипты машин, ставшие более универсальными (в смысле можно внаглую скопировать большую часть текста и загнать ее в текст другого скрипта другой машины с минимальными правками).
3. Наконец-то вменяемо заработала коррекция скорости по высоте. Все дело в том, что у земли самолеты имеют меньшую скорость, нежели на средних и больших высотах, к примеру у МиГ-23МЛ у земли скорость 1350 км/ч, на высоте же - 2500, у МиГ-29 та же скорость на высоте, но у земли - 1500, у МиГ-25 скорость у земли 1200, зато на высоте - около или даже больше 3000 км/ч.
4. Также к своему неудовольствию отметил, что не работали показатели коррекции скорости по стреловидности крыла и работе тормозов. Как выяснилось, не в ту строчку вписал нужный коэффициент. Пока возился с мешами модели, было не до этого, но когда смена мешей была обеспечена, устранил и этот недочет.
5. Наконец заработала метка цели на ИЛС. в основе этого "явления" лежит схема, которую предложил еще в первой версии denis8424. Я, как обычно творчески подошел к пересмотру догматов и получил " те же яйца, только в профиль". Надо было бы смастряить файл примера, но все как-то не соберусь. Сентябрь вообще выдался довольно насыщенным и много чего так и не удалось сделать...

6. На ИЛС заработали метки измерения дальности до цели - это для МиГ-23, для Су-25 стал работать прицел АСП-17 (опять таки надо кинуть файл примера).
7. Начала работать возможность "убитьсяАПстену", то бишь разбить самолет о землю, хотя и тут надо доработать, потому что на тех скоростях, которые есть в игре БГЕ часто не успевает среагировать. Надо изощряться...
8. Как апофеоз  всех работ сентября отмечу введение отстрела тепловых ловушек, они же ЛТЦ, они же ЛО. Пока они работают на МиГ-23МЛАЭ2 и МиГ-23МЛД. Способ отстрела весьма извращенный. В файле json самолета выставляется значение проперти startLo = 0, которое говорит о наличии на борту патронов с ЛТЦ. Далее в файле есть список "суб-объектов", как я их обозвал. Это - фигура летчика, генераторы пушечных снарядов и эти самые генераторы ловушек. Все "суб-объекты" имеют чтение определения своего локального положения и разворота относительно родителя плюс проперти. Для генераторов ЛТЦ их два - число патронов и внушительный такой список из координат генераторов ловушек и их разворотов. собственно, можно было ограничиться только координатами, но у некоторых машин выброс ловушек может идти сначала сверху из верхних кассет, а потом снизу - из нижних. поэтому пришлось делать вложенный список. каждый элемент списка включает себя координаты (всегда) и разворот в радианах (очень редко). Поэтому алгоритм отстрела таков.
а) Подается команда на отстрел проперти startLO = 1.
б) Циклом отыскиваются потомки с именем "генераторЛО" и это свойство передается им.
в) Генератор ловушек выполняет команду на выстрел.
г) Генератор ловушек уменьшает свое проперти "патронЛО" (число ловушек) на 1.
д) Генератор ловушек сдвигается на новое 2место жительства" согласно списку координат и разворотов на одно деление (отыскивается элемент с номером, соответствующем текущему значению числа ловушек).
д)Генератор ловушек проверяет, есть ли в элементе списка еще и данные для разворота. Если есть, он еще и поворачивается.
Как только число ловушек равно нулю, генератор немедленно блоуирует у своего родителя возможность стрельбы, проперти startLO самолета становится равным минус 1. И генератор исчезает "мавр сдал свое дело".

Ну а дальше пошло нудное занятие по подгонке стартовых координат и поворотов, создание дыма горящих ЛТЦ - это уже рутина...
Из эффектов полета остается сделать  вихри при маневрировании и эффект пробития звукового барьера.
И еще, штопор. Вот с ним надо крепко подумать. Имея перед глазами показатели угла атаки, пусть и такие грубые и примитивные, как у меня, несложно добиться сваливания в штопор. Более-менее ясно, как его крутить. Остается придумать, как из него выйти. С этим у меня откровенно ничего не вышло и в первой версии я это дело просто убрал, отложив до лучших времен. Не знаю, как там насчет "лучших", но делать это необходимо.
Также я занимался и МиГ-21. Сделал развертку - в первом приближении, для камуфляжа и расшивки. Дополнительные объекты вроде ниш шасси, колес и пр., я наношу на развертку потом, места для них хватает. пока получается камуфляж МиГ-21бис ВВС ГДР.

четверг, 1 сентября 2016 г.

Реинкарнации.Новое слово в бортовых номерах.

Постараюсь набрать этлт пост без ошибок - пытаюсь освоить десятипальцевый метод набора текста. Получается со скоростью пока нешибко, нонадо когда-то начинать.
Пока идет работа по возврашению моделей из первой вермии встрой. В первую очередь это касается кабин. Ничего особо нового нет, кроме скрипта работы приборов, да текстуры там теперь работают в формате dds. Введен строй МиГ-23МЛД, готовится МиГ-27К...
Давно назревал вопрос с бортовыми номерами. Так уж получилось, что у меня действоало жесткое ограничеие по количеству номеров - 16 штук и не более. Номера представляли собой плейны с цифрами, меши которвх подменяли постоянный обьект CntAircraft. Но я помнил о возможностях UV-скроллинга и мне хотелось эти возможности использовать. В конце концов решение было найдено. Сам бортовой номер в моем случае - строковое проперти, состояшее из цифровых симвлов. UV-скроллинг предусматривает сдвиг развертки вправо-влево (по оси Х), и вверх-вниз(по оси Y). Отыскав в своих закромах заготовки бортовых номеров, приступил к созданию так называеемых стилей - текстур цифр от 0 до 9, обьединенных в строчки. В принципе можно было использовать всего одну и применять цвет объекта к материалу. И получить люьой цвет цифр. Однако существуют варианты номеров с кантом (обводкой по контуру) и их довльно много - и тут цвет объекта неприменим. Поэтому в итог у меня получились три стиля бортовых номеров в 6 вариантах - белый(без канта), контурный белый кант, прозрачный внутри и 4 варианта с обводкой - красный, желтый, синий и черный. Полученные варианты по моим прикидкам, перкрывают пока весь нужный мне диапазон - что натовский, что сербский, что наш, что ливийский стандврты.
Далее пошла реформа генерации бортового номера - теперь бортовой номер в комплекте к модели идет один, но состоит он  из объектов, число которых равно длине номера, к примеру, "541" - три объекта - numObj0-1-2, последний символ в имени - номер симола в последователности цифр. В данном случае - 5 - 0 , 4-1 и 1-2.  А далее следует алгоритм сдвига развертки. У нас 10 цифр, значит одно "деление" сдвига - 0.1, а цифра, извлекаемая из последовательности номера, указывает, насколько надо сдвинуть развертку. Привожу кусок кода. Надеюсь, мысль понятна.
   
 #ЭТОТ БЛОК ФОРМИРУЕТ НОМЕР ЮНИТА, ВЫБИРАЯ ЧИСЛА В ПРОМЕЖУТКЕ, УКАЗАННОМ В ФАЙЛЕ JSON
            #Ограничения слева и справа по номеру
            limitLeft = dataJSON["listBortNumber"][0]
            limitRight = dataJSON["listBortNumber"][1]
            
            numberUnit = random.randrange(limitLeft,limitRight)
            if numberUnit not in bge.logic.globalDict["importMesh"]:
                if numberUnit not in bge.logic.globalDict["importMesh"]:
                  
 if numberUnit < 10:
#для номеров типа 01,02.03 и так далее
                        unitNew['unitNum'] = '0' + str(numberUnit)
                    else:
                        unitNew['unitNum'] = str(numberUnit)
                    bge.logic.globalDict["importMesh"].append(numberUnit)
           
            #Далее идет выдача бортовых номеров
            for numObj in unitNew.childrenRecursive:
                #В названии составляющих бортового номера присутствует numObj
                if 'numObj' in numObj.name:
                    #Далее выбирается конкретная цифра в номере
                    number = int(numObj.name[-1])
                    sdvigUVplane = int(unitNew['unitNum'][number])  
                    mesh = numObj.meshes[0] 
                    array = mesh.getVertexArrayLength(0)
                    for k in range(0,array):
                        vertex = mesh.getVertex(0,k)
                        UV = vertex.getUV()
                        #Сдвиг УВ-сколиинга вправо на нужное деление
                        UV[0] = UV[0] - sdvigUVplane/10
                        vertex.setUV(UV)

плейн номера знает, какая цифра в номере ему нужна, извлекает ее, преобразует в число и сдвигает свою развертку на нужное деление. Максимальная длина бортового номера - 5 символов (ирак и Югославия), обычно 2-3 (мы и натовцы), реже - 4 - (Сирия, ЧССР, Ливия). Номера теперь в json юнитов задаются ограничениями слева и справа, типа 'listBortNumber':[0, 100].
Кстати о джейсонах. Файлы эти размножились и прочно обосновались как в файлах юнитов, так и в файлах оружия и стало их много. они выполняют стартовую работу - раздают проперти, парентят объекты, располоагают их и разворачивают, как надлежит. Для всех МиГ-23 работа над файлами джейсонов закончена, кроме МиГ-27, но и для них осталось лишь определить положение ракет Р-60, может быть по мере добавления новых видов оружия будут создаваться дополнительные json, но это дело еще впереди.
Пока что результат с бортовыми номерами и json установки оружия...
 МиГ-23МЛД, бортовой номер "31 красный" При первом пробном запуске был "24 крачный".
 Ливийский МиГ-23МФ, бортовой номер трудно разглядеть - запускал несколько раз, номер менялся типа 4782 или 4753 черный.
А это - эксперимент с json МиГ-23БН ВВС Ливии - кроме трех ПТБ - по паре РБК-500 и РБК-250, плюс пара ОФАБ-250 на хвостовых балках.

пятница, 10 июня 2016 г.

Явно верной дорогой идем, товарищи...

Есть какая-то мистическая взаимосвязь между успешным кодингом и отключением света в моем доме... уже давно заметил, чт стоит создать солидный кусочек нового кода и приготовить солидный задел на будущее, как наши доблестные энергетики гасят свет. Причем надолго. Бывает это нечасто, но совпадения с успешным продвижением  по проекту настораживают)))... Как это было вчера. После некоторой возни я отладил пуски НАР, одиночные пуски ракет типа "воздух-воздух" и приготовился реализовать пушечный огонь, как последовало отключение (давненько такого не было, чтобы на 8 часов). В иоге вчерашний день был потерян.
Сегодня опять занялся оружием и сделал огонь из пушки. А к аркетам присобачил факел огня. Ничего особо сложного там не оказалось, разве что отработал вызов функций из другого скрипта - примитивно, но работает. В начале работающего скрипта пику - import moduleclass
А потом в нужном месте - moduleclass.blablabla(). То есть пишу, какую функцию надобно использовать из загруженного модуля moduleclass. Как всегда, нужные мысли не всегда приходят в нужное время. Что мешало в первой версии  таким образом разбить на функции хотя бы тот же искусственный интеллект ботов и спокойно вызывать нужную функцию в зависимости от ситуации? Но лучше поздно, чем никогда... Пока у меня таким образом работают функции сброса и пуска, плюс функции смены оружия, я сейчас пока стараюсь побыстрее создать "скелет" игры, создавая код в меру своего умения и сопровождая его подробным комментарием, чтобы потом при совершенствовании не вспоминать, чего я там нагородил. ну и стараюсь, чтобы объем поменьше был у пускового файла.  Относительно недавно один пользователь БУ, с которым я списался в ВК, любезно продемонстрировал мне, как можно мыслить абстракциями и что из этого можно извлечь. С помощью Питона. Результат впечатляющий, и, после завершения работы над основной частью кода, я, скорее всго, начну пробовать 2мыслить абстрактно", что должно привести к резкому сокращению кода и должно повысить скорость. К тому же он меня предупредил, что реализованный в БГЕ ныне метод мутации объекта (после создания класса) не совсем оптимален и может вызвать утечку памяти при определенных условиях.  Если честно, я пока в мутации разбираюсь слабо, но это дело придется поправлять.
Пока что на данный момент имеем пуски неуправляемых ракет, сбросы бомб, и пуски пока еще болванок, которые должны стать управляемыми ракетами. Плюс пушка. Из крайне неоходимых операций добавления объектов мне осталось реализовать алгоритм отстрела тепловых ловушек, а также дымные следы. Есть предположение, что можн7о будет добавить дымные шлейфы и к НАРам, от которых я был вынужден в первой версии отказаться. Есть у меня анимированная текстура длинного дыма, которую я и использую. Частица дыма для НАР будет одна- ее длина будет расти сообразно скорости ракеты,а потом частица будет 2отцепляться" от ракеты с исчезновением факела огня и быстро таять... Таким образом, БГЕ не должен сильн перегружаться при массовых пусках ракет. Что касаемо УР большой дальности, то для них дымный след останется тем же, но в алгоритм добавления частиц дыма будет добавлено выставление длины частицы сообразно скорости ракеты. Также это правило будет действовать и для отстреливаемых ложных целей 9ловушек). В первой версии неестественность дыма бросалась в глаза на малых скоростях самолета. К тому же УР будут набирать скорость слежения за целью плавно, а не рывком, как в первой версии - из-за этого "ломаность" линии дыма также бросалась в глаза.
После завершения работы над отстрелом ловушек и дфмами можно будет приступать к возвращению и совершенствованию самонаведения для ракет, а потом очередь дойдет и до бронепробиваемости под разными углами для разных типов снарядов... Работы много еще. а вот после завершения "скелета" игры и отработки взаимодействия объектов уже можно клепать модели и разнообразить технофауну. В первой версии примерно так и было, с той лишь разницей, что новые объекты там добавлялись с большим скрипом. Надеюсь, в этот раз такого безобразия не будет.
А теперь - красивые картинки (ну как красивые, довольно приешиеся, поди уже, с пустнным пейзажем и МиГ-23)...

 Пуск Р-23Р

 Пушечный огонь






 Залп НАРами
 Сброс бомб

суббота, 28 мая 2016 г.

Меню. Ощупью в полдень...

Теоретически создание меню вроде как вещь несложная.Небольшой опыт у меня худо-бедно имелся. Даже для создания меню выбора типа оружия когда-то добрался. Потом, правда все прикрыл, планируя заняться в конце создания первой версии. в итоге работу над первой версией остановил за ее бессмысленностью, и занялся относительно недавно тем же самым во второй версии.
В первую очередь занялся меню редактора миссии, как наиболее сложной частью меню. при создании миссии необходимо:
1. Создать коалиции
2. Выбрать юнит коалиции
3. Выдать юниту оружие (причем учесть все точки подвески).
4. Указать количество юнитов данного типа в группе
5. Цувзвть координаты группы на террайне
6. указать маршрут группы по точкам
7. Указать тип миссии юнитов группы (перехват, патруль, эскорт, БШУ, РБУ, разведка)
8. Собрать все данные в кучу в строго определенном порядке
9. Загнать весь список в большой мега-список миссии.
10. Выбрать следующий юнит и повторить вышеперечисленные пункты.
11. По окончании формирования сценария миссии записать мега-список в текстовый файл.

пока работа подошла к фазе выбора оружия. В моем меню сначала появляется набор флажков участвующих в данной миссии стран (потенциально участвующих). При нажатии на иконку флажка она помечается белой рамкой. Далее, нажав синюю или красную кнопку, отправляем флажок в нужный нам "лагерь" коалиции. По окончании формирования коалиции можно отменить результат или подтвердить, для этого есть кнопки с надписями рядом - Back (Назад) или Аccept(Принять).
После подтверждения появляется меню выбора юнитов и оружия для них. Названия юнитов формируются в виде столбца кнопок с иконками выбранной страны и текстом, цвет которого соотетствует "цвету стороны". При нажатии кнопки юнита появляется надпись Weapons(справа) и под ней кнопки выбора пар подвесок. Для МиГ-23МЛАЭ2 ВВС Лвии, к примеру, точек подвески три (считая нулевую - для подвесных топливных баков), но само оружие размещается на двух парах точек подвески. На скрине как раз показан набор оружия для подкрыльевых пилонов (пара точек подвески за номером 1).
Необходимо как-то отмечать выбранные (нажатые) кнопки юнитов и оружия (можно это сделать изменением цвета, но, скорее всего, это будет белая черта-подчеркивание - на мой взгляд - четче видно).
Пока чтог пишется скрипт управления меню, по мере 2отшлифовки" и вылавливания ошибок в него добавляются все новые и новые блоки генерации и расстановки кнопок, пишутся комментарии и пояснения, зачем все это нужно.. Помимо генерации самих кнопок их еще надо и расставить -так что там еще приходится учитывать координаты кнопок меню, чтобы они не "наезжали" друг на друга и на линии меню. Как обычно, скрины. Немного скучные - я не уделял пока оформлению меню много внимания, да и вообще, по идее, меню надо делать после окончания работы над самой игрой (так я думал раньше), но во второй версии слишком много завязано на меню, поэтому, сделав какой-то минимум в игровом процессе, пришлось браться за кногпки и надписи...
P.S. Пока в меню выбора сторон только два флага - Ливии и Саудовской Аравии- в папках имеются самолеты разной стпени готовности, но я пробовал и другие страны (пустые папки с названиями юнитов - чисто для теста). Все это работало, что позволяет надеяться, что в будущем процесс добавления новых юнитов будет походить быстро и безболезненно (а не так, как в первой версии, да и юниты могут стать какими угодно, к примеру имперский крейсер "Звездный разрушитель", хе-хе)...

вторник, 3 мая 2016 г.

Горячая пора-5. Снова бубен и танцы...

Заимев кое-какой опыт игростроения и программирования, со своей колокольни могу сказать, что самое пакостное в этом деле - выработка стандартов. Нет речь не идет о вещах типа формата кодировки типа Юникод или UTF-8(хотя очередной неожиданный облом с кодировкой заставил меня сильно пожалеть, что не существует одного раз и навсегда установленного стандарта кодировки, по крайней мере тогда  можно было бы не опасаться "взбрыков" Винды).
Стандарты в игростроении это некая сакральная вещь, к которым приходишь после долгих размышлений, проб, ошибок и разного рода неожиданностей, иногда столь же забавных, сколь и зловредных.
Целых три дня я пытался сообразить, с какого перепугу у меня не генерятся одинаковые подвески оружия на разных пилонах. Потом было выявлено "узкое место". Потом был применен метод "против лома нет приема, если нет другого лома"... В общем, очередные танцы с бубном. Однако по порядку.

Все варианты подвесок для того или иного юнита, а также его стартовые значения свойств (типа ТТХ, БРЭО и дополнительных объектов у меня прописаны в текстовом файле с именем - "ИмяЮнита_Нация_Инит" формата txt. Это именно что текстовый файл, только весьма своеобразного наполнения. Для подвесок вооружения строчки в нем имеют вид:
P|1|1-R-60-4|FLG_APU602W_|0.0025|0.034
P|1|1-R-60-4|R-60|-1.428|-0.81|-0.01|-0.0175|0.0|0.0|1|0.01|0.043|1|60|s3
P|1|1-R-60-4|R-60|1.428|-0.81|-0.01|-0.0175|0.0|0.0|1|0.01|0.043|1|60|s3
P|1|1-R-60-4|R-60|-1.66|-0.81|0.17|-0.0175|1.575|0.0|1|0.01|0.043|1|60|s3
P|1|1-R-60-4|R-60|1.66|-0.81|0.17|-0.0175|-1.575|0.0|1|0.01|0.043|1|60|s3
P|2|2-R-60-4|FLG_APU602F_|0.0025|0.034
P|2|2-R-60-4|R-60|-0.47|-0.21|-1.0|-0.0175|0.0|0.0|2|0.01|0.043|1|60|s3
P|2|2-R-60-4|R-60|0.47|-0.21|-1.0|-0.0175|0.0|0.0|2|0.01|0.043|1|60|s3
P|2|2-R-60-4|R-60|-0.7|-0.21|-0.71|-0.0175|1.575|0.0|2|0.01|0.043|1|60|s3
P|2|2-R-60-4|R-60|0.7|-0.21|-0.71|-0.0175|-1.575|0.0|2|0.01|0.043|1|60|s3

В данном случае после буквы Р и разделительной черты следует индекс пары подвески (первая, вторая...), затем следует куча других значений - координаты местонахождения, тип изменяемого меша, повороты объекта при появлении, вес, лобовое сопротивление и так далее... Замечу только, что сначала записи типа 1-R-60-4 и ей подобные выглядели так -  R-60-4. На подобное извращение пришлось пойти из-за весьма любопытного нюанса. Маленького такого нюанса... И зловредного.
Для того, чтобы не плодить кучу проперти типа пойнтВеапон1, пойнтВеапон2  и так далее, в отличие от первой версии у меня существует лишь одно такое проперти, тоже строковое и имеет оно вид (точнее имело вид) - 'FuelTank-3_R-60-4_R-60-4'. Чтобы получить список вооржения я эту строку преобразовал в список матодом
if weapon != 'No_Weapon':
        #То режем значение проперти по списку   
        weaponList = list(weapon.split('_'))

При распечатке списка получилось ['FuelTank-3','R-60-4','R-60-4']
Казалось бы, радуемся жизни. Генерация оружия у меня идет методом перебора символов в текстовом файле (как раньше писал):
#то заглядываем в файл
    for string in directClass:
        #Срез строки по маркеру |
        config = string.split('|')
        #Эта строка, с начальным символом # - комментарий и ее читать не надо
        if config[0] == '#':
            continue
     
        #Это означает, что строка относится к подвеске оружия
        elif config[0] == 'P' and weapon != 'No_Weapon':
            #Далее сравниваем значение названий вооружения и их ИНДЕКСА в списке weaponList, потому что
            #названия подвеско могут совпасть, а вот и названия и номера одновременно - нет.
            for obj in weaponList: 
                #print(weaponList.index(obj))
                if obj == config[2]:
                    #Это название МЕША, который следует загрузить из бленда
                    importObj = config[3]
                    #НЕ ПУТАТЬ НАЗВАНИЯ ПОДВЕСКИ  И МЕША ТРЕБУЕМОГО ОБЪЕКТА, ПОТМУ ЧТО ПОДВЕСКА МОЖЕТ БЫТЬ СМЕШАННОЙ
                  
                    if importObj not in bge.logic.globalDict["listLoadObj"]:
                        bge.logic.LibLoad('//Weapon/' + importObj + '/' + importObj + ".blend",'Mesh',load_actions = False)
                        bge.logic.globalDict["listLoadObj"].append(importObj)
                    #В строчках подвесок указываются пилоны подвески, но для них проперти веапон
                    #задаваться не будет - ни к чему, зато число объектов-ракет и бомб определяется числом строчек
                    newM = scene.addObject('UniversalMesh', own)
                    newM['meshs'] = config[3]
                    newM.setParent(own.parent, False, False)
                    #После парентинга и замены мешей раздаем координаты ракетам и бомбам
                    if 'APU' not in importObj:
                        if 'Pilon' not in importObj:
                            if 'Fuel' not in importObj:
                                newM.localPosition[0] = float(config[4])
                                newM.localPosition[1] = float(config[5])
                                newM.localPosition[2] = float(config[6])
                                newM.applyRotation([float(config[7]),float(config[8]),float(config[9])],True)
                                newM['weapon'] = int(config[10])
                                newM['antiForce'] = float(config[11])
                                newM['massChild'] = float(config[12])
                                newM['childBK'] = int(config[13])
                                newM['textWeapon'] = config[14]
                                newM['tipSbros'] = config[15]
                            #Зато у топливного бака есть емкость
                            elif 'Fuel' in importObj:
                                newM.localPosition[0] = float(config[4])
                                newM.localPosition[1] = float(config[5])
                                newM.localPosition[2] = float(config[6])
                                newM['fuel'] = float(config[7])
                                newM['antiForce'] = float(config[8])
                    #Для пилонов и АПУ предусмотрено лобовое сопротивление, как идля топливных баков, ракет и бомб
                    elif 'APU' in importObj:
                        newM['antiForce'] = float(config[4])
                    elif 'Pilon' in importObj:
                        newM['antiForce'] = float(config[4])
По окончании всего этого закрываем текстовый файл и ликвидируем генератор (мавр сделал свое дело). Сбольшим удивлением обнаружил, что генерится у меня только одна пара подвесок, причем ДВА РАЗА. то есть я вижу-то одну пару подвесок - с четырьмя Р-60, но их там ВОСЕМЬ и ДВА ПИЛОНА, они "вложены2 друг в друга. вот тут я и завис... Перепробовал разные способы, ничего не помогало. причем вроде как алгоритм-то верный - фигура летчика, баки, все это прекрасно работало. Ошибка была выявлена и оказалась весьма странной. Снова смотрим:if weapon != 'No_Weapon':
        #То режем значение проперти по списку   
        weaponList = list(weapon.split('_'))

Перед этим я исправил в текстовом файле R-60-4 и аналогичные строки на 1-R-60-4 и так далее. Думал, если дополнительно указать номер подвески перед ее названием, то это сработает.
Посмотрел на список:
 ['FuelTank-3','R-60-4','R-60-4']
После манипуляций с резкой и преобразованием проперти в список с учетом ИНДЕКСА полученных элементов в списке должно было пропечататься:
  ['0-FuelTank-3','1-R-60-4','2-R-60-4']. А вот получилось:
['0-FuelTank-3',1-'R-60-4','1-R-60-4'].
Теперь понятно, почему первая пара подвески генерилась дважды, а второй не было вообще? Я специально распечатал строковые значения индекса списка и получил 0,1,1. А должно было быть 0,1,2. Как у всех нормальных людей. Видно чего-то опять "гениальное" сотворил, талант у меня на такие вещи, м-дааааа...
Тогда я решил поступить по-простому, по пролетарски. Раз эта ошибка появляется при одинаковых названиях оружия на подвеске, значит, надо эти названия сделать неодинаковыми. Как хорошо, что я еще не добрался до меню, а экспериментирую, жестко задав значение проперти в исходном скрипте... Я просто поменял вид 2оружейного2 проперти на 0-FuelTank-3_1-R-60-4_2-R-64.
Против лома нет приема. Скрипт послушно проглотил наживку. И имеем результат:

Танцы с бубном продолжаются, denis8424 предложил просто задать значения подвески "справа-налево", причем для всех точек, что позволит сделать индивидуальные подвески. В том числе и асимметричные. Со своей стороны, кажется додумался, как выбирать оружие, несколько упростив эту процедуру, заодно это позволит не переключаться при наличии одинаковых вооружений на разных парах подвески. Выбор оружия должен производиться не по номеру подвески а по названию самого оружия. Правда, это дело еще надо обдумать...

четверг, 28 апреля 2016 г.

Горячая пора-4. Кувалдой и напильником обретешь ты право свое...

Столь вычурным названием этот пост обязан  долгим и не сказать что удачным поискам решения по загрузке и расстановке юнитов, а также раздаче им стартовых характеристик. После серии обломов пришел к тому, что теперь юниты грузятся путем просмотра многомерного списка типа:
generationList = [['2','UnitAir','red','Yes','MiG-23MF','Libya','FuelTank-3_R-23R_R-13M','Intercept','4','300.0_200.0_1500.0','0.0'],
                      ['2','UnitAir','red','Not','MiG-23MF','Libya','FuelTank-3_R-23R_R-13M','Intercept','4','1000.0_200.0_1500.0','0.0']]

Часть данных, судя по всему придется либо трансфорировать, либо просто выкинуть, но девять десятых из этого списка останется, наверное.
Из этого мегасписка, который будет выглядеть куда как пострашнее (а ведь здесь всего-то два самолета), извлекаются циклом по отдельности вложенные списки, которые я обозвал кластерами (надо же как-то выпендриться). Далее из кластера извлекаются и используются данные, причем иногда их надо преобразовать. Если учесть, что эта операция с небольшой натяжкой - одноразовая и используется только лишь при старте игры, тог тормозить она не должна (при старте игры и так есть закономерное подвисание при подгрузке ландшафта (что я наблюдаю во вполне "фирменных" играх тоже).
Далее я долго ломился в открытую дверь... Изощрялся в вызовах функций, модулей, классов, плохо в этом соображая и не понимая, что это совсем необязательно. В конце концов после отработки генерации на подвесках всего, что требуется (прошлый пост), пришел к более простому и универсальному способу. В каждую папку с юнитом суется файл с названием типа MiG-23MF_Libya_INI.txt, где содержится записб на первый взгляд непонятная, однако если читать скрипт, который занимается извлечением и применением данных из этого файла, то не такая уж и непонятная. Сам файл имеет вид типа:
#Технические характеристики
T|694|17500|220|0.8|1.3|0.3|1.0|0.14|4|12.5|1.8|4090.0|400|10000.0|E_|7400|FLG_|1.1|1.1|W\n
#Характеристики БРЭО
E|45|60|1.8|1|0.75|0.1|0.3|15|W\n
#Размещение камеры летчика в кабине
D|0.0|3.0|0.56|W\n
#Размещение пилота
O|PilotRus|0.0|2.85|0.25|W\n
#Бортовые номера
N|b_|6901,6902,6903,6904,6905,6906,6907,6908,6910,6911,6912,6913,6914,6915,6916|W\n
#Один топливный бак
P|0|FuelTank-1|FLG_FuelTank_Center_|0.0|-1.13|-1.04|0.8|0.05|W\n
#Пара топливных баков
P|0|FuelTank-2|FLG_FuelTank_Wing_|-2.67|-1.76|-0.1|0.8|0.05|W\n
P|0|FuelTank-2|FLG_FuelTank_Wing_|2.67|-1.76|-0.1|0.8|0.05|W\n
#Три бака
P|0|FuelTank-3|FLG_FuelTank_Center_|0.0|-1.13|-1.04|0.8|0.05|W\n
P|0|FuelTank-3|FLG_FuelTank_Wing_|-2.67|-1.76|-0.1|0.8|0.05|W\n
P|0|FuelTank-3|FLG_FuelTank_Wing_|2.67|-1.76|-0.1|0.8|0.05|W\n
#ПЕРВАЯ ПАРА ПОДВЕСОК
#Ракеты Р-24Р
P|1|R-24R|FLG_APU23_|0.005|W\n
P|1|R-24R|R-24R|-1.428|-2.0|0.03|-0.035|0.0|0.0|1|0.02|W\n
P|1|R-24R|R-24R|1.428|-2.0|0.03|-0.035|0.0|0.0|1|0.02|W\n
#Ракеты Р-24РМ
P|1|R-24RM|FLG_APU23_|0.005|W\n
P|1|R-24RM|R-24RM|-1.428|-2.0|0.03|-0.035|0.0|0.0|1|0.02|W\n
P|1|R-24RM|R-24RM|1.428|-2.0|0.03|-0.035|0.0|0.0|1|0.02|W\n

В файле перечислены варианты подвесок самолета, его пилоны для этих подвесок, координаты и повороты подвешиваемых объектов, а также всякие мелочи вроде лобового сопротивления, веса горючего в баках  и так далее. Но перед этим расписаны технические характеристики самолета, его особенности, вроде типа используемого шасси или названия семейства. Плюс положение летчика, положение камеры в кабине, характеристики бортовой электроники и так далее. Все это буду расписывать в следующих постах, по мере "введения в строй" бортсистем. Добавлю только, что предусмотрены "мертвые зоны" для РЛС (БРЛС "Фантомов", "Томкэтов", МиГ-23М, МиГ-21МФ например весьма плохо видят цели на фоне земли и не могут их захватить, зато радары МиГ-23МЛД, Ф-15, МиГ-29, не говоря уж о Ф-22 и "Тайфунах", отлично видят и сопровождают низколетящие цели), параметры устойчивости к помехам и так далее. в перспективе думаю возможно реализовать так называемую "уводящую помеху" для УРВВ с РГСН, до которой дело так и не дошло в первой версии, как и до контейнеров РЭБ, которые и будут эту помеху устраивать. Вообще во второй версии имитацию электроники юнитов постараюсь сделать гораздо более продвинутой.
Ладно, это погтом, и вообще, "гладко ьыло на бумаге", вернемся к нашим баранам...
В игровой сцене есть такой объект Generator, который является "внуком" двигателя. "Внучок" проживает недолгую, но очень насыщенную жизнь, прочитав файл с текстовыми данными и ударными, прямо-таки стахановскими методами генерируя и развешивая на своего "папу" (потомка двигателя, так сказать, в первом поколении) плейны, меши которых меняются на меши пилонов, ракет, бомб и баков. Заодно он "наставляет на путь истинный" своего "деда", выставляя и подправляя ему вевозможные проперти вроде угловых скоростей, высотности, угла обзора радара и так далее. Такой вот сознательный товарищ. после чего исчезает.
Выглядит это примерно так:
#Открываем файл инициализации юнита       
        directClass = open(bge.logic.expandPath('//Aircraft/' + typeUnit + '/' + typeUnit + 'INI' + '.txt'),'r')
       
        #то заглядываем в файл
        for string in directClass:
             #Срез строки по маркеру |
             config = string.split('|')
             #Эта строка, с начальным символом # - комментарий и ее читать не надо
             if config[0] == '#':
                 continue
            
             #Эта строка - технические данные летательного аппарата
             elif config[0] == 'T':
                 own.parent.parent['speedMax'] = int(config[1])                  #Максимальная скорость
                 own.parent.parent['heightMax'] = int(config[2])                 #Максимальный потолок
                 own.parent.parent['speedVert'] = int(config[3])                 #Максимальная вертикальная скорость
                 own.parent.parent['angX'] = float(config[4])                    #Максимальная скорость тангажа
                 own.parent.parent['angY'] = float(config[5])                    #Максимальная скорость крена
                 own.parent.parent['angZ'] = float(config[6])                    #Максимальная скорость рыска
                 own.parent.parent['startSpeed'] = float(config[7])              #Стартовый коэффициент скорости
                 own.parent.parent['rotatDyn'] = float(config[8])                #Угловое ускорение
                 own.parent.parent['dvigDyn'] = int(config[9])                   #Динамика(приемистость) двигателя

Сам скрипт вроде и длинный и преобразования строковых величин опять же. Да, xml, наверное было бы получше, но, как сказать... Из-за тегов возрастет объем, а если учесть, что таковых текстовых данных очень много... Проще уж повозиться со скриптом в самой игре, чем подгонять друг под друга новые и новые xml, да и данные в txt четко укладываются в строчки, не занимая много места.
И самый убийственный довод - c TXT я работать умею, а с xml - нет, увы... Пока, надеюсь... мне надо было сдвинуть с места застопорившую было работу и это все-таки удалось.
Из этого способа генерации меня пока все устраивает, осталось доделать массу для подвешиваемых объектов (она у меня играет большую роль, сильно влияя на маневренность), а также продумать, каким образом надо производить отстрел ловушек и стрельбу из пушки. Для сброса бомб и пуска ракет все более-менее понятно, а вот для пушки и ЛТЦ надо придумать новый способ.
Кстати о массе. В конце концов я привел все массовые характеристики к тоннам. Вес самолета, топлива, оружия - если в кг - загромождение идет большими цифрами. А так - максимум - сотнями приходится опернировать, а не сотнями и десятками тысяч.
В общем после грубой подгонки началась более тонкая работа - шлифовка и "достраивание" для летательных аппаратов. Выясяется, какие проперти и для чего нужны, как их использовать и так далее. Постепенно надо изобретать способ формирования стартового мегасписка и уточнять, какие параметры нужны во вложенных списках.
Результат  последних дней и часов работы - МиГ-23МФ с тремя ПТБ, бортовым номером, ракетами и летчиком в кабине (заодно привел к единому стандарту кокпиты МиГ-23БН и МФ):

  

воскресенье, 17 апреля 2016 г.

Горячая пора-3. Танцы с бубном.

Начнем с цитаты. Она подходит к нынешнему положению дел.
"""– Интересная работа?
– А разве бывает неинтересная работа?
– Да, конечно… И чем же вы занимаетесь?
– Я занимаюсь структурным анализом. Но учтите, Саул, я отрешился от земного. Давайте я расскажу вам еще что-нибудь про тахоргов.
– Да нет, благодарю вас, про тахоргов не надо. Лучше расскажите, как вы работаете.
– Саул, я же сказал, что отрешился.
– Ну как же это так – отрешился? Что же, вы теперь совсем не думаете о работе?
– Наоборот. Все время думаю. Я всегда думаю о той работе, которой занят в данный момент. Сейчас я суперкарго и второй пилот – это на тот случай, если у Антона вдруг случится отложение солей. Впрочем, об этом я, кажется, уже… Так вот, мне сейчас очень хочется пойти и немножко поводить «Корабль».
– Да вы еще успеете поводить! И потом я прошу рассказать не о сущности вашей работы, а о внешней форме, так сказать… Вот вы приходите на работу. Обычные трудовые будни…
– Хорошо. Будни. Я ложусь на вычислитель и думаю.
– Ну-ну… Постойте – на вычислитель? Ну да, понимаю. Вы лингвист, и вы ложитесь на… И что же дальше?
– Час думаю. Другой думаю. Третий думаю…
– И наконец?..
– Пять часов думаю, ничего у меня не получается. Тогда я слезаю с вычислителя и ухожу.
– Куда?!
– Например, в зоопарк.
– В зоопарк? Отчего же в зоопарк?
– Так. Люблю зверей.
– А как же работа?
– Что ж работа… Прихожу на другой день и опять начинаю думать.
– И опять думаете пять часов и уходите в зоопарк?
– Нет. Обычно ночью мне в голову приходят какие-нибудь идеи, и на другой день я только додумываю. А потом сгорает вычислитель.
– Так. И вы уходите в зоопарк?
– При чем здесь зоопарк? Мы начинаем чинить вычислитель. Чиним до утра.
– Ну, а потом?
– А потом кончаются будни и начинается сплошной праздник. У всех глаза на лоб, и у всех одно на уме: вот сейчас все застопорится, и начинай думать сначала.
– Ну, ладно. Это будни. Однако же нельзя все время работать…
– Нельзя, – сказал Вадим с сожалением. – Я, например, не могу. В конце концов заходишь в тупик, и приходится развлекаться.
– Как?
– Как придется. """
А. и Б. Стругацкие "Попытка к бегству"

Дорого бы я дал за такую возможность валяться на вычислителе и думать. Имеется в виду, конечно квазибиологический комп с мыслеуправлением. Глаза не напрягать, на скрипящем и кряхтящем раздолбанном кресле не сидеть...
Иногда я бываю непробиваемо тупым. Особенно, если начинаю освоение чего-нибудь нового. Потом, как обезъяна, начинаю копировать и ставить что-то уже наработанное, но не понимаю до конца, как оно работает. Потом следует "щелчок" и новая порция навыков укладывается в москХ. При этом я вполне способен вынести мозг тем, кто меня наставляет на путь истинный. Те, кто читает эти строки, наверняка поймут, о чем речь...
В прошлом посте я выложил куски кода по стартовой загрузке семейства МиГ-23/27. Осталось дело за малым - научиться не только генерить объекты, но и менять им меши. После серии брани со стороны консоли об отсутствующих мешах и неправильных путях и опечатках, наконец свершилось страшное. Стали генериться и появляться подвесные баки. Повернутые на 90 градусов. Долго мне еще будут икаться "проклятые Блендером меши". При импорте файла в формате обж внешне все выглядит благопристойно, но нельзя забывать, что в графе "поворот по Х" стоит 90 градусов. То же самое случилось с пилонами. Исправил. Баки есть, бомб и остального нет. Опять начал танцевать с бубном. Принтом вывожу список потомков. Есть. Пути к мешам (блендам)? Правильно, все на месте. Где оружие?! Принт в файл контроля юнита на игровой сцене. Что за хрень? Только баки! открываю скрип генерации объектов в "самолетном файле". Диагноз серьезен, прогноз печален. Припаренчивание мешей ракет и бомб идет к самому генератору, который исчезает, выполнив свою миссию. а надо цеплять к родителю генератора - фюзеляжу. Добавляю .parent к self. Открываю игру, запускаю. ура! Все на месте. Но... А где левый блок с НАР? Ну да, конечно, там парент не проставлен... Исправил. Снова запуск и я вижу МиГ-23БН в полном обвесе - три ПТБ, по паре Б-8, ОФАБ-20 и ФАБ-100. Слава Высокому Небу!
Вообще-то я рассчитывал генератор объектов сделать единым в игровой сцене, но при вызове класса там встречаются свои нюансы - имя класса надо формировать с помощью модуля sys. А кроме этого, есть еще функция самого класса. Вчерашний вечер был убит на попытки изощриться и сделать подобное. Заодно чуть не был сведен с ума мой добровольный помощник (да и я сам чувствовал себя не очень ... комфортно). В итоге пока сделал загрузку оружия старым способом через генератор в самом самолетном файле. Есть у меня подозрения, где я мог лопухнуться, но пока еще не проверял. может и не лопухнулся, а просто честно ломился в открытую дверь (так уже бывало - смотрим посты по разметке квадратов ландшафта).
Ну а пока что имеем  полный обвес, и способ генерации, по-видимому, будет изменен еще раз. Путем загрузки данных из тестового фала со всеми координатами, поворотами, массой, лобовым сопротивлением... вот так вот рождаются и мгновенно устаревают файлы. Результат этого устаревшего файла:

суббота, 16 апреля 2016 г.

Горячая пора - 2. Записки бюрократа.

Пару дней назад сдуру удалил файл МиГ-23БН. Теперь вот думаю, а может не сдуру. Как сказал Диего Марадона, забив мяч англичанам рукой: "Мою руку направлял сам Бог". Учитывая, что совсем недавно перед этим матчем Аргентина огребла от британцев на фолклендских, то бишь Мальвинских островах, кое-какие основания для этих слов у него были (обида аргентинцев не прошла с тех пор). Ну, может быть, мою руку направляла Высокое Небо (читаем Валентинова). В том файле содержался начатый мною стартовый класс для семейства МиГ-23 и МиГ-27. Обычно я всегда проверяю содержимое корзины перед удалением, но тут почему-то не стал. Может, к лучшему.
Позавчера я этот файл восстановил, вчера написал класс FLG_, то бишь FLOGGER_, в котором помимо расстановки вооружения, указал конкретные технические характеристики для разных модификаций. Какие-то модификации почти не отличаются, какие-то отличаются сильно. я бы не сказал, что файл полностью закончен, потому что в нем пока отсутствуют характеристики БРЭО, вроде дальности действия радара, его угла обзора, времени сканирования и пр.
Тем не менее, прописывание всего этого заняло весь день, потому что везде надо было менять own на self, прописывать другие имена и тому подобное. В несколько приемов я с этим справился. Та же участь ждет остальные модули первой версии для МиГ-29, Су-25, F-15, F-16 и F-5.  Про модули для новых машин я не говорю, потому что добавляться они будут с новыми машинами. вообще же класс FLG_ выглядит примерно так:
стартовые характеристики:
class FLG_(bge.types.KX_GameObject):   
    def __init__(self, old_owner):
        if self.parent.parent['unitName'] in ['MiG-23MF','MiG-23M']:
           
            #Если этот юнит управляется игроком, то выставляем камеру пилота в кабине в нужную позицию
            if.self.parent.parent['bot'] == 0:
                Gor = scene.objects["Gor"]
                Gor.localPosition = [0.0, 3.0, 0.56]
           
            if 'PilotObj' not in bge.logic.globalDict['listLoadObj']:
                #Вызов и установка фигуры пилота
                bge.logic.LibLoad('//Aircraft/PilotObj.blend', 'Scene', load_actions = False)
                bge.logic.globalDict['listLoadObj'].append('PilotObj')
           
            pilot = scene.addObject('PilotRus', self.parent)
            pilot.setParent(self.parent, False, False)
            pilot.localPosition = [0.0, 2.85, 0.25]
           
            #Пушка ГШ-6-30 для МиГ-27
            if 'MiG-27' in self.parent.parent['unitName']:
                pushka = scene.addObject('UniversalMesh', self.parent) 
                pushka['meshes'] = 'GSh630'     
                pushka.setParent(self.parent, False, False)
                pushka.localPosition = [0.0,1.4,-0.675]
           
            #Вначале выдаем ограничения по маневренности, высотности, скорости и прочим ТХ
            self.parent.parent['speedMax'] = 694 #максимальная скорость
            self.parent.parent['heightMax'] = 17500 #потолок
            self.parent.parent['MaxPower'] = 12.5 #максимальная  тяга двигателя
            self.parent.parent['speedVert'] = 220 #максимальная вертикальная скорость
            self.parent.parent['angX'] = 0.8 #максимальная угловая скорость тангажа
            self.parent.parent['angY'] = 1.3 #максимальная угловая скорость крена
            self.parent.parent['angZ'] = 0.3 #максимальная угловая скорость рыска
            self.parent.parent['rotatDyn'] = 0.1 #динамичность угловых скоростей
            self.parent.parent['dvigDyn'] = 4 #динамичность двигателя
            self.parent.parent['speedDyn'] = 5 #динамичность скорости
            self.parent.parent['startSpeed'] = 1.0 #стартовый коэффициенот скорости
            self.parent.parent['maxFuelSpeed'] = 1.8 #максимальный расход топлива кг в секунду
            self.parent.parent['massFuelOwn'] = 4090 #внутренний запас топлива
            self.parent.parent['unitChassy'] = 'E_' #тип шасси
            self.parent.parent['ownECM'] = 0.1 #встроенная система РЭБ - эффективность
        elif self.parent.parent['unitName'] == 'MiG-23MS':
            #Вначале выдаем ограничения по маневренности, высотности, скорости и прочим ТХ
            self.parent.parent['speedMax'] = 694 #максимальная скорость
            self.parent.parent['heightMax'] = 17500 #потолок
            self.parent.parent['MaxPower'] = 12.5 #максимальная  тяга двигателя
            self.parent.parent['speedVert'] = 220 #максимальная вертикальная скорость
            self.parent.parent['angX'] = 0.8 #максимальная угловая скорость тангажа
            self.parent.parent['angY'] = 1.3 #максимальная угловая скорость крена
            self.parent.parent['angZ'] = 0.3 #максимальная угловая скорость рыска
            self.parent.parent['rotatDyn'] = 0.12 #динамичность угловых скоростей
            self.parent.parent['dvigDyn'] = 4 #динамичность двигателя
            self.parent.parent['speedDyn'] = 5 #динамичность скорости
            self.parent.parent['startSpeed'] = 1.0 #стартовый коэффициенот скорости
            self.parent.parent['maxFuelSpeed'] = 1.8 #максимальный расход топлива кг в секунду
            self.parent.parent['massFuelOwn'] = 4590 #внутренний запас топлива
            self.parent.parent['unitChassy'] = 'E_' #тип шасси
            self.parent.parent['ownECM'] = 0.05 #встроенная система РЭБ - эффективность
        elif self.parent.parent['unitName'] == 'MiG-23BN':
            #Вначале выдаем ограничения по маневренности, высотности, скорости и прочим ТХ
            self.parent.parent['speedMax'] = 694 #максимальная скорость
            self.parent.parent['heightMax'] = 18500 #потолок
            self.parent.parent['MaxPower'] = 12.5 #максимальная  тяга двигателя
            self.parent.parent['speedVert'] = 220 #максимальная вертикальная скорость
            self.parent.parent['angX'] = 0.8 #максимальная угловая скорость тангажа
            self.parent.parent['angY'] = 1.3 #максимальная угловая скорость крена
            self.parent.parent['angZ'] = 0.3 #максимальная угловая скорость рыска
            self.parent.parent['rotatDyn'] = 0.13 #динамичность угловых скоростей
            self.parent.parent['dvigDyn'] = 4 #динамичность двигателя
            self.parent.parent['speedDyn'] = 5 #динамичность скорости
            self.parent.parent['startSpeed'] = 1.0 #стартовый коэффициенот скорости
            self.parent.parent['maxFuelSpeed'] = 1.8 #максимальный расход топлива кг в секунду
            self.parent.parent['massFuelOwn'] = 4590 #внутренний запас топлива
            self.parent.parent['unitChassy'] = 'E_' #тип шасси
            self.parent.parent['ownECM'] = 0.05 #встроенная система РЭБ - эффективность

Здесь отнюдь не все модификации - а то слишком много места уйдет. А теперь кусочек кода по вооружению:

#Генерация вооружения
            if self.point9 != 'pusto':
                #Добавление топливных баков
                if self.point0 in ['FuelTank-1','FuelTank-3']:
                    ptbCnt = scene.addObject('UniversalMesh', self)
                    ptbCnt['meshes'] = 'FLG_FuelTank_Center_'
                    ptbCnt['fuel'] = 800.0
                    ptbCnt.setParent(self.parent, False, False)
                    ptbCnt.localPosition = [0.0,-1.13,-1.04]
                if self.point0 in ['FuelTank-2','FuelTank-3']:
                    #Левый подвесной бак
                    ptbL = scene.addObject('UniversalMesh', self)
                    ptbL['meshes'] = 'FLG_FuelTank_Wing_'
                    ptbL['fuel'] = 800.0
                    ptbL.setParent(self.parent, False, False)
                    ptbL.localPosition = [-2.67,-1.76,-0.1]
                    #Правый подвесной бак
                    ptbR = scene.addObject('UniversalMesh', self)
                    ptbR['meshes'] = 'FLG_FuelTank_Wing_'
                    ptbR['fuel'] = 800.0
                    ptbR.setParent(self.parent, False, False)
                    ptbR.localPosition = [2.67,-1.76,-0.1]
           
            #Генерация вооружения
            if self.point1 != 'pusto':
               
                #Добавление оружия
                #Ракеты средней дальности для МиГ-23
                if self.point1 in ['R-23R+R-23T','R-24R+R-24T','R-24RM+R-24T','R-24R','R-23R','R-24RM','R-24T','R-23T']:
                    #Пилон стандартный для всех вариантов
                    pilon1 = scene.addObject('UniversalMesh', self)
                    pilon1.setParent(own, False, False)
                    pilon1['meshes'] = 'FLG_APU23_'
                    #Ракет две штуки всегда, расположение - одинаковое
                    weaponMesh1newObject1 = scene.addObject('UniversalMesh', self)       
                    weaponMesh1newObject1.setParent(self, False, False)
                    weaponMesh1newObject2 = scene.addObject('UniversalMesh', self)       
                    weaponMesh1newObject2.setParent(self, False, False)
                    weaponMesh1newObject1.localPosition = [-1.428,-2.0,0.03]
                    weaponMesh1newObject1.applyRotation([-0.035,0.0,0.0],True)
                    weaponMesh1newObject2.localPosition = [1.428,-2.0,0.03]
                    weaponMesh1newObject2.applyRotation([-0.035,0.0,0.0],True)
                   
                    if self.point1 in ['R-24R','R-23R','R-24RM','R-24T','R-23T']:
                        #Для первой ракеты значение проперти и меша по-любому стандартны
                        weaponMesh1newObject1['weapon'] = 1
                        weaponMesh1newObject1['meshes'] = self.point1
                        #При симметричной подвеске нет вопросов и по второй ракете
                        weaponMesh1newObject2['weapon'] = 1
                        weaponMesh1newObject2['meshes'] = self.point1
                       
                    #Смешанная подвеска   
                    elif self.point1 == 'R-23R+R-23T':
                        #Для первой ракеты значение проперти и меша по-любому стандартны
                        weaponMesh1newObject1['weapon'] = 1
                        weaponMesh1newObject1['meshes'] = 'R-23R'
                        #При смешанной подвеске вторая ракета получает другие значения проперти и меша
                        weaponMesh1newObject2['weapon'] = 3
                        weaponMesh1newObject2['meshes'] = 'R-23T'
                    elif self.point1 == 'R-24R+R-24T':
                        #Для первой ракеты значение проперти и меша по-любому стандартны
                        weaponMesh1newObject1['weapon'] = 1
                        weaponMesh1newObject1['meshes'] = 'R-24R'
                        #При смешанной подвеске вторая ракета получает другие значения проперти и меша
                        weaponMesh1newObject2['weapon'] = 3
                        weaponMesh1newObject2['meshes'] = 'R-24T'
                    elif self.point1 == 'R-24RM+R-24T':
                        #Для первой ракеты значение проперти и меша по-любому стандартны
                        weaponMesh1newObject1['weapon'] = 1
                        weaponMesh1newObject1['meshes'] = 'R-24RM'
                        #При смешанной подвеске вторая ракета получает другие значения проперти и меша
                        weaponMesh1newObject2['weapon'] = 3
                        weaponMesh1newObject2['meshes'] = 'R-24T'
       
       
                #Ракеты Р-3Р, Р-3С, Р-13М и Р-13М1      
                elif self.point1 in ['R-3R','R-3S','R-13M','R-13M1']:
                    weaponMesh1newObject1 = scene.addObject('UniversalMesh', self)       
                    weaponMesh1newObject1.setParent(self, False, False)
                    weaponMesh1newObject1['weapon'] = 1
                    weaponMesh1newObject1['meshes'] = self.point1
                    weaponMesh1newObject2 = scene.addObject('UniversalMesh', self)       
                    weaponMesh1newObject2.setParent(self, False, False)
                    weaponMesh1newObject2['weapon'] = 1
                    weaponMesh1newObject2['meshes'] = self.point1
                    #Это расположение ракет на пилонах МиГ-23
                    if 'MiG-23' in self.parent.parent['unitName']:
                        weaponMesh1newObject1.localPosition = [-1.428,-1.57,0.027]
                        weaponMesh1newObject1.applyRotation([-0.0175,0.0,0.0],True)
                        weaponMesh1newObject2.localPosition = [1.428,-1.57,0.027]
                        weaponMesh1newObject2.applyRotation([-0.0175,0.0,0.0],True)
                        pilon1 = scene.addObject('UniversalMesh', self)
                        pilon1.setParent(self, False, False)
                        pilon1['meshes'] = 'FLG_APU13W'
                    #Расположение ракет на МиГ-27 чуть отличается плюс другой пилон   
                    elif 'MiG-27' in self.parent.parent['unitName']:
                        weaponMesh1newObject1.localPosition = [-1.428,-1.57,-0.02]
                        weaponMesh1newObject1.applyRotation([-0.0175,0.0,0.0],True)
                        weaponMesh1newObject2.localPosition = [1.428,-1.57,0.02]
                        weaponMesh1newObject2.applyRotation([-0.0175,0.0,0.0],True)
                        pilon1 = scene.addObject('UniversalMesh', self)
                        pilon1.setParent(self, False, False)
                        pilon1['meshes'] = 'FLG_APU3W_'

Несколько длинновато, ну ладно, пускай на всякий случай будет.
Как видно из написанного, в обязательном порядке добавляется фигура летчика, а для МиГ-27 еще и пушка ГШ-630. Кроме того, с течением времени добавятся блоки выброса помех, контейнеры РЭБ, и другое вооружение, вроде никак не доделываемых мною УРВЗ Х-25.
Все это - одноразовая функция, исполняемая объектом Generator, с коротким временм жизни, двойной parent - это родитель его родителя (дедушка, сатло быть, хе-хе) - сам двигатель юнита. вот, значит, внучок, дедушку жизни учит... Проставляя ему свойства, прописанные в классе. Вся эта бюрократия, хотя и весьма объемна, но необходима. могу только сказать, что в том же WoE подобных перечислений на порядок больше. Хотя, может стоит брать все данные из текстовых файлов?  я просто не знаю, открытый, а потом закрытый текстовый файл загружает память или нет...
В общем, пока так обстоят дела. Картинок пока новых нет, так что остается только текст.
P.S. Сейчас видел забавное поведение вороны, прилетевшей на огород - попить ей, видите ли захотелось. Четыре ведра, одно закрытое. По очереди отпила из КАЖДОГО ОТКРЫТОГО. Видимо, думала, что в разных ведрах вода разной степени вкусности. Потом некоторое время поизучала закрытое и улетела. Видимо, решила, что там та же самая вода...

среда, 13 апреля 2016 г.

Горячая пора. Или опять "проклятые Блендером" меши.

Как-то незаметно подошло время подвешивать оружие. Пока не стреляющее. макеты, если угодно. Некоторое время пришлось потратить на то, чтобы уяснить алгоритм генерации оружия на подвесках и сами пилоны. Само оружие и пилоны, хотя и не имеют много поликов, но все же не плейны и тратить время на просчет невидимых с большого расстояния мелких объектов не хочется. Также не хотелось оставлять висящей мертвым грузом одноразовые кирпичи логики. Сначала было искушение сделать некий единый для всех генератор, но при импорте класса, насколько я понимаю, фокус с формированием имени импортируемого модуля не пройдет, во всяком случае, рисковать я не стал.
Я просто сделал объект с названием типа Generator_MiG-23BN_ в самом подгружаемом файле, поместив плейн на неактивный слой. Жить ему недолго - по окончании загрузки он удаляется. Но перед этим он добавляет и цепляет к своему родителю ("центру юнита", он же "бортовой номер")  плейн. Так называемый "универсальный меш" - и название у него такое же, только на инглиш. Заодно генератор добавляет мешу свойство weapon, если это оружие и общее для все таких объектов проперти meshes. В этом проперти указывается название меша, котороый должен проявиться при высоком уровне детализации. Заодно внес изменения в скрипт контроля состояния детализации юнита - с учетом нового имени UniversalMesh. После "подчистки" скрипта генерации от ошибок и опечаток был обруган консолью. Опять выползла та самая ошибка в мешах МиГ-23. Опять придется проводить лечение экспортом-импортом в формате obj. Вроде бы это последние 2осколки" от старого "зараженного" файла. Который, очевидно, за что-то был проклят Блендером и БГЕ.
Теперь у двигателя самолета присутствует лишь одно свойство для подвесок - pointWeapon, оно строковое и имеет вид типа: PTB-3_B-8_OFAB-250_FAB-100_. При помощи функции split('_')[индекс число]  происходит сортировка данных в проперти и мы получаем список вооружения для юнита. И вообще все подвесок. Первое значение зарезервировано  для топливных подвесных баков, далее идут уже названия подвесок вооружения на пилонах. Сами пилоны жестко прописаны в классе генерации, в самом подгружаемом бленде юнита, что исключает ошибки после отлаживания скрипта при его использовании, заодно освобождает от лишних проперти типа pilon.
Скорее всего, свойство pointWeapon я перенесу на сам генератор, а на движке самолета проперти уберу. Сам принцип пуска будет отличаться от ранее принятого. Не будет проперти pusk, команда на отсоединение и запуск нужного оружия будет будет подаваться прямо на нужный объект-потомок. Принцип формирования списков имеющегося оружия по значению класса weapon останется, этот метод себя вполне оправдал в первой версии. Информация об используемом оружии будет также передаваться на оверлейные сцены напрямую - непосредственно текстовому объекту - нет смысла держать в глобальном словаре "малоподвижные" элементы.
Заодно выяснилось, что сделанные мною зеркала не кушают много логики, если задать разрешение отрендериваемой видеотекстуре 128. Даже на 256 в принципе - терпимо - 25 процентов. При 128 - вообще 6 процентов. Так что пока зеркала в кабине оставлю в покое.
Остается дописать скрипт генерации и расстановки объектов, используя ранее написанные модули для самолетов в первой версии - это касается всех машин. Стартовые позиции и углы наклона для ракет и бомб уже давно прописаны, что сэкономит время.
В заключение - скрин МиГ-23БН с подвешенными блоками Б-8. Серый пилон подвески и стал той причиной, которая заставила ругаться консоль. Будем лечить...

воскресенье, 7 февраля 2016 г.

Тяжелый рестарт и Fuck Windows!

Долгое время не писал на тему игростроения и своего проекта. Причина была довольно банальная - серия неудач и метания с поисками. Поскольку первая версия блендер-симулятора вполне доказала свою работоспособность, но в тоже время, в силу своих изначально заложенных особенностей, она оказалась достаточно закрытой структурой, тяжело поддающейся модернизации. Окончательно заставило меня заняться второй версией невозможность, скажем так, обеспечить онлайн-версию игры. Мои знакомые и друзья прямо говорят о необходимости этой "фичи". Раз надо, значит, придется делать. Хотя я не поклонник онлайн-игр, да и со своим модемом и "отличной" связью много не наиграю, да и как-то получилось в последнее время, что игры для меня стали своего рода "мониторным учебником" - любопытно взглянуть, как выглядит эффект взрыва, облака, посмотреть на террайн там... Зачастую вполне хватает роликов на ютубе.
Примерно дня четыре назад была найдена разгадка странного поведения replaceMesh в БГЕ. При замене мешей для МиГ-23/27 консоль начинала ругаться на некорректное поведение создаваемых мешей, причем часть мешей все равно менялась, а часть не появлялась (по крайней мере, так это выглядело на экране). Повидимому, при создании исходных мешей вкралась ошибка, которая потом размножилась с отделением в самостоятельные объекты частей юнитов. Ничего удивительного (теперь), поскольку самолеты создавались очень давно в еще версии 2.6, потом переделывались в других версиях... Лечение  этого безобразия было проведено с помощью экспорта моделей в obj и последующим импортом полученных объектов обратно. Разумеется, пришлось потом переименовывать, расставлять центры объектов заново и так далее, но работа того стоила - после создания экспериментального файла со скриптом замены мешей консоль молчала, а объекты исправно менялись. И тут возникла еще одна проблема. Самолеты, как правило, состоят из множества объектов (закрылки, предкрылки, стабилизаторы, рули, фонари кабины, про шасси вообще молчу). Особенностью моего кода является то, что он завязан на использование похожих имен. Причем для замены мешей КРАЙНЕ необходимо, чтобы имена объектов и мешей совпадали полностью или частично. А теперь картина маслом: сидит перед монитором человек и лихорадочно щелкает мышью то по имени объекта в N-панели, то по имени меша в боковой панели свойств. и объектов, гм, много... Представили, да? Эпичное зрелище. Особенно , если я не дожму и промажу по клавише, а потом, при подгрузке файла и запуске процесса замены мешей консоль выразится в том смысле, что такого меша в сцене нет.  Придется опять открывать файл и искать ошибку. И устранять. Ручками, ручками... Все это надоело и я задался вопросом, нельзя ли сей процесс автоматизировать. Ответ - в Блендере все можно, надо только знать, как. В итоге подошел к вопросу создания аддона массового приведения в соответствие имен объектов и мешей, но пока ограничился запуском RunScript вручную (раньше я не понимал, зачем нужна эта кнопка в текстовом редакторе Блендера, теперь дошло, радость-то какая, можно было бы и раньше поинтересоваться).
Сам код был составлен denis8424 в ответ на мои неуклюжие попытки чего-то изобразить самому.
import bpy

scene = bpy.context.scene

for ob in scene.objects:
    if ob.layers[scene.active_layer] == True and ob.name != 'Camera':
        newName = 'prefix' + ob.name.split('.')[0]
        ob.name = newName
        ob.data.name = ob.name

В данном мини-скрипте 'prefix' - это набираемая ручками приставка к имени объекта. Все же это гораздо удобнее, чем выделять объекты по одному и менять у них имена. префикс можно разместить перед или за именем объекта или сделать несколько приставок к именам. Для объектов второй версии игры выстраивается своя архитектура имен. приведу отрывок из пишущейся параллельно документации:  

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

Структура имени исходного меша:
"сокращенное название семейства" + "сокращенное название детали"
Пример: FLM_FldL0_ - Fulcrum("FLM") + Fold("Fld") + Left("L") + 0
Означает МиГ-29, створка шасси, левая, номер ноль

Структура имени вызываемого на замену меша:
"сокращенное название семейства" + "сокращенное название детали" + "модификация юнита" + "национальность юнита"
Пример: FLM_FldL0_MiG-29A_IrAF_ - Fulcrum("FLM") + Fold("Fld") + Left("L") + 0 + MiG-29A("MiG-29A") + IrAF("IrAF")
Означает МиГ-29, створка шасси, левая, номер ноль, МиГ-29А, ВВС Ирака

В состав имени вводится разделитель "_" - для удобства

Название семейства задается заглавными латинскими буквами, и представляет собой сокращение от натовской кодировки
военной техники (примечание: для наземки можно и так - Т72, Т62, М1А и так далее).

Список сокращений

Семейства ЛА:
FSC - Fresco - МиГ-17
FAM - Farmer - МиГ-19
FLM - Fulcrum МиГ-29
FLG - Flogger МиГ-23/27
FXB - Foxbat МиГ-25
FLN - Flanker Су-27
FRF - Frogfoot - Су-25
FNR - Fencer - Су-24
FBD - Fishbed - МиГ-21
FRA - Fitter Су-7
FRB - Fitter Су-17/20/22
EGL - Eagle F-15
FFL - Fighting Falcon F-16
TMT - Tomcat F-14
TGR - Tiger F-5
PNT - Phantom F-4
VDO - Voodoo F-101
ARR - Aardwark F-111
SKW - Skyhowk A-4
SKR - Skyrider A-1
INR - Intruder A-6
TND - Thunderbolt A-10
TCF - Thunderchief F-105



Детали юнитов
Trr - Turret - башня, турель
Cnn - Canon - пушка, ствол, ПУ
Crp - Corpus - корпус
Cnp - Canopy - фонарь кабины
Arb - Airbrake - воздушный тормоз
Slt - Salaty - предкрылок
Flp - Flaps - закрылок
Fln - Flaperon - флаперон
Inp - Interceptor - интерцептор
Fus - Fuselage - фюзеляж
Wng - Wing - крыло
Cns - Consol - консоль крыла (поворотная)
Rdd - Rudder - руль направления
Fld - Fold - створка шасси
Aln - Ailieron - элерон
Elv - Elevator - руль высоты (стабилизатор)
Cck - Cockpit - кабина
Whl - Wheel - колесо

Собственно, принцип построения юнитов и их поведение в игре здесь и приведены. Добавлю только, что в связи с ненужностью в игре практически все время деталей шасси с их анимациями, они будут подгружаться лишь при выполнении взлета или ипосадка. Также для экономии ресурсов сама модель может быть анимированной детализированной (вблизи, когда можно разглядеть работу элеронов, рулей и прочей механики) и детализированной, неанимированной (по сути - один объект - вся механика объединена с фюзеляжем в один меш) - это для тех случаев, когда самолет можно рассмотреть довольно подробно, но работа его механизации практически незаметна. фактически создаются две системы детализации, третья - отдельная система - это детали шасси, она стоит особняком, когда используется - писал выше. И к этому стоит добавить "чистый" лоуполи LOD - очень грубо изготовленный меш, скорее напоминающий силуэт, который используется на больших дистанциях, где самолет выглядит либо точкой, либо черточкой или какой-то серо-черной тенью. Большаую часть времени в игре юнит проводит именно так. Или на совсем уж больших дистанциях, надобность даже в этом отпадает - хватит и треугольника.
Во второй версии создается с нуля сама архитектура игры. Она планируется более гибкой, с возможностью добавления дополнений и модов. К тому же, опять же с целью экономии ресурсов, планируется загрузка конкретных объектов, а не всего пакета вооружения, например. Зачем нужна масса ракет и бомб, если в данной миссии используется два-три типа из сотни?
Кстати, об оружии. созданный мною для первой версии пакет вооружения был проверен на замену мешей, ошибок выявлено не было, поэтому последовало его "дробление" на отдельные папки типа R-27R, R-13S, AGM-65E, AIM-120C-5  и так далее. Имя им легион - набор вооружения был резко расширен, особенно в части крылатых ракет, наших и иностранных.
Та же процедура планируется в отношении пилонов подвески вооружения для самолетов и вертолетов, контейнеров постановки помех и других "суб-объектов". Да, количество файлов возрастет весьма резко, но не составит труда легко добавить или заменить любую пеапку (если придерживаться некоторых правил, естественно, которые еще только создаются, кхе-кхе).
И вот тут началось самое интересное. Я обладаю несомненным талантом создавать проблемы на ровном месте, где их по определению, вроде не должно быть...
Для управления всей этой армадой файлов во второй версии крайне необходим алгоритм поиска файлов и путей к ним. Казалось бы, функция listdir  в модуле os - наше все. Увы... denis8424  в своем боле кратко выразился насчет "слэшей не этой системы в Винде". Я поражаюсь его терпению. Переписка была весьма оживленной. Сначала моя Винда тупо повторяла, что файлы не найдены. Разобрались - пути к файлам в Винде  с одной стороны и во всех прочих (!) с другой отличаются разными слешами - с наклоном влево (Винда, прямо левацкий уклон, троцкизм какой-то, 58-ая статья) и нормальным правым наклоном (нормальный рабочий почерк человека с наклоном вправо, встречаются, правда некоторые личности, у которых наклоны могут быть и вправо и влево - видел сам, но не будем о грустном). - это Линукс и прочие FreeBSD. После правки скрипта Винда узрела объекты для поиска и.. отказалась их идентифицировать! В ее интерепретации - это не файл, не папка и не ссылка. На вопрос, заданный мною в монитор: "А что это вообще такое?", ответа, понятное дело не последовало. неведома звершка, не иначе. Чебурашка. Fuck Windows! Проблему опять решил denis8424, з0а что я ему весьма благодарен. http://denis8424.blogspot.ru/
Фактически, на его скрипте и будет держаться вторая версия. На базе этого скрипта планирую создать инструменты обновления, меню, подгрузки объектов, защиту от ошибок... Не моделями и не графикой едиными жива игра. Хотя и они важны, не скрою.
Все это время с перерывами, пилю модели для второй версии. часть, конечно, будет взята из первой версии, но часть будет либо обновлена либо создана заново. Сегодня вот, взялся за Су-30МК. пока показывать особо нечего, там идет процесс ретопологии, сама модель не моя, пак с ними выложил человек в далеком 2003 году.  В паке, который я, по своей хомячиной природе, заначил еще пару лет назад, есть Су-27, Су-33, Су-27ИБ (ныне Су-34), расшивки на них нет, если рассматривать вблизи, то видна "покорябання2 сетка - неровная, явно со следами булевых вырезаний, полигонов гораздо больше, чем нужно, но это не брюзжание - это превосходная исодная модель для создания своих юнитов. к тому же, в отличие от того же МиГ-23, Су-17, МиГ-21 и еще многих машин, наших или иностранных, для новейших "Сушек" нет чертежей с поперечными сечениями. А без них строить модель сложнее на порядок. Но вообще, по замыслу, в игру можно будет вставить все что угодно, соблюдая простенькие правила. Так и до наземки можно добраться. или в космос слетать... Ладно, надеюсь, у читающих сей опус, хватило терпения дочитать его до конца, да и не стоит сильно предаваться мечтаниям, хотя мечтать вроде и не вредно... Да еще и прошлый пост по ирано-иракской надо доделывать - картинки искать и детали уточнять.