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

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

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