На довольно долгое время я застрял. Хорошо так застрял, давно со мной такого не было. Причиной этому стала "размазанная" по нескольким скриптам ошибка в иде недостающих аргументов для функций. А учитывая то, что функции вызывались через try-except с перхватом исключения, и внешне все выглядело благообразно... Едиснтвенно, что выглядело безобразно- так это целераспределение для ботов. Боты считали противниками своих собратьев и не стреляли по своим только потому, что в условие пуска был заложен запрет на стрельбу по объекту с одинаковыми для бота "цветами". Это выглядело смешно, если бы не отняло у меня три недели. Правда, насчет "отняли", я погорячился. По-всякому измываясь над собственным кодом, я научился с подсказки dron-a проводить инкапсуляцию внутри кода. Кода класса, я имею в виду. Теперь, значит, кроме наследования, еще и инкапсуляция... Собственно говоря, ошибка лежала в несколько другой плоскости, но это именно тот случай, когда не было бы счасться, да несчастья помогло. Ее устранение свелось всего-начсего к тщательной проверке "шапок" модулей и наборам переменных в скобках после названий функций...
Инкапсуляция - это другое дело. Она позвоялет исключить "накладок" в поеведении объектов, "пряча" данные внутри класса от внешнего мира. Вообще-то до них все равно добраться можно, но сделать это гораздо сложнее. Основательной переделке подверглись все классы боевых самолетов, причем делалось это неоднократно, по мере выяснения свойств инкапсуляции и осознания области ее применения. Ниже приводится класс для МиГ-23БН. Мне влом его резать, проще клавишами копировать-вставить. Да и образцом в случае чего послужит.
import bge
#import UnitAir_engine
from ClassUnitAir import UnitAir
class MiG23BN_Libya_(UnitAir):
import UnitAir_engine as __UnitAir_engine
def __init__(self, old_owner):
UnitAir.__init__(self, old_owner)
__air = True
__airtype = "JET"
__dron = False
__multiengine = False
__airbrake = True
__slats = True
__flaps = True
__swingwing = True
__canopy = True
__chassy = True
__yaw = True
#Летательный аппарат
def is_AIR(self):
return self.__air
#Подтип ЛA - вертолет, самолет (реактивный или внитовой)
def is_AIRTYPE(self):
return self.__airtype
#Пилотируемый или БПЛА
def is_DRON(self):
return self.__dron
def is_FLAPS(self):
return self.__flaps
def is_SLATS(self):
return self.__slats
def is_SWINGWING(self):
return self.__swingwing
def is_AIRBRAKE(self):
return self.__airbrake
#Одно- или многодвигательный
def is_MULTIENGINE(self):
return self.__multiengine
def is_CHASSY(self):
return self.__chassy
def is_CANOPY(self):
return self.__canopy
def is_YAW(self):
return self.__yaw
#######################################
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_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_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_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_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 is_YAW_Device(self):
YAW_Device = [
["Rdd_",[-0.0018,0.0036,-0.0174],"rotat",-1],
["Rdd_",[-0.0018,0.0036,-0.0174],"rotat",1]
]
return YAW_Device
def is_POINT_YAW(self):
reper = [-25, 25]
return reper
####################################
#Наличие-отсутствие стабилизатора
def is_ROLL(self):
return True
def is_ROLL_Device(self):
ROLL_Device = [
["ElvL_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvR_",[0.0087,0.0,0.0],"rotat",-1],
["ElvL_",[-0.0087,0.0,0.0],"rotat",1],
["ElvR_",[0.0087,0.0,0.0],"rotat",1]
]
return ROLL_Device
def is_POINT_ROLL(self):
reper = [-20, 20]
if self.WINGS > 300:
reper = [-13, 13]
#print(reper)
return reper
#Наличие-отсутствие стабилизатора
def is_ROLLwings(self):
return True
def is_ROLLwings_Device(self):
ROLLwings_Device = [
["InpR_",[0.0,0.0,0.0],"rotat",0],
["InpL_",[0.0,0.0,0.0],"rotat",0]
]
if self.ROLLwings < 0 and self.rollSelf == -1:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",-1]]
elif self.ROLLwings > 0 and self.rollSelf == 1:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings < 0 and self.rollSelf == 0:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings > 0 and self.rollSelf == 0:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",-1]]
elif self.ROLLwings < 0 and self.rollSelf == 1:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings > 0 and self.rollSelf == -1:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",-1]]
#print(self.ROLLwings,self.rotatY)
return ROLLwings_Device
def is_POINT_ROLLwings(self):
reper = [-45, 45]
if 299 < self.WINGS < 549:
reper = [-30, 30]
elif self.WINGS > 549:
reper = [0, 0]
#print(reper)
return reper
####################################
#Наличие-отсутствие стабилизатора
def is_PITCH(self):
return True
def is_PITCH_Device(self):
PITCH_Device = [
["ElvL_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvR_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvL_",[-0.0087,0.0,0.0],"rotat",1],
["ElvR_",[-0.0087,0.0,0.0],"rotat",1]
]
return PITCH_Device
def is_POINT_PITCH(self):
reper = [-17, 49]
return reper
#################################################
#Методы движения, работы ЛОД и прочего
def engine(self):
self.__UnitAir_engine.engine(self)
def mutate(cont):
MiG23BN_Libya_(cont.owner)
Самая вкусная строчка почти в самом низу:
self.__UnitAir_engine.engine(self)
Символ __ означает как раз эту самую инкапсуляцию. Вызов идет изнутри самого класса и других объектов не касается. Если посмотреть на класс с методами, то там тоже можно встретить переменные вида __air. Это специфические переменные, сообщающие, например, что у МиГ-23БН один двигатель, крыло с изменяемой стреловидностью, есть тормоза, закрылки и прочее. Это чисто его внутреннее дело.
Теперь же движение объекта из логического кирпича в пусковом файле выглядит так:
ge
import json
import sys
import random
cont = bge.logic.getCurrentController()
own = cont.owner
scene = bge.logic.getCurrentScene()
import sys
pathFolder = own.unitName + own.unitNation + "/folderPy"
sys.path.append(bge.logic.expandPath("//Aircraft/" + pathFolder))
unitmodule = own.unitNode + own.unitNation + "NodeScript"
unit_module = __import__(unitmodule)
UNITCLASS = own.unitNode + own.unitNation
UNIT_CLASS = __import__(UNITCLASS)
#Импорт из папки для юнитов ЛА модклей
import UnitAir_engine
import UnitAir_LODes
import UnitAir_shoot
import CONTROL_Operations
import mathutils
import UnitGround_Sensores
import UnitGround_Artillery
import UnitGround_LODes
import Weapon
ArbitrGame = scene.objects["ArbitrGame"]
#############################################
#############################################
def UnitAir():
cont = bge.logic.getCurrentController()
own = cont.owner
#if len(own.idTarget) > 0:
# print(own.unitName, scene.objects.from_id(int(own.idTarget[0])).unitName)
if own.controlUnit != "Statist":
own.globalTargetList = ArbitrGame.UNITS[0][own.targetType][own.target]
#UnitAir_engine.engine(own, scene)
own.engine()
unit_module.correctData(own)
#Работа уровня детализации идет ВСЕГДА
UnitAir_LODes.LODes(own)
Думаю, извивы моей мысли понятны - импорттируем класс по названию - MiG-23BN_Libya_.py, а из него тащим метод движения, который, в свою очередь, дергает скрипт движения. Если посмотреть класс, то в начале можно найти строку import UnitAir_engine. Это он и есть...
Теперь подобные вещи придется делать для оружия, от греха подальше. А то вдруг нацелятся все ракеты типа Р-23Р на один "Фантом" (который еще делать надо).
Простор для инкапсуляции еще есть, но не будем пока о грустном. После отлова ошибки и доводки сриптов, наконец, боты стали вести себя правильно. А именно - разворачиваться в сторону противника, сканировать местность, сбрасывать баки, разгоняться и маневрировать, и даже стрелять... Вновь ожила СПО, заработали звуковые маркеры. Короче, жизнь стала налаживаться.
Инкапсуляция - это другое дело. Она позвоялет исключить "накладок" в поеведении объектов, "пряча" данные внутри класса от внешнего мира. Вообще-то до них все равно добраться можно, но сделать это гораздо сложнее. Основательной переделке подверглись все классы боевых самолетов, причем делалось это неоднократно, по мере выяснения свойств инкапсуляции и осознания области ее применения. Ниже приводится класс для МиГ-23БН. Мне влом его резать, проще клавишами копировать-вставить. Да и образцом в случае чего послужит.
import bge
#import UnitAir_engine
from ClassUnitAir import UnitAir
class MiG23BN_Libya_(UnitAir):
import UnitAir_engine as __UnitAir_engine
def __init__(self, old_owner):
UnitAir.__init__(self, old_owner)
__air = True
__airtype = "JET"
__dron = False
__multiengine = False
__airbrake = True
__slats = True
__flaps = True
__swingwing = True
__canopy = True
__chassy = True
__yaw = True
#Летательный аппарат
def is_AIR(self):
return self.__air
#Подтип ЛA - вертолет, самолет (реактивный или внитовой)
def is_AIRTYPE(self):
return self.__airtype
#Пилотируемый или БПЛА
def is_DRON(self):
return self.__dron
def is_FLAPS(self):
return self.__flaps
def is_SLATS(self):
return self.__slats
def is_SWINGWING(self):
return self.__swingwing
def is_AIRBRAKE(self):
return self.__airbrake
#Одно- или многодвигательный
def is_MULTIENGINE(self):
return self.__multiengine
def is_CHASSY(self):
return self.__chassy
def is_CANOPY(self):
return self.__canopy
def is_YAW(self):
return self.__yaw
#######################################
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_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_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_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_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 is_YAW_Device(self):
YAW_Device = [
["Rdd_",[-0.0018,0.0036,-0.0174],"rotat",-1],
["Rdd_",[-0.0018,0.0036,-0.0174],"rotat",1]
]
return YAW_Device
def is_POINT_YAW(self):
reper = [-25, 25]
return reper
####################################
#Наличие-отсутствие стабилизатора
def is_ROLL(self):
return True
def is_ROLL_Device(self):
ROLL_Device = [
["ElvL_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvR_",[0.0087,0.0,0.0],"rotat",-1],
["ElvL_",[-0.0087,0.0,0.0],"rotat",1],
["ElvR_",[0.0087,0.0,0.0],"rotat",1]
]
return ROLL_Device
def is_POINT_ROLL(self):
reper = [-20, 20]
if self.WINGS > 300:
reper = [-13, 13]
#print(reper)
return reper
#Наличие-отсутствие стабилизатора
def is_ROLLwings(self):
return True
def is_ROLLwings_Device(self):
ROLLwings_Device = [
["InpR_",[0.0,0.0,0.0],"rotat",0],
["InpL_",[0.0,0.0,0.0],"rotat",0]
]
if self.ROLLwings < 0 and self.rollSelf == -1:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",-1]]
elif self.ROLLwings > 0 and self.rollSelf == 1:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings < 0 and self.rollSelf == 0:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings > 0 and self.rollSelf == 0:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",-1]]
elif self.ROLLwings < 0 and self.rollSelf == 1:
ROLLwings_Device = [["InpL_",[0.0174,0.0,0.0],"rotat",1]]
elif self.ROLLwings > 0 and self.rollSelf == -1:
ROLLwings_Device = [["InpR_",[-0.0174,0.0,0.0],"rotat",-1]]
#print(self.ROLLwings,self.rotatY)
return ROLLwings_Device
def is_POINT_ROLLwings(self):
reper = [-45, 45]
if 299 < self.WINGS < 549:
reper = [-30, 30]
elif self.WINGS > 549:
reper = [0, 0]
#print(reper)
return reper
####################################
#Наличие-отсутствие стабилизатора
def is_PITCH(self):
return True
def is_PITCH_Device(self):
PITCH_Device = [
["ElvL_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvR_",[-0.0087,0.0,0.0],"rotat",-1],
["ElvL_",[-0.0087,0.0,0.0],"rotat",1],
["ElvR_",[-0.0087,0.0,0.0],"rotat",1]
]
return PITCH_Device
def is_POINT_PITCH(self):
reper = [-17, 49]
return reper
#################################################
#Методы движения, работы ЛОД и прочего
def engine(self):
self.__UnitAir_engine.engine(self)
def mutate(cont):
MiG23BN_Libya_(cont.owner)
Самая вкусная строчка почти в самом низу:
self.__UnitAir_engine.engine(self)
Символ __ означает как раз эту самую инкапсуляцию. Вызов идет изнутри самого класса и других объектов не касается. Если посмотреть на класс с методами, то там тоже можно встретить переменные вида __air. Это специфические переменные, сообщающие, например, что у МиГ-23БН один двигатель, крыло с изменяемой стреловидностью, есть тормоза, закрылки и прочее. Это чисто его внутреннее дело.
Теперь же движение объекта из логического кирпича в пусковом файле выглядит так:
ge
import json
import sys
import random
cont = bge.logic.getCurrentController()
own = cont.owner
scene = bge.logic.getCurrentScene()
import sys
pathFolder = own.unitName + own.unitNation + "/folderPy"
sys.path.append(bge.logic.expandPath("//Aircraft/" + pathFolder))
unitmodule = own.unitNode + own.unitNation + "NodeScript"
unit_module = __import__(unitmodule)
UNITCLASS = own.unitNode + own.unitNation
UNIT_CLASS = __import__(UNITCLASS)
#Импорт из папки для юнитов ЛА модклей
import UnitAir_engine
import UnitAir_LODes
import UnitAir_shoot
import CONTROL_Operations
import mathutils
import UnitGround_Sensores
import UnitGround_Artillery
import UnitGround_LODes
import Weapon
ArbitrGame = scene.objects["ArbitrGame"]
#############################################
#############################################
def UnitAir():
cont = bge.logic.getCurrentController()
own = cont.owner
#if len(own.idTarget) > 0:
# print(own.unitName, scene.objects.from_id(int(own.idTarget[0])).unitName)
if own.controlUnit != "Statist":
own.globalTargetList = ArbitrGame.UNITS[0][own.targetType][own.target]
#UnitAir_engine.engine(own, scene)
own.engine()
unit_module.correctData(own)
#Работа уровня детализации идет ВСЕГДА
UnitAir_LODes.LODes(own)
Думаю, извивы моей мысли понятны - импорттируем класс по названию - MiG-23BN_Libya_.py, а из него тащим метод движения, который, в свою очередь, дергает скрипт движения. Если посмотреть класс, то в начале можно найти строку import UnitAir_engine. Это он и есть...
Теперь подобные вещи придется делать для оружия, от греха подальше. А то вдруг нацелятся все ракеты типа Р-23Р на один "Фантом" (который еще делать надо).
Простор для инкапсуляции еще есть, но не будем пока о грустном. После отлова ошибки и доводки сриптов, наконец, боты стали вести себя правильно. А именно - разворачиваться в сторону противника, сканировать местность, сбрасывать баки, разгоняться и маневрировать, и даже стрелять... Вновь ожила СПО, заработали звуковые маркеры. Короче, жизнь стала налаживаться.
Комментариев нет:
Отправить комментарий