среда, 9 марта 2016 г.

Физика и классы.

Как-то быстро начинаешь привыкать к тому, что еще недавно было для самого себя непонятным и почти магическим. Даже если еще не до конца в этой магии разобрался.
Как справедливо заметили на ГеймДеве, у моих машин в первой версии поведение было излишне резким, дерганым. собственно, это я знал и сам, но без капитальной переделки кода первой версии исправить это было невозможно. А учитывая то, что я просто надстраивал код, дописывая функции и модули довольно-таки хаотично, переделка влекла за собой залезание в лютые дебри. Возможно, из этого что-нибудь и вышло, но сожрало бы уйму времени. Гораздо проще написать код заново, жестко "раскладывая все по полочкам", и используя все лучшее, что сумел наработать ранее.
Физика вращения (самое больное место) теперь задается через Torque, силу, вращающую юнит, заодно стал интенсивно использоваться дампинг для Rotation, что придало вращению юнита плавность и инерционность. Была мысль использовать изменение веса юнита через mass, однако после неудачной попытки я это дело пока отложил, решив воздействовать на поведение самолета через коэффициенты, учитывающие изменения массы топлива, наличия подвесок, и их лобового сопротивления. помимо прочего, сделал еще и плавное убывание-нарастание скорости при выпуске шасси, тормозов и так далее. Раньше скорость менялась практически мгновенно. Все это было достигнуто классами. Собственно, модуль движения юнита состоит из двух функций, которые вызывают и используют классы. Пока классов два - класс управления через клавиатуру и кдасс собственно движения.Выглядит это дело так:

import bge

#Функция, описывающая способ управления ЛА - вызов класса управления - игрок, бот или онлайн
def control():
    cont = bge.logic.getCurrentController()
    own = cont.owner
    scene = bge.logic.getCurrentScene()
    own = cont.owner
    sensor = cont.sensors[0]
      
    #Создание экземпляра класса и его использование
    if sensor.positive:
        if own['bot'] == 0:
            import ClassGamer
            engine = ClassGamer.control(own)
           
#Функция, описывающая полет ЛА - вращение, ускорение, торможение и прочее - физика
def flight():
    cont = bge.logic.getCurrentController()
    own = cont.owner
    scene = bge.logic.getCurrentScene()
    own = cont.owner
    sensor = cont.sensors[0]
   
    #Создание экземпляра класса и его использование
    if sensor.positive:
        if own['crash'] > 0.2:
            import ClassEngineAir
            engine = ClassEngineAir.control(own)

Сами классы  управления и движения полностью здесь я приводить не буду, поскольку это вещи довольно простые - в прошлых постах их создание было описано. "Шапка" и "окончание2 текста класса одинаковы, различие лишь в "начинке". Для описания движения используется стандартный метод расчета "потребной" скорости движения и вращения. Даже не очень сильно отличается от первой версии проекта. Различия лишь в уборке ненужных проперти, и усовершенствовании "работы" остающихся. к примеру, выкинуты проперти направления движения (значения -1, 0 и +1), выкинуты такие проперти, как sdvigkrylo, krylo, krenNapr и тому подобные. Свойство аэродинамической схемы вообще, индицирующее наличие-отсутствие крыла изменяемой стреловидности, объединилось с wing(-1 - КИС отсутствует, от нуля и больше - уже положение крыла). Предполагаю, что при изменении положения крыла ЛТХ будут меняться единоразово, вызовом данных из текстового файла. В итоге будет выброшена куча проперти, оставшихся будет, конечно, много, но до 60 штук, как было в первой версии, надеюсь, не дойдет. Кроме того, отдельными функциями будет вызываться радар, и, скорее всего, шасси. У меня как-то так сложилось, что шасси представляют собой отдельный блок анимированных деталей, который используется чрезвычайно редко. Наверное, стоит его выделить в отдельную функцию. Радар же по идее, должен во второй версии работать импульсами, включаясь через равные промежутки времени, которые для разных самолетов можно задать разными. Раньше радар работал непрерывно, хотя вроде бы и немного кушал, но если есть возможность разгрузить движок от  лишней работы, да еще и весьма существенно, почему нет? Также отдельной функцией будет, по-видимому, анимирование юнита. Вызываться оно будет при небольшом расстоянии от активной камеры, все остальное время это будут либо ЛОДы, либо единый неанимированный меш.
По поводу пейзажа и небосвода. Три года назад Мартинс Упитис выкладывал примеры своих наработок шейдеров неба, земли, воды и солнца. По каким-то причинам он последнюю версию не довел, а кушает она прилично - около 20 процентов. Поэтому от идеи использовать все и сразу я пока отказался, взяв за основу менее навороченную, но гораздо более быструу версию Упитиса, солнце,  как обычно, немного внеся "своего колорита". Солнце у меня привязано к сфере-скайбоксу,  и может совершать движение по небосводу. Во всяком случае, так задумывается. Само солнце - это лампа типа Sun, к которой я рассчитываю привязать спрайт солнца, но необходимо рассчитать изменение его размеров, так чтобы для наблюдателя они оставались постоянными. Имитации эффектов линзы, которую Упитис очень хорошо продемонстрировал в своем творее, я пока делать не буду. Надо подробно разобрать код шейдера, понять, как это все работает и постараться его реализовать. Кстати, сам Упитис ссылался на работы еще одного человека, который занимался написанием шейдеров, и вообще, прошерстив Интернет, я нашел довольно много литературы по написанию шейдеров, но пока стоят более насущные задачи - доводка физики юнита, создание оверлея и кокпита, отработка уровней детализации. Работы довольно много, идет она не слишком быстро, по причине того, что я пытаюсь зафиксировать в комментариях к коду все свои действия и максимально тщательно писать скрипты, чтобы потом не искать судорожно, вспоминая, в каком скрипте и где я разместил то или иное действие.
Во всяком случае, что-то стало получаться...

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

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