Уже есть несколько вопросов о том, как создать кнопку в SpriteKit, например Swift Spritekit Adding Button. Программно и настройка кнопок в SKScene.
В любом случае решение состоит в том, чтобы создать SKSpriteNode
с текстурой для кнопки, а затем в функции touchesEnded
проверить, попадает ли касание в кнопку-SKSpriteNode
.
Интересно, однако, что если сделать кнопку дочерней, скажем, SKCameraNode
или другой SKSpriteNode
, то этот метод больше не работает.
Мой вопрос: почему? и как преодолеть эту дилемму.
ОБНОВИТЬ:
Что касается сообщения ниже, здесь представлены две альтернативные версии простого файла GameScene.swift. Основное отличие состоит в том, что в первом случае sprite2
не является дочерним элементом камеры, а в версии 2 — им.
Примечание. Обратите внимание, что в GIF-файлах в версии 1 щелчок по фиолетовому спрайту (sprite2
) приводит к выводу «Вы коснулись фиолетового спрайта», тогда как в версии 2 написано «синий спрайт». Таким образом, проблема проясняется:
Прикосновение к дочернему элементу другого узла SKNode регистрируется как касание самого верхнего родительского узла, а не как фактическое касание узла!
Новый вопрос: Как это исправить.
Дополнение: в версии 2 sprite2
немного изменил позицию из-за того, что стал дочерним элементом камеры — так как это M.W.E. и это не влияет на эту демонстрацию, я решил не исправлять это.
Версия 1
class GameScene: SKScene {
var cam: SKCameraNode!
var sprite = SKSpriteNode(imageNamed: "sprite")
var sprite2 = SKSpriteNode(imageNamed: "sprite2")
override func didMove(to view: SKView) {
backgroundColor = SKColor.white
sprite.position = CGPoint(x: size.width/4,y: size.height/2)
sprite2.position = CGPoint(x: size.width/4 * 3,y: size.height/2)
sprite.anchorPoint = CGPoint(x:0.5, y:0.5)
// Set up the camera
cam = SKCameraNode()
self.camera = cam
cam.setScale(3.0)
cam.position = CGPoint(x: size.width/4, y: 0)
sprite.addChild(cam)
addChild(sprite); addChild(sprite2)
}
func touchDown(atPoint pos : CGPoint) {
}
func touchMoved(toPoint pos : CGPoint) {
}
func touchUp(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self)
if sprite.contains(touchLocation) {
print("You tapped the blue sprite")
}
if sprite2.contains(touchLocation) {
print("You tapped the purple sprite")
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
Версия 2
class GameScene: SKScene {
var cam: SKCameraNode!
var sprite = SKSpriteNode(imageNamed: "sprite")
var sprite2 = SKSpriteNode(imageNamed: "sprite2")
override func didMove(to view: SKView) {
backgroundColor = SKColor.white
// Scale Sprites
// sprite.setScale(0.3)
sprite2.setScale(0.3)
sprite.position = CGPoint(x: size.width/4,y: size.height/2)
// sprite2.position = CGPoint(x: size.width/4 * 3,y: size.height/2)
sprite.anchorPoint = CGPoint(x:0.5, y:0.5)
// Set up the camera
cam = SKCameraNode()
self.camera = cam
cam.setScale(3.0)
cam.position = CGPoint(x: size.width/4, y: 0)
sprite.addChild(cam)
addChild(sprite); //addChild(sprite2)
cam.addChild(sprite2)
}
func touchDown(atPoint pos : CGPoint) {
}
func touchMoved(toPoint pos : CGPoint) {
}
func touchUp(atPoint pos : CGPoint) {
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let touchLocation = touch!.location(in: self)
if sprite.contains(touchLocation) {
print("You tapped the blue sprite")
}
if sprite2.contains(touchLocation) {
print("You tapped the purple sprite")
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
touchesEnded
вSKScene
, удерживающем ваши кнопки и камеру, или в подклассеSKSpriteNode
, который является вашим экземпляром кнопки? - person Confused   schedule 15.01.2017touchesEnded
вSKScene
удерживая кнопки и камеру. - person SumNeuron   schedule 15.01.2017