вторник, 22 марта 2016 г.

Немного о агрегатировании.

Набросал небольшой пример агрегатирования пользовательских классов. Всё сделано очень упрощенно, хотя все равно простыня получилась. Вешаете на дефолтный куб сенсор типа Always включенный в импульсном режиме, к нему подключаете контроллер типа Module, и в нем прописываете функцию main().

import bge
import mathutils

class engine(object):
    """
    класс двигателя, понятно, что у объекта может быть не один двигатель,
    да и изменяемый вектор тяги у каждого двигателя может быть...
    """
    
    def __init__(self, maxSpeed, master):
        # максимальная скорость объекта
        self.maxSpeed = maxSpeed
        # текущая скорость объекта
        self.currentSpeed = mathutils.Vector([0.0, 0.0, 0.0])
        # изменение скорости за раз, по идее надо вектором делать
        self.dim = 0.01
        # объект, на котором этот двигатель установлен, тот самый юнит
        self.master = master
        
    
    def update(self):
        """
        изменение скорости юнита
        """
        # вызываем функцию изменения текущей скорости
        self.speedControl()
        # изменяем положение юнита в пространстве
        self.master.worldPosition = self.master.worldPosition + self.currentSpeed

        
    def speedControl(self):
        """
        функция изменяет текущую скорость объекта используя события клавиатуры
        """
        # Всё как в документации
        keyboard = bge.logic.keyboard
        ACTIVE = bge.logic.KX_INPUT_ACTIVE
        if keyboard.events[bge.events.WKEY] == ACTIVE:
            X = self.currentSpeed[1] + self.dim
            if X < self.maxSpeed:
                self.currentSpeed[1] = X
        elif keyboard.events[bge.events.SKEY] == ACTIVE:
            X = self.currentSpeed[1] - self.dim
            if abs(X) < self.maxSpeed:
                self.currentSpeed[1] = X
        return 0
        
        
class unit(bge.types.KX_GameObject):
    """
    класс, реализующий несколько дополнительных возможностей для объекта
    наследует Гейм Обжект, поэтому имеет все присущие тому атрибуты
    """
    def __init__(self, old_owner):
        """
        функция __init__ для класса, вопроса зачем она быть не должно
        """
        # переменная, счетчик жизни,так сказать
        self.hp = 1000
        # словарь, в который записываются экземпляры агрегатированных классов
        # словарь потому что таковых классов может быть много
        self.updateDict = {}
        # вот запишем в него экземпляр класса engine, который 
        # будет отвечать за перемещения объекта
        self.updateDict['engine'] = engine(1.0, self)
        
    
    def update(self):
        """
        функция обновления состояния класса
        """
        # уменьшаем счетчик жизни на 1
        self.hp = self.hp - 1
        # посмотреть сколько еще осталось
        print(self.hp) 
        # если меньше или равно нулю,       
        if self.hp < 1:
            # то удаляем объект
            self.endObject()
        # а здесь будем изменять состояния всех встроенных объектов    
        for key in self.updateDict:
            # берем ключ из словаря и изменяем
            self.updateDict[key].update()
        

def main(cont):
    """
    Управляющая функция
    """
    # текущий владелец контроллера
    own = cont.owner
    # тип владельца
    typ = type(own)
    # если владелец все еще типа ГеймОбжект,
    if typ == bge.types.KX_GameObject:
        # то изменяем его тип в юнит, все как в документации
        old_object = own
        mutated_object = unit(own)
        assert(own is not mutated_object)
        assert(own.invalid)
        assert(mutated_object is cont.owner)
    # иначе, если владелец уже изменен,    
    elif typ == unit:
        # обновляем его состояние
        own.update()
        

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

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