В этом посте не будет картинок. по причине довольно рутинных вещей на этих самых картинках.
После ударного труда над подключением F-16, и особенно отработки размещения бомб и ракет типа "Мейверки" на пилонах внешней подвески встал извечный вопрос. Немного похожий на извечный русский вопрос: "Что делать?" Точнее, как мне кажется, извечный вопрос игродела: "Что делать дальше?". Пара оппонентов г7отовы - Ф-15 и Ф-16. МиГ-23 и Су-25 вроде как тоже готовы. Хочешь не хочешь, а надо браться за искусственный интеллект. Для опробования смены уровней детализации хватало примитивногог рефлекса для бота - тот тупо разгонялся и пер себе по прямой, позволяя камере кружить вокруг него и выискивать недочеты. Но рано или поздно большая часть недочетов устраняется и приходится заниматься уже искусственным интеллектом.
Для начала я попробовал несколько усложнить маршевый режим. На высоте менее 65 процентов от предельной для бота в скрипте я выставил ему увеличение мощности до 900 из 1100 и прописал увеличить тангаж, но не слишком сильно, насовав в код ограничений:
def marsh():
scene = bge.logic.getCurrentScene()
cont = bge.logic.getCurrentController()
self = cont.owner
orient = self.worldOrientation[2][1]
ROLLnull(self)
if self.worldPosition[2] < self['heightMax'] * 0.65:
if orient < self['limitPitch'] * 0.3:
upPitch(self)
elif orient > self['limitPitch'] * 0.3:
#downPitch(self)
self['rotatX'] = 0.0
self['localDict']['etalonDvig'] = 400
else:
PITCHnull(self)
self['localDict']['etalonDvig'] = 900
После ряда подгонок и вылавливания мелких ошибок я с удовлетворением наблюдал на экране, как Ф-16 послушно задрал нос и полез вверх. Причем, как и хотел - не строго вертикально, а под некоторым углом.
Набрав нужную высоту, истребитель начал опускать нос и пробил звуковой барьер. Но ненадолго, - он начал постепено сбрасывать тягу до 400, как и прописано в скрипте. Сбросив тягу он полетел дальше, по горизонтали, выровнявшись по глобальным осям. Первые зачатки искусственного разума проявились...
Далее быстренько насовав ограничителей по тем функциям, где картина уже более-менее ясна, типа набора энергии, при котором надо включить форсаж, убрать тормоз и выровняться, как и в описанном выше случае, я задался вопросом применения оружия. Но прежде чем егог применять, боту еще надо выбрать6
1. Тип работы прицела - "земля" или "воздух".
2. Выбрать ВСЕ оружие, пригодное в данном случае,
3. Из всего арсенала выбрать что-то подальнобойнее.
4. Включить нужный сенсор, ибо, к примеру УРВВ Р-24Р нужна обязательная подсветка БРЛС, а вот Р-24Т абсолютно все равно, получит ли она целеуказание от БРЛС или теплопеленгатора. И подсвечивать ей цель не надо.
Выполняет все эти заумные манипуляции еще одна функция, сочиненная вчера и сегодня дополненная строчкой выбора сенсора. В принципе, все там понятно, единственно что, постороннему человеку будет сожновато понять, откуда берутся все эти многочисленные свойства-проперти. Да, их много, но пока это "черновой" вариант, в будущем можно будет как-то постепенно упрощать текст, увеличивая скорость работы игры. пока что мне важно получить вменяемый и работающий (самое главное!) вариант, от которого можно отталкиваться.Тем более, что во второй версии добавление нового проходит на порядок быстрее и легче, чем в первой (хотя не будь первой, не было бы и этой версии - опыт в одночасье не получишь). Итак смотрим скрипт, а точнее, функцию выбора оружия, сенсора и типа прицеливания.
def sensorBot(self):
listBotWeapon = [[],[],[]]
listWeaponTemp = []
#Выбор режима работы прицельных систем - воздух или земля
if self['tipMissions'] in battleAir:
self['targetType'] = 0
elif self['tipMissions'] in battleGround:
self['targetType'] = 1
for weapon in self.childrenRecursive:
if 'weapon' in weapon:
if weapon['childBK'] > 0:
#Если имеется такое проперти, то этот тип оружия -
#либо управляемые или неуправляемые ракеты или же управляемые бомбы
if 'distMax' in weapon:
#все управляемое оружие имеет приоритет по очередности использования
#заносим в сегментр 1 многомерного списка (то есть нулевой)
if 'tipGSN' in weapon:
#Кроме наличия ГСН, необходимо, чтобы режим работы прицела соответствовал
#предназначению оружия - земля или небо
if str(self['targetType']) in weapon['typeTarget']:
listBotWeapon[0].append(weapon)
#а вот ракеты НАР, блоки НАР ставим с ледующий сегмент
elif 'tipGSN' not in weapon:
listBotWeapon[1].append(weapon)
#Это - для всевозможных кассет, бомб и зажигательных баков
elif 'distMax' not in weapon:
listBotWeapon[2].append(weapon)
"""
Таким образом выстраивается оечередность использования вооружений
1. Управляемое оружие - ракеты и бомбы
2. Неуправляемые ракеты - одиночные и блоки
3. Всевозможные боеприпасы СВОБОДНОГО падения
4. Пушки и пушечные контейнеры - для них значение проперти weapon - нулевое
"""
#А далее - сортируем пог дальности действия оружия - выбираем самое дальнобойное.
for objWeaponListSegment in listBotWeapon:
#Сначала сортируем список управляемого оружия
if len(listBotWeapon[0]) > 0:
listWeaponTemp = sorted(listBotWeapon[0], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#Теперь - неуправляемые ракеты и блоки НАР
elif len(listBotWeapon[1]) > 0:
listWeaponTemp = sorted(listBotWeapon[1], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#И затем - неуправляемые боеприпасы свободногог падения
elif len(listBotWeapon[2]) > 0:
listWeaponTemp = sorted(listBotWeapon[2], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#Если вообще ничего нет, то переходим на пушки
elif len(listBotWeapon[2]) == 0:
self['weapon'] = 0
#Последний штрих - оружие-то выбрано и режим работы прицела, но надо еще и сенсор выбрать
#для сопряжения оружия, режима работы сенсора и типа самого сенсора. Есть РЛГСН,которым нужна
#только РЛС для работы, а вот целеуказание ИКГСН можно и РЛС задавать и теплопеленгатор
#использовать, так что этот момент тоже весьма важен
for sensorUnit in self['localDict']['sensList']:
if sensorUnit in listWeaponTemp[-1]['typeSensor']:
self['typeSensor'] = self['localDict']['sensList'].index(sensorUnit)
#print(self['typeSensor'], self['unitName'],self['weapon'],self['nameWeapon'])
Для облегчения понимания того, что здесь наворочено, написано много комментариев. Это освежит и собственную память. И да, надо вставлять пояснения, откуда берутся проперти типа ['localdict']['listSensor'], пготому как оно появляется при старте игры во время загрузки юнита и в другом скрипте. Ничего не поделаешь, нынешняя боевая техника - вещь сложная(хотя если делать модель персонажа, то там проперти наберется как бы не больше).
Запустив очередной тест игрового файла я дождался загрузки и нормального старта без ругани консоли (это произошло где-то с третьей попытки после отлова синтаксических ошибок), посмотрел распечатку принат в консоли. Она гласила - 1 F-16C_ 2 AIM-120C, что в переводе на человеческий означало:
1. Сенсор из списка - по номеру второй от начала, то есть 1 после нулевого. Это - БРЛС.
2. Тип бота - Ф-16Це.
3. Выбрана вторая пара подвесок.
4. Имя выбранного оружия - АИМ-120Це АМРААМ.
ЧТД.
Поскольку в легенде миссии я прописал на Ф-16 на первую пару АИМ-7, на вторую - АМРААМ, а на третью - "Сайдуиндеры". Самые дальнобойные-то и выбрались. Для них нужна работа БРЛС, и она также включилась.
Далее, необходимо обеспечить многочисленные нюансы. Разворот бота в сторону цели, корректирование его ориентации в пространстве. Очень тщательно выверить работу взаимодействия сенсоров юнитов между собой - в первую очередь. Все дело в том, что необходимо сообщать в случае работы сенсоров о совем местонахождении. Самолет, облучающий перед собой участок неба, буквально орет на весь район о своем присутствии. И наоборот - тихо (ну ладно, громко летящий) у самой земли перхватчик, включивший вместо БРЛС теплопленгатор, не насторожит оппонента, прущего где-то вверху и стороне от его курса. И противник поймет, что что-то не так только после взрыва ракеты с тепловой ГСН...
Но ботам я пока стрелять не дам. Сначала необходимо отработать списки угроз, их обновление и структуру, отработать СПО с ее истерикой - мерзким зуммером и миганием разноцветных огоньков, а уж потом дать возможность стрелять противнику.
такая вот диспозиция на сегодняшний день.
После ударного труда над подключением F-16, и особенно отработки размещения бомб и ракет типа "Мейверки" на пилонах внешней подвески встал извечный вопрос. Немного похожий на извечный русский вопрос: "Что делать?" Точнее, как мне кажется, извечный вопрос игродела: "Что делать дальше?". Пара оппонентов г7отовы - Ф-15 и Ф-16. МиГ-23 и Су-25 вроде как тоже готовы. Хочешь не хочешь, а надо браться за искусственный интеллект. Для опробования смены уровней детализации хватало примитивногог рефлекса для бота - тот тупо разгонялся и пер себе по прямой, позволяя камере кружить вокруг него и выискивать недочеты. Но рано или поздно большая часть недочетов устраняется и приходится заниматься уже искусственным интеллектом.
Для начала я попробовал несколько усложнить маршевый режим. На высоте менее 65 процентов от предельной для бота в скрипте я выставил ему увеличение мощности до 900 из 1100 и прописал увеличить тангаж, но не слишком сильно, насовав в код ограничений:
def marsh():
scene = bge.logic.getCurrentScene()
cont = bge.logic.getCurrentController()
self = cont.owner
orient = self.worldOrientation[2][1]
ROLLnull(self)
if self.worldPosition[2] < self['heightMax'] * 0.65:
if orient < self['limitPitch'] * 0.3:
upPitch(self)
elif orient > self['limitPitch'] * 0.3:
#downPitch(self)
self['rotatX'] = 0.0
self['localDict']['etalonDvig'] = 400
else:
PITCHnull(self)
self['localDict']['etalonDvig'] = 900
После ряда подгонок и вылавливания мелких ошибок я с удовлетворением наблюдал на экране, как Ф-16 послушно задрал нос и полез вверх. Причем, как и хотел - не строго вертикально, а под некоторым углом.
Набрав нужную высоту, истребитель начал опускать нос и пробил звуковой барьер. Но ненадолго, - он начал постепено сбрасывать тягу до 400, как и прописано в скрипте. Сбросив тягу он полетел дальше, по горизонтали, выровнявшись по глобальным осям. Первые зачатки искусственного разума проявились...
Далее быстренько насовав ограничителей по тем функциям, где картина уже более-менее ясна, типа набора энергии, при котором надо включить форсаж, убрать тормоз и выровняться, как и в описанном выше случае, я задался вопросом применения оружия. Но прежде чем егог применять, боту еще надо выбрать6
1. Тип работы прицела - "земля" или "воздух".
2. Выбрать ВСЕ оружие, пригодное в данном случае,
3. Из всего арсенала выбрать что-то подальнобойнее.
4. Включить нужный сенсор, ибо, к примеру УРВВ Р-24Р нужна обязательная подсветка БРЛС, а вот Р-24Т абсолютно все равно, получит ли она целеуказание от БРЛС или теплопеленгатора. И подсвечивать ей цель не надо.
Выполняет все эти заумные манипуляции еще одна функция, сочиненная вчера и сегодня дополненная строчкой выбора сенсора. В принципе, все там понятно, единственно что, постороннему человеку будет сожновато понять, откуда берутся все эти многочисленные свойства-проперти. Да, их много, но пока это "черновой" вариант, в будущем можно будет как-то постепенно упрощать текст, увеличивая скорость работы игры. пока что мне важно получить вменяемый и работающий (самое главное!) вариант, от которого можно отталкиваться.Тем более, что во второй версии добавление нового проходит на порядок быстрее и легче, чем в первой (хотя не будь первой, не было бы и этой версии - опыт в одночасье не получишь). Итак смотрим скрипт, а точнее, функцию выбора оружия, сенсора и типа прицеливания.
def sensorBot(self):
listBotWeapon = [[],[],[]]
listWeaponTemp = []
#Выбор режима работы прицельных систем - воздух или земля
if self['tipMissions'] in battleAir:
self['targetType'] = 0
elif self['tipMissions'] in battleGround:
self['targetType'] = 1
for weapon in self.childrenRecursive:
if 'weapon' in weapon:
if weapon['childBK'] > 0:
#Если имеется такое проперти, то этот тип оружия -
#либо управляемые или неуправляемые ракеты или же управляемые бомбы
if 'distMax' in weapon:
#все управляемое оружие имеет приоритет по очередности использования
#заносим в сегментр 1 многомерного списка (то есть нулевой)
if 'tipGSN' in weapon:
#Кроме наличия ГСН, необходимо, чтобы режим работы прицела соответствовал
#предназначению оружия - земля или небо
if str(self['targetType']) in weapon['typeTarget']:
listBotWeapon[0].append(weapon)
#а вот ракеты НАР, блоки НАР ставим с ледующий сегмент
elif 'tipGSN' not in weapon:
listBotWeapon[1].append(weapon)
#Это - для всевозможных кассет, бомб и зажигательных баков
elif 'distMax' not in weapon:
listBotWeapon[2].append(weapon)
"""
Таким образом выстраивается оечередность использования вооружений
1. Управляемое оружие - ракеты и бомбы
2. Неуправляемые ракеты - одиночные и блоки
3. Всевозможные боеприпасы СВОБОДНОГО падения
4. Пушки и пушечные контейнеры - для них значение проперти weapon - нулевое
"""
#А далее - сортируем пог дальности действия оружия - выбираем самое дальнобойное.
for objWeaponListSegment in listBotWeapon:
#Сначала сортируем список управляемого оружия
if len(listBotWeapon[0]) > 0:
listWeaponTemp = sorted(listBotWeapon[0], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#Теперь - неуправляемые ракеты и блоки НАР
elif len(listBotWeapon[1]) > 0:
listWeaponTemp = sorted(listBotWeapon[1], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#И затем - неуправляемые боеприпасы свободногог падения
elif len(listBotWeapon[2]) > 0:
listWeaponTemp = sorted(listBotWeapon[2], key = lambda obj:obj['distMax'])
self['weapon'] = listWeaponTemp[-1]['weapon']
#Если вообще ничего нет, то переходим на пушки
elif len(listBotWeapon[2]) == 0:
self['weapon'] = 0
#Последний штрих - оружие-то выбрано и режим работы прицела, но надо еще и сенсор выбрать
#для сопряжения оружия, режима работы сенсора и типа самого сенсора. Есть РЛГСН,которым нужна
#только РЛС для работы, а вот целеуказание ИКГСН можно и РЛС задавать и теплопеленгатор
#использовать, так что этот момент тоже весьма важен
for sensorUnit in self['localDict']['sensList']:
if sensorUnit in listWeaponTemp[-1]['typeSensor']:
self['typeSensor'] = self['localDict']['sensList'].index(sensorUnit)
#print(self['typeSensor'], self['unitName'],self['weapon'],self['nameWeapon'])
Для облегчения понимания того, что здесь наворочено, написано много комментариев. Это освежит и собственную память. И да, надо вставлять пояснения, откуда берутся проперти типа ['localdict']['listSensor'], пготому как оно появляется при старте игры во время загрузки юнита и в другом скрипте. Ничего не поделаешь, нынешняя боевая техника - вещь сложная(хотя если делать модель персонажа, то там проперти наберется как бы не больше).
Запустив очередной тест игрового файла я дождался загрузки и нормального старта без ругани консоли (это произошло где-то с третьей попытки после отлова синтаксических ошибок), посмотрел распечатку принат в консоли. Она гласила - 1 F-16C_ 2 AIM-120C, что в переводе на человеческий означало:
1. Сенсор из списка - по номеру второй от начала, то есть 1 после нулевого. Это - БРЛС.
2. Тип бота - Ф-16Це.
3. Выбрана вторая пара подвесок.
4. Имя выбранного оружия - АИМ-120Це АМРААМ.
ЧТД.
Поскольку в легенде миссии я прописал на Ф-16 на первую пару АИМ-7, на вторую - АМРААМ, а на третью - "Сайдуиндеры". Самые дальнобойные-то и выбрались. Для них нужна работа БРЛС, и она также включилась.
Далее, необходимо обеспечить многочисленные нюансы. Разворот бота в сторону цели, корректирование его ориентации в пространстве. Очень тщательно выверить работу взаимодействия сенсоров юнитов между собой - в первую очередь. Все дело в том, что необходимо сообщать в случае работы сенсоров о совем местонахождении. Самолет, облучающий перед собой участок неба, буквально орет на весь район о своем присутствии. И наоборот - тихо (ну ладно, громко летящий) у самой земли перхватчик, включивший вместо БРЛС теплопленгатор, не насторожит оппонента, прущего где-то вверху и стороне от его курса. И противник поймет, что что-то не так только после взрыва ракеты с тепловой ГСН...
Но ботам я пока стрелять не дам. Сначала необходимо отработать списки угроз, их обновление и структуру, отработать СПО с ее истерикой - мерзким зуммером и миганием разноцветных огоньков, а уж потом дать возможность стрелять противнику.
такая вот диспозиция на сегодняшний день.
Комментариев нет:
Отправить комментарий