Компонент сущности в Swift
Я пытаюсь создать простую игру для iOS с использованием архитектуры сущностей и компонентов, аналогичной описанной здесь.
Чего я хотел бы добиться в своей игре, так это когда пользователь касается экрана, определяет, где произошло касание, и перемещает все объекты одного типа в определенном направлении (направление зависит от того, где пользователь коснулся, справа от экрана = вверх, слева от экран = вниз).
Пока что игра очень простая, и я только начинаю, но я застрял в этой простой функциональности:
Моя проблема в том, что SKAction
должен запускаться на всех объектах типа, но происходит вообще.
До того, как я перестроил свою игру на подход ECS, это работало нормально.
Здесь GKEntity
подкласс, который я объявил в Lines.swift:
class Lines: GKEntity {
override init() {
super.init()
let LineSprite = SpriteComponent(color: UIColor.white, size: CGSize(width: 10.0, height: 300))
addComponent(LineSprite)
// Set physics body
if let sprite = component(ofType: SpriteComponent.self)?.node {
sprite.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: sprite.size.width, height: sprite.size.height))
sprite.physicsBody?.isDynamic = false
sprite.physicsBody?.restitution = 1.0
sprite.physicsBody?.friction = 0.0
sprite.physicsBody?.linearDamping = 0.0
sprite.physicsBody?.angularDamping = 0.0
sprite.physicsBody?.mass = 0.00
sprite.physicsBody?.affectedByGravity = false
sprite.physicsBody?.usesPreciseCollisionDetection = true
sprite.physicsBody?.categoryBitMask = 0b1
sprite.zPosition = 10
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
В TouchesBegan
Я вызываю функцию Move(XAxisPoint: t.location(in: self))
который объявлен в GameScene
и вот что Move()
делает:
///Determines direction of movement based on touch location, calls MoveUpOrDown for movement
func move(XAxisPoint: CGPoint){
let Direction: SKAction
let Key: String
if XAxisPoint.x >= 0 {
Direction = SKAction.moveBy(x: 0, y: 3, duration: 0.01)
Key = "MovingUp"
} else {
Direction = SKAction.moveBy(x: 0, y: -3, duration: 0.01)
Key = "MovingDown"
}
moveUpOrDown(ActionDirection: Direction, ActionKey: Key)
}
///Moves sprite on touch
func moveUpOrDown(ActionDirection: SKAction, ActionKey: String) {
let Line = Lines()
if let sprite = Line.component(ofType: SpriteComponent.self)?.node {
if sprite.action(forKey: ActionKey) == nil {
stopMoving()
let repeatAction = SKAction.repeatForever(ActionDirection)
sprite.run(repeatAction, withKey: ActionKey)
}
}
}
///Stops movement
func stopMoving() {
let Line = Lines()
if let sprite = Line.component(ofType: SpriteComponent.self)?.node {
sprite.removeAllActions()
}
}
Я предполагаю, что есть некоторая проблема с этой строкой кода Line.component(ofType: SpriteComponent.self)?.node
но компилятор не выдает никаких ошибок, и я не уверен, где моя ошибка.
Любая помощь / руководство будет с благодарностью!
1 ответ
Вопрос заключается в следующей строке MoveUpOrDown
а также StopMoving
let Line = Lines()
Это создает новый Lines
объект затем говорит ему, чтобы запустить действие. Поскольку он новый, он не был добавлен на сцену, поэтому он не рисуется и не обрабатывается.
Вы должны получить существующий Lines
объект и изменение этого вместо создания нового.
В качестве примечания, общее соглашение для именования методов и переменных заключается в использовании camelCase
что значит MoveUpOrDown
должно быть moveUpOrDown
, С другой стороны SnakeCase
Для классов и структур используется протоколы SpriteComponent
является текущим. Это позволяет сразу узнать, работаете ли вы с типом или переменной.