Во-первых, в приведенном выше коде нет вызовов для запуска анимации с ключом "shootAnimation"
и отсутствует вызов для повторного запуска анимации без съемки при stopShooting()
и вызов для повторного запуска съемки. анимация в формате startShooting()
. Методы должны включать их, как показано ниже
func startShooting() {
self.removeAction(forKey: "noshootAnimation")
// Add this call
self.run(shootAnimation)
self.shooting = true
}
func stopShooting() {
self.removeAction(forKey: "shootAnimation")
// Add this call
self.run(noshootAnimation)
self.shooting = true
}
Во-вторых, анимации noshootAnimation
и shootAnimation
являются пустыми действиями: они ничего не будут делать, если инициализированы как SKAction()
. В зависимости от того, что вы пытаетесь сделать, существует ряд методов класса SKAction
, которые будут создавать для вас действия здесь .
В-третьих, любые SKNode
(напомним, что сцена является подклассом SKNode
) не будет получать сенсорные вызовы, если для свойства isUserInteractionEnabled
узла установлено значение false
(для которого оно установлено по умолчанию); вместо этого он будет обработан так, как если бы его родитель получил вызов. Однако, если isUserInteractionEnabled
узла будет true
, это будет тот, который получает вызовы UIResponder
, а не его родительский узел. Убедитесь, что для этого свойства установлено значение true
для сцены и для всех узлов, которые должны получать касания (вы можете сделать это в didMove(to:)
в сцене или где-то еще).
Теперь я предлагаю улучшение. Я часто использую кнопки в Spritekit, но все они являются подклассами настраиваемого класса кнопок (сам является подклассом SKSpriteNode
), который использует делегирование протокола для оповещения участников о событиях касания. Схема выглядит так:
class Button: SKSpriteNode {
weak var responder: ButtonResponder?
// Custom code
// MARK: UIResponder
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
// Respond here
responder?.respond(to: self)
}
}
protocol ButtonResponder: AnyObject {
func respond(to button: Button)
}
class MyScene: SKScene, ButtonResponder {
func respond(to button: Button) {
// Do something on touch, but typically check the name
switch button.name {
case "myButton":
// Do something specific
default:
break
}
}
override func didMove(to view: SKView) {
// Set the scene as a responder
let buttonInScene = childNode(withName: "myButton") as! Button
buttonInScene.responder = self
}
}
Подробнее о делегировании см. здесь . Надеюсь, это немного помогло.
РЕДАКТИРОВАТЬ: преобразовать местоположение касания
Вы можете преобразовать касание в узел на экране, передав вместо этого ссылку на метод location(in:)
из UITouch
сцены, как вы это делали в своем коде
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
let yourNode = childNode(withName: "yourNode")!
for touch in touches {
let touchLocationToYourNode = touch.location(in: yourNode)
// Do something
}
}
В качестве альтернативы используйте методы SKNode
convert(_:from:)
и convert(_:to:)
let nodeA = SKNode()
let nodeB = SKNode()
nodeA.xScale = 1.5
nodeA.yScale = 1.2
nodeA.position = .init(x: 100, y: 100)
nodeA.zRotation = .pi
let pointInNodeACoordinateSystem = CGPoint(x: 100, y: 100)
let thatSamePointInNodeBCoordinateSystem = nodeB.convert(pointInNodeACoordinateSystem, from: nodeA)