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

Опытный кролик и наследство. Классы и новый (небольшой) погром.

Наконец, я добрался до файлов Упитиса и честнго прочитал их. И даже сумел кое-что понять. Но все это касалось скрипта lum.py, а еще надо было разбираться с другими скриптами - для неба и земли, воды и еще мелочью вроде шумов и тп.
Но тут застарелая проблема все-таки выползла наружу и заявила о себе в полный голос.
Да, я вроде как научился создавать экземпляры классов и более-менее вменяемо могу ответить, зачем - для придания игровым объектам свойств, с помощью которых они реагируют на события. В более широком смысле - создания больших групп объектов, со своими схожими атрибутами (вроде полета) и своими ТТХ (скорость, потолок).
Закавыка, однако, заключалась в том, что класс один на все самолеты и вертолеты, артиллерию, танки и так далее. Юниты отличаются лишь своими ТТХ внутри группы.
Видимо, ручки у меня все же не совсем прямые, потому что время от времени происходило странное "перекрещивание". Например ф-15 у себя искал детали МиГ-29, если верить распечатке консоли. Причем этот прикол начинался после внесения изменений и сохранения пускового файла. Стало ясно, что с этим надо что-то делатью Окончательно мое терпение лопнуло после того, как в миссии с МиГ-23 и Ф-16 "двадцатьтретий" отказался менять стреловидность, а его атрибут WINGS стал равен минус 1, как у Ф-16, хотя в json прописан ноль.
И решил я попробовать наследование классов. Спасибо подсказкам dron-a, вроде получилось.
Для начала я создал еще один json и вынес его в папку с самолетами - это был общий файл для всех летательных аппратов. Приводить я его не буду, нет смысла - нудное перечисление через запятую ключей и их нулевых значений. Но все это привело к резкому сокращению скрипта класса ЛА. За счет выкидывания из него этих ключей - идет чтение json.

import bge
import json

with open(bge.logic.expandPath('//Aircraft/AIRCRAFT_CLASS.json'), 'r') as directAircraft:
    JSONaircraft = json.load(directAircraft)

class UnitAir(bge.types.KX_GameObject):
   
    def __init__(self, old_owner):
        self.__dict__.update(JSONaircraft)
               
def mutate(cont):
    UnitAir(cont.owner)

Этот скрипт висит в пусковом файле и выдает создание класса для ЛА. А запускает его функция из другого скрипта, в том же бленде.

def UnitAir(cont):
    own = cont.owner
    nameGeneral = own.childrenRecursive["confaUnit"]["confaUnit"]["unitClass"]
    #unit_module = importlib.import_module(nameGeneral)
    unit_module = __import__(nameGeneral)
    unit_class = getattr(unit_module, nameGeneral)
    x = unit_class(own)

Тут была возня с поиском и импортом нужного скрипта класса-наследника из другого бленда (который загружается при запуске игры - файл модели). К моему удивлению импортлиб скрипт не нашел. А вот поставленная из любопытства строчка с __impot__ом помогла. В скрипте ищется файл с именем класса, который прописан в объекте-потомке confaUnit. Этот объект своеобразный пакет в командирском сейфе - в случае начала БД его вскрывают и читают, что надо делать. Потом уничтожают.
В качестве подопытного кролика был выбран МиГ-23БН. Но это скорее уже опытный кролик - сколько на нем всего опробовалось... Скрипт класса-наследника выглядит так:

import bge

from ClassUnitAir  import UnitAir

class MiG23BN_Libya_(UnitAir):
   def __init__(self, old_owner):
      UnitAir.__init__(self, old_owner)
      #self.__dict__.update(JSONaircraft)
               
def mutate(cont):
    MiG23BN_Libya_(cont.owner)

Скрипт содержится в стороннем файле и надо обязательно вызвать сначала класс-родитель - ClassUnitAir. Точнее скрипт, а из него выдернуть сам класс - UnitAir.
Схема эта сработала и я кинулся вносить строчки с названием класса в json. После чего опробовал МиГ-23МФ и Ф-16. На сей раз никто не искал несуществующие детали и механика работала нормально.
А теперь вот мыслю, пока припрятать наследование класса для дальнейшего использования. А классы наследники сделать самостоятельными. для этого надо слегка поменять аргументы в скриптах и ввести чтение json. Поскольку на мой взгляд, наследование здесь не имеет пока особого смысла. Но оно может пригодиться в других местах и полученный опыт никогда не бвает бесполезным.
Да и попробую резко сократить файл вызова и старта самого класса, если их можно отыскивать и грузить по именам.

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

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