已经有一些关于如何在 SpriteKit 中制作按钮的问题,例如Swift Spritekit 以编程方式添加按钮和在 SKScene 中设置按钮。
无论哪种方式,解决方案是为SKSpriteNode
按钮制作一个纹理,然后在函数touchesEnded
中测试触摸是否落在按钮内SKSpriteNode
。
然而,有趣的是,如果要将按钮设置为子按钮,例如 aSKCameraNode
或 another SKSpriteNode
,则此方法不再有效。
我的问题是为什么?以及如何克服这一困境。
更新:
关于下面的帖子,这里有两个简单的 GameScene.swift 文件的替代版本。主要区别在于,在第一种情况下,sprite2
它不是相机的孩子,而在版本 2 中它是。
注意:在 gifs 中,请注意在版本 1 中,单击紫色精灵 ( sprite2
) 会导致它打印“你轻按了紫色精灵。”,而在版本 2 中它会显示“蓝色精灵”。因此问题很清楚:
点击另一个 SKNode 的子节点注册为点击最上面的父节点,而不是实际点击的节点!
新问题:如何纠正这个问题。
附录:在第 2 版sprite2
中,由于成为相机的孩子,位置发生了一些变化——因为它是 MWE,它不会影响这个演示,我选择不更正它。
版本 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
}
}