воскресенье, 7 мая 2017 г.

Перестройка идет своим чередом...

Отреставрировал работу сенсоров, а также прицеливание - плвающую по индикатору лобового стекла метку цели. Сделал ее в скрипте управления игрока - туда же свалил все функции по работе кабины - не вижу смысла городить лишний код в других местах и скриптах. Для сенсоров дописал код для лазерного и радиодальномеров, плюс телевизионный прицел. Но пока не могу точно сказать, работает или нет. Цели фиксируются и селектируются, хотя пока не исправлен огрех с индексом выбора цели в списке - надо проверить длины списков. Идет возня с переписыванием ИИ. Точнее, его вычиткой - копируются блоки текста, переносятся в новый скрипт и проверяются на грамматику и синтаксис - пока на глазок, потому что ошибок старый скрипт не выдавал, но наводиться на цель боты пока не спешат. Впрочем, ошибку в сенсорном скрипте я исправил именно таким "перелопачиванием", заодно выбросив лишнее и устаревшее. Боты, тем не менее, способны уже осознанно выбирать наиболее дальнобойное оружие и включать подходящий для этого оружия сенсор.
Заодно в скрипт сенсора заложена на будущее возможность работы сразу по нескольким целям, так что надеюсь, смоделировать перехват "томагавков" звеном МиГ-31 с одновременным обстрелом с каждого МиГа 4 КР должно получиться. Но потом. Сейчас - подчистка ИИ. Вообще же у меня осталось - ИИ ботов, система СПО для самолета игрока, РЭБ с ловушками и самонаведение ракет. Скрипт самонаведения я уже переписал, но пока не будет сближения с ботами и индикации ПР, пробовать его не стоит. Звуков вот пока нет еще - ими я займусь после перечисленного.
Было также исправлено переключение камер. В общем-то работа рутинная, но временами код приходится писать заново - в классах заложено много возможностей и они меняют некоторые вещи до неузнаваемости.
Alex Hawk прислал сообщения с файлами, но обнаружил я их только вчера и сегодня опять не могу найти. Гугл, на мой взгляд, наворотил лишнего в своих приложениях, не знаю, как другие, а я в них частенько путаюсь.

вторник, 2 мая 2017 г.

Теория классовой борьбы-2. Метод мавра.

В прошлом посте я делился новообретенными знаниями о создании класса и изощрялся в раздаче данных в этом самом классе. И все бы хорошо - все работало, самолет летал, пускались ракеты, работал кокпит... Словом все было замечательно. Однако тут  при добавлении оппонентов вышла неувязочка. Сначала я к своему удивлению, обнаружил упорное нежелание модели МиГ-23МФ добавлять высокодетализированные меши. Погтом вдруг обнаружилось, что кабины нет и управления, кстати, тоже нет. И при всем этом консоль упорно выдавало отсутствие какой-либо ошибки. Еще раз вспомнив бессметрное изречение O.din13: "Боендер не тупит - тупят люди", я приступил к исследованию сего бага. В конце концов, пришлось признать, что дал маху. И весьма ощутимого. Ошибка была в том, что в БГЕ создается ОДИН класс на ВСЕ юниты типа "летательный аппарат". Но при этом его данные меняются в масштабах ВСЕЙ сцены, а не одного конкретного объекта. В итоге вместо пары МиГ-23МФ и пары Ф-16 мы получаем 4 самолета одного типа - чья сточка с данными будет прочитана последней. И это был Ф-16. Но вот добавление "основы" юнита у меня идет независимо от значения в классе, в итоге получаем Ф-16 с нормально работающей моделью и Миг-23 с ЛОД-основой, но тоже вроде как Ф-16! Прикол, ничего не скажешь...
Пришлось некоторое время поломать голову. В итоге, следуя дао дятла и с остервнением пробившись сквозь дебри своего же кода, получил работающую модель. Надо заметить, что у меня идет подключение и использование скриптов-модулей в некоем "коммутаторе". Чтобы совсем уж не ломать существующую структуру с неясным исходом, я применил старый испытанный прием - "против лома нет  приема".

Класс у меня стал простым и суровым:
import bge

class air(bge.types.KX_GameObject):
   
    def __init__(self, old_owner):
       
        self.nameIndex = str(id(self))
        self.WINGS = -1
        self.Temp_WINGS = -1
        self.FLAPS = 0
        self.Temp_FLAPS = 0
        self.SLATS = 0
        self.Temp_SLATS = 0
        self.CANOPY = 0
        self.Temp_CANOPY = 0
        self.AIRBRAKE = 0
        self.Temp_AIRBRAKE = 0
        self.CHASSY = 0
        self.Temp_CHASSY = 0
        self.ROLL = 0
        self.Temp_ROLL = 0
        self.YAW = 0
        self.Temp_YAW = 0
        self.PITCH = 0
        self.Temp_PITCH = 0
        self.ROLLwings = 0
        self.Temp_ROLLwings = 0
        self.avto = 0
        self.Temp_avto = 0
        self.PR = 0
        self.Temp_PR = 0
        self.LockOn = 0
        self.enemy = 0
        self.weapon = -1
        self.Temp_weapon = -1
        self.crash = 1.0
        self.Temp_crash = 1.0
        self.correctSpeedAngleOfAttack = 0.0
        self.levelsDetails = 3
        self.Temp_levelsDetails = 3
        self.angleOfAttack = 0.0
        self.ownType = 0
        self.sensEyesscanTimer = 300
        self.rotatX = 0.0
        self.rotatY = 0.0
        self.rotatZ = 0.0
        self.rollSelf = 0
        self.pitchSelf = 0
        self.yawSelf = 0
        self.antiForce = 0.0
        self.massFuel = 0.0
        self.massChild = 0.0
        self.massFuelTank = 0.0
        self.ownAntiForce = 0.0001
        self.lovushki = 0
        self.correctRotat = 1.0
        self.correctSpeed = 1.0
        self.slideRotat = 0.0
        self.speedTemp = 0.0
        self.typeShtopor = "NULL"
        self.Temp_BK = 0
        self.BK = 0
        self.typeSensor = 0
        self.targetType = 0
        self.timerImpulse = 0
        self.sonicBoom = 0
        self.idTarget = []
        self.PuskSbros = 0
        self.Temp_PuskSbros = 0
        self.indexRadarDist = 0
        self.timerShoot = 0
        self.classWeapon = ""
        self.nameWeapon = ""
        self.Temp_typeSensor = 0
        self.localTargetList = []
        self.threatWeapon = []
        self.sbrosInterval = 0
        self.ochered = 0
        self.Temp_ochred = 0
        self.dictWeapon = {}
       
        self.controlUnit = ""
        self.keyDict = ""
        self.bortNumber = 0
        self.target = -1
       
        self.typeMissions = ""
        self.Marshrut = []
        self.ownGroup = ""
        self.targetGroup = []
        self.escortGroup = []
        self.statusDict = {}
        self.ownBase = ""
        self.levelsSkill = 100
               
        self.THREAT = {"UnitAir":{'RL':[],'TP':[],'LD':[],'RD':[],'TV':[],'MG':[],'SN':[],'EL':[]},
                       "UnitGround":{'RL':[],'TP':[],'LD':[],'RD':[],'TV':[],'MG':[],'SN':[],'EL':[]},
                       "tnreatWeapon":[]}
       
        self.unitName = ""
        self.unitNation = ""
        self.unitModule = ""
        self.speedMax = 0.0
        self.heightMax = 0
        self.speedVert = 0
        self.startSpeed = 1.1
        self.limitRoll = 1.1
        self.limitPitch = 1.1
        self.alarmAngleOfAttack = 0.0
        self.globalRotatPitch = 0.005
        self.speedStall = 0.0
        self.angX = 0.0
        self.angY = 0.0
        self.angZ = 0.0
        self.rotatDyn = 0.0
        self.dvigDyn = 1
        self.MaxPower = 0.0
        self.maxFuelSpeed = 0.0
        self.massFuelOwn = 0.0
        self.massOwn = 0.0
        self.antiECM = 0.0
        self.stealth = 0.7
        self.maxVisibleDist = 0
        self.ownECM = 0.0
        self.lovushki = 0
        self.Temp_lovushki = 0
        self.sensorList = ["Eyes"]
        self.WINGS = -1
        self.Temp_WINGS = -1
        self.dvig = 0
        self.dvigRight = 0
        self.dvigLeft = 0
        self.Temp_dvig = 0
        self.Temp_dvigRight = 0
        self.Temp_dvigLeft = 0
        
        self.etalonDvig = 0
        self.typeManeur = ""
        self.bot = 0           
             
      
def mutate(cont):
    air(cont.owner)

В нем происходит появление всех атрибутов с исходными значениями. Сообсветственно, все юниты при рождении - братья-близнецы. Потом они получают свои качества...
Повозившись с открытиями-закрытиями json, я махнул рукой и стал при появлении юнитов цеплять к ним 2репер", хотя его можно назвать и "ярлыком" (на княжение, стало быть, угу). В этом ярлыке командой типа yarlyk["startDict"]= {} я создавал стартовый словарь и ссыпал туда из json-ов данные. Не абы как, чтобы потом можно было разобраться. В итоге юнит уже имел потомка при появлении, а впотомке было записано все, что нужно. Мне пришлось ввести еще пару бриков для стартовой инициализации юнита - разовая операция по чтению словаря потомка приводила к появлению у объектов одного класса разного набора характеристик. Ничего сложного - просто используем setattr или __dict__.
#Сборка атрибутов юнита
def startInit():
    cont = bge.logic.getCurrentController()
    own = cont.owner
   
    for key in own.childrenRecursive["confaUnit"]["confaUnit"]["startProp"]:
        setattr(own, key, own.childrenRecursive["confaUnit"]["confaUnit"]["startProp"][key]) 
   
    setattr(ArbitrGame, own.keyDict, own.childrenRecursive["confaUnit"]["confaUnit"])
   
    with open(bge.logic.expandPath(own.childrenRecursive["confaUnit"]["confaUnit"]["unitPath"]), 'r') as directClass:
        JSONtechnic = json.load(directClass)
        for key in JSONtechnic["listPropertys"]:
            setattr(own, key, JSONtechnic["listPropertys"][key])
            #print(getattr(own, key))
   
    if own.controlUnit == "Gamer":
        gamerConfig = ["a_x","a_y","a_z","Temp_a_x","Temp_a_y","Temp_a_z"]
        for key in gamerConfig:
            setattr(own, key, 0.0)
           
        setattr(own, "timerFuel", 0)
        setattr(own, "colorHUD", 0) 
           
        sensor1 = scene.objects['SENSOR1']
        sensor2 = scene.objects['SENSOR2']
        sensor3 = scene.objects['SENSOR3']
        #Расстановка сенсоров пустышек для отслеживания ориентации в пространстве
        sensor1.setParent(own, False,False)
        sensor1.worldOrientation = own.worldOrientation
        sensor1.localPosition = [0.0, 1.0, 0.0]
        sensor2.setParent(own, False,False)
        sensor2.worldOrientation = own.worldOrientation
        sensor2.localPosition = [1.0, 0.0, 0.0]
        sensor3.setParent(own, False,False)
        sensor3.worldOrientation = own.worldOrientation
        sensor3.localPosition = [0.0, 0.0, 1.0]

        if 'Cockpit' not in bge.logic.getSceneList():
            bge.logic.addScene('Cockpit',1)
            unit = own.unitName + own.unitNation
            typeCockpit = "//Aircraft/" + unit + "/Cockpit_" + unit + "/Cockpit_" + unit + ".blend"
            bge.logic.globalDict["cockpitPath"] = typeCockpit
   
    elif own.controlUnit == "Statist":
        own.ownType = 1
   
    #Убирем более ненужный реперный объект
    own.childrenRecursive["confaUnit"].endObject()              
   
    #Обязательно заносим юнит в списки "лагерей", сортируя по ходу дела
    ArbitrGame.UNITS[1].append(own)
    ArbitrGame.UNITS[0][own.ownType][own.target-1].append(own)  
    #print(ArbitrGame.UNITS)
   
Судьба репеного объекта соответствует известному изречению:"Мавр сделал свое дело..."
Такая вот поправочка вышла.
Кстати, аналогично я поступил и с оружием. Мне только не хватало, чтобы пущенная мною Р-24Р вдруг трансформировалась в "Сайдуиндер".
Сейчас идет возня с оживлением ботов - с их ИИ и возвращению сенсоров. с сенсорами придется попотеть - во-первых, изменились некоторые названия, во-вторых, где-то скрывается ошибка, возможно, опечатка, сейчас я переписываю скрипт, заодно убирая ставшие ненужными моменты.
Удалось также отладить камеру с ее переключениями - имеется в виду внешний обзор, а также восставноить текстовую маркировку юнитов - по их названиям, лагерю и дистанции.