GKEntity и конечные автоматы

Я работаю над небольшим проектом, используя SpriteKit и GameplayKit. Я впервые использую систему сущностей/компонентов, и мне это нравится. Но теперь я нахожусь в точке, когда мне нужно отслеживать состояния моих сущностей (Создание, Нормальное, Удаление), чтобы они не взаимодействовали во время фазы их появления (которая может включать или не включать действия для анимации вещи) и этап их удаления.

До сих пор я создал EntityStateComponent, который создает экземпляр GKStateMachine с различными состояниями, и, поскольку нет необходимости в обновлениях для каждого кадра, это не так сложно. Дело в том, что это состояние больше связано с сущностью, чем с компонентом, и мне интересно, имеет ли смысл создать подкласс из GKEntity и добавить туда конечный автомат, а не в компонент.

Твои мысли?

PS: я уже создаю подклассы от GKEntity просто для удобства init(), который создает все компоненты


person BadgerBadger    schedule 05.01.2017    source источник


Ответы (1)


Вы правы, состояние связано с сущностью, а не с компонентом. Поместите конечный автомат непосредственно в сущность или создайте базовый класс сущности, от которого наследуются все ваши сущности.

class VisualEntityBase : GKEntity, VisualEntity {
    var node: SKSpriteNode!
    var stateMachine: GKStateMachine!


    // MARK: Initialization

    init(imageNamed: String, atStartPosition: CGPoint) {
        super.init()

        // Initialise Texture
        let texture = SKTexture(imageNamed: imageNamed)

        // Initialise Node
        self.node = SKSpriteNode(texture: texture, size: texture.size())
        self.node.position = atStartPosition

        // Initialise StateMachine
        self.stateMachine = GKStateMachine(states: [
            VisualEntityIdle(),
            VisualEntityPendingMove(),
            VisualEntityMoving()
        ])

        self.stateMachine.enter(VisualEntityIdle.self)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
person Mark Brownsword    schedule 05.01.2017
comment
Большое спасибо за это! Я воздерживался от добавления чего-либо в мои подклассы GKEntity, потому что это метод учебника, но в какой-то момент необходимость использовать необязательную цепочку и принудительную развертку все время казалась неправильной. И сделать покадровое обновление внутри компонента для чего-то, что связано с сущностью, в любом случае невозможно. - person BadgerBadger; 06.01.2017
comment
Эта статья мне помогла понять ECS, стоит прочитать, если вы еще не видели. - person Mark Brownsword; 06.01.2017
comment
Кроме того, демоботы Пример использует IntelligenceComponent, который содержит GKStateMachine. - person Mark Brownsword; 09.01.2017
comment
@MarkBrownsword, извините, мне кажется, что ваш приведенный выше пример (Демоботы) противоречит вашему ответу! Не могли бы вы поконкретнее на примере, почему они ставят конечный автомат в компонент? - person arunjos007; 10.12.2018