понедельник, 30 мая 2016 г.

Поход за консенсусом.

Только что удалось отработать генерацию юнитов на сцене путем чтения файла миссии. Во многом вторая версия своим появлением обязана крайне неудачно выбранному способу создания миссии в первой. Как таковая, миссия создавалась в виде отдельной функции со своим уникальным названием и при старте БГЕ приходилось открывать модуль миссий, а затем построчно читать данные для каждого юнита, генеря их, расставляя и раздавая им потомков и нужные проперти.
Во второй версии все это достигается чтением текстового файла в папке Scenery. Разумеется, от генерации, расстановки и прочего для юнитов не обойтись, но данные теперь не повисают в памяти, к тому же становится на порядок легче добавлять новые миссии и кампании. Пока правда, есть одна загвоздка. Необходимо в меню при щелчках по кнопкам, собирать данные в некую структуру и затем полдученную строчку загонять в файл. Задача решаемая, только несколько занудная - необходимо четко соблюсти порядок записи новых данных, отвечающий вырабатываемым стандартам. Так что если угодно, нужен консенсус (согласие) между меню и игровой сценой. Чем и занимаюсь - сближением позиций заинтересованных сторон, так сказать...
А пока пришло время для красивой картинки - тест на чтение текстового файла (точнее файлов, ибо теперь все проперти и потомки с скоординатами и ориентацией раздаются юнитам сразу после появления, что позволило выбросить лишнюю функцию и убрать лишний объект-потомок, который эту функцию и исполнял). Вместо полусотни сточек кода на эти четыре объекта были потрачены 4 строчки в текстовом файле, плюс некоторое количество строчек для его открытия, чтения и закрытия. В любом случае, дело это окупится.
На скотне ниже - звено ливийских МиГ-23МФ с единообразными подвесками - три ПТБ плюс по паре Р-23Р и Р-60.

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

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

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

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

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

И снова бюрократия...

Без бюрократии никак. "Социализм - это учет" (с). Зачастую начинается процесс поисков и принятия стандартов и решений как в известной сказочек- "пойди туда, не знаю куда и принеси то, не знаю что". В принципее-то, понятно, что нужно, так сказать в глобальном смысле, но вот когда переходишь от общего к частному, вдруг оказывается, что мелочей многог и путей для них как бы не больше.
Аварийный сброс подвесок, сброс топливных баков и выборочный сброс подвесок был осовне и оказался он не таким уж сложным. Кроме того, наконец дошли руки до вычисления лобовогог сопротивления всех внешних потомков и учета влияния их веса. Также в зачаточном состоянии находится реализация столкновения с землей (вот тут придется лезть в ландшафт и присваивать всем его блокам проперти "земля", хотя надо поглядеть, может и на материал реакцию сенсора лучше поставить). Во всяком случае, при проверке поведения самолета после освобождения от подвесок выяснилось, что становится он куда как более разворотливым и пропечатывание принтом величины лобового сопротивления и веса потомков дало положительный результат - поправки вводятся и учитываются. Это, конечно, не аэродинамика, но что-то поближе к ней. Можно вконец обнаглеть и ввести учет по весу расходуемых снарядов виз БК пушек и блоков НАР...
Теперь начинается самое любопытное - обеспечение стрельбы. Как пушками, так и ракетами. Для начала управляемого оружия не будет - точнее данные по его параметрам введены-то будут, но их использование начнется после отработки пусков и сбросов "болванок". Потому что в этой версии управляемое оружие существенно усложнится.
Во-первых, набор оружия сильно возрастет. Это не будеут лишь УРВВ (с РГСН и ТГСН) и УРВП, а также бомбы (обычные и корректируемые) и блоки с НАР.
Во-вторых, параметров для тех же УРВВ станет гораздо больше. К примеру, вводятся ограничения по высоте применения (верхняя и нижняя границы), ограничения по превышению-принижению цели (теперь уже не стрельнешь снизу вверх на 15 км или наоборот),  также будет учитываться ракурс пуска - в переднюю или заднюю полусферу (тут надо хорошенько продумать - известно, что дистанция разрешения пуска в ЗПС меньше раза в 2-3, чем если бы пуск был в переднюю полусферу).
В-третьих широко будет применяться противодействие, причем помехи будут куда как разнообразнее. Кроме тепловых ловушек и диполей со встроенной РЭБ, влияющей на скорость наведения, будут применяться "уводящие" помехи, "подменные" помехи (ракете средства РЭБ смогут "подменить" индекс цели для ее РГСН), также "ослепляющие2 помехи для тепловых ГСН, наподобие "Витебска" или древней "Липы" (по слухам, исходящим из Сирии, экипажи вертолетов, на которых установлен "Витебск", могут не обращать внимания на почти все ПЗРК, кроме самых современных, а вот "Липа" гарантий в той же Чечне не давала против даже стареньких "Стрел"). Плюс дымовые помехи - например для дымовых гранат БТТ, сбивающих наводку УР с лазерной ГСН. В общем, много чего.
Пока что пишется очередной файл формата txt, в который и запихиваются все эти данные. Судя по всему, для каждого вида вооружения будет работать свой класс, который опять же придется писать отдельно. правда, в этом есть и свой плюс - можно не отвлекаться на строчки, относящиеся к другому типу оружия (как это было в первой версии, где я слишком сильно старался все объединить и создать что-то универсальное).
В этот раз картинок не будет и вообще процесс сейчас стал очень небыстрым. По не зависящим от меня обстоятельствам и из-за совершенно взбесившейся погоды с ее грозами много поработать за компом не удается... Да и частенько весь процесс игростроения сводится к высчитыванию на бумаге тех или иных вариантов. 

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