пятница, 20 октября 2017 г.

Опытный кролик-2. Новые методы использования классов.

В прошлом посте я писал о своих опытах с МиГ-23БН, который был моим подопытным кроликом в деле отработки новых методов использования классов.
Тогда речь шла всего-навсего о создании класса-наследника с целью "развести" и не допустить "перекрещивания" данных при создании юнитов.
однако совет dron-a по поводу использования методов в самом классе заставил меня задуматься... когда я только начинал осваивать классы, я уже, сам того не зная, писал в них методы, но не знал, как правильно их использовать. видимо, для осознания новых возможностей и способов требуется время и с "лету" схватывать я таки не способен. Но все-таки медленно, но учусь. Для начала приведу пример с использованием методов теле класса на примере класса уже очень опытного виртуального колика - многострадального МиГ-23БН.

import bge

from ClassUnitAir  import UnitAir

class MiG23BN_Libya_(UnitAir):
    def __init__(self, old_owner):
        UnitAir.__init__(self, old_owner)
    #Летательный аппарат
    def is_AIR(self):
        return True
    #Подтип ЛA - вртолет, самолет (реактивный или внитовой)
    def is_AIRTYPE(self):
        return "JET"
    #Пилотируемый или БПЛА
    def is_DRON(self):
        return False
   
    #Одно- или многодвигательный
    def is_MULTIENGINE(self):
        return False
    def is_CHASSY(self):
        return True
   
    #######################################
    def is_CANOPY(self):
        return True
    def is_CANOPY_Device(self):
        CANOPY_Device = [
                        ["Cnp_",[0.0087,0.0,0.0],"rotat"]
                        ]
        return CANOPY_Device
    def is_POINT_CANOPY(self):
        reper = [0, 114]
        return reper
    ########################################
    def is_FLAPS(self):
        return True
    def is_FLAPS_Device(self):
        FLAPS_Device = [
                        ["FlpR_",[-0.0087,0.0,0.0],"rotat"],
                        ["FlpL_",[-0.0087,0.0,0.0],"rotat"]
                        ]
        return FLAPS_Device
    def is_POINT_FLAPS(self):
        reper = [-50, 0, 100]
        return reper
   
   
    ######################################
    #Наличие-отсутствие предкрылков
    def is_SLATS(self):
        return True
    def is_SLATS_Device(self):
        SLATS_Device = [
                        ["SltR_",[-0.0087,0.0,0.0],"rotat"],
                        ["SltL_",[-0.0087,0.0,0.0],"rotat"]
                        ]
        return SLATS_Device
    def is_POINT_SLATS(self):
        reper = [0, 40]
        return reper
   
    #####################################
    #Наличие-отсутствие крыла изменяемой стреловидности
    def is_SWINGWING(self):
        return True
    def is_POINT_WINGS(self):
        reper = [0, 300, 550]
        return reper
   
    def is_WINGS_Device(self):
        WINGS_Device = [
                        ["WngR_",[0.0,0.0,-0.00174],"rotat"],
                        ["WngL_",[0.0,0.0,0.00174],"rotat"]
                        ]
        return WINGS_Device
   
    ####################################
    #Наличие-отсутствие воздушных тормозов
    def is_AIRBRAKE(self):
        return True
    def is_AIRBRAKE_Device(self):
        AIRBRAKE_Device = [
                           ["ArbUR_",[-0.00783,0.0,0.0],"rotat"],
                           ["ArbUL_",[-0.00783,0.0,0.0],"rotat"],
                           ["ArbDR_",[0.00696,0.0,0.0],"rotat"],
                           ["ArbDL_",[0.00696,0.0,0.0],"rotat"]
                          ]
        return AIRBRAKE_Device
   
    def is_POINT_AIRBRAKE(self):
        reper = [0, 100]
        return reper

             
def mutate(cont):
    MiG23BN_Libya_(cont.owner)

Смотрим на функции типа def is_чегго-то-там. Это не что иное, как некие константы - например наличие или отсутствие крыла изменяемой стреловидности, принадлежности к воздушным юнитам, но эти константы, например, могут нести такую ценную информацию, как скорость поворота крыла и его название. Первоначально я хотел ставить не многомерные списки, а словари. Однако, после многократной ругани со стороны консоли БГЕ о невозможности прочесть из функции класса метод с этим самым словарем, решил все же поставить многомерные списки. Посмотрим, мрожет потом я все-таки пойму, где ошибался и поставлю словари.
Что это дает? Это дакт возможность пока для стандартных анимаций (точнее псевдоанимаций, потому как идет просто движение деталей через скрипт) загнать их работу в единый скрипт, избавив бленды моделей от лишнего кода по тем же перемещениям КИС для МиГ-23. Экономия существенная.
Посмотрим, как это работает. Для начала команда на перекладку крыла из скрипта для игрока CONTROL_gamer.

#Смена стреловидности - для самолетов с КИС
    if keyboard.events[bge.events.QKEY] == JUST_ACTIVATED or keyboard.events[bge.events.TABKEY] == JUST_ACTIVATED:
        #Проперти wing у самолетов с КИС имеет минимальное значение 0. При смене стреловидности вызывается класс юнита
        #и проводится смена значений максимальных значений скорости и маневренности
        if own.FLAPS == 0:
            if own.Temp_WINGS == own.WINGS:
                if keyboard.events[bge.events.QKEY] == JUST_ACTIVATED:
                    if own.is_SWINGWING():
                        own.WINGS += 1

Сначала при нажатии клавиши идет проверка наличия крыла изменяемой стреловидности у данного юнита. смотрим is_SWINGWING  в коде выше.Если там стоит True, то команда проходит и начинается самое  интересное. Функция перекладки в скрипте CONTTROL_UnitAir универсальна для всех типов самолетов с КИС. Вообще всех. Такова особенность построения моделей и использования в них названий.
#Псевдоанимации крыльев
def wings(own):
    #Направоение перекладки крыла
    wings = 0
   
    #Смена стреловидности возможна лишь при убранных закрылках
    if own.WINGS > own.is_POINT_WINGS()[-1]:
        own.WINGS = own.is_POINT_WINGS()[-1]
    elif own.WINGS < 0:
        own.WINGS = 0
   
    #Выставление напрaвления перекладки и убывания-возрастания проперти
    if own.Temp_WINGS < own.WINGS:
        wings = 1
        if own.WINGS-own.Temp_WINGS == 5:
            AudioEmitter = scene.addObject('AudioEmitter', own, 220)
            AudioEmitter.setParent(own, False, False)
            AudioEmitter["audioProp"] = "FLAPS"
           
        own.WINGS += 1
   
    elif own.Temp_WINGS > own.WINGS:
        wings = -1
        own.WINGS -= 1
        if own.WINGS-own.Temp_WINGS == -5:
            AudioEmitter = scene.addObject('AudioEmitter', own, 220)
            AudioEmitter.setParent(own, False, False)
            AudioEmitter["audioProp"] = "FLAPS"
       
    #Собственно, движение крыльев - это действие не зависит от уровня детализации
    for key in own.is_WINGS_Device():
        if key[2] == "rotat":
            own.childrenRecursive[key[0]].applyRotation([key[1][0]*wings,
                                                         key[1][1]*wings,
                                                         key[1][2]*wings
                                                         ],True)
   
    #Остановка псевдоанимации на кадрах со значением 0,300,550   
    if own.WINGS in own.is_POINT_WINGS():
        own.Temp_WINGS = own.WINGS

Здесь используются данные о реперных точках положения крыла - там , где должна прекратиться анимация и жестко выставлены ограничения слева и справа. Это is_POINT_WINGS.  А еще используются данные из многомерного списка. я думаю, понятно, как - название детали, скорость поворота, флаг - "поворот".

Остается добавить, что подобные вещи можно проделать с фонарями кабин, щитками тормозов, закрылками и предкрылками. Потому что все это вещи стандартные и неизменяемые. Они либо есть, либо их нет.полагаю, что можно в общем-то все данные по всем деталям загнать в класс и их использовать. Но пока ограничился вышеперчисленным.
Наверняка, в класс можно вогнать и данные по сенсорам, встроенным пушкам, отстреливаемым ловушкам и прочему. Это дело будущего. По идее, все это приведет к сокращению кода. И упрощению кода тоже.

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

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