繁体   English   中英

如何通过在 Spritekit 中触摸它们来检测隐藏的 SKSpriteNode?

[英]How to detect hidden SKSpriteNode by touching them in Spritekit?

我正在使用 Spritekit 创建棋盘游戏。 最初所有的部分(SKSpriteNode)都是隐藏的。 我触摸它们后它们应该出现吗? 但是由于它们被设置为隐藏,当我覆盖 touchBegan 函数时我无法访问它们。 我该怎么办?

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let location = touches.first!.locationInNode(self)
    let touchedNode = self.nodeAtPoint(location)
    if(touchedNode.name == "pieces"){
        if(touchedNode.hidden == true){
            touchedNode.hidden = false
        }
    }
}

您正在尝试的是在 iOS8 上工作。 但这已在 iOS9 中得到修复。 如果您在 iOS8 上尝试您的代码,您将看到它有效。 这是在 iOS8 上让我恼火的事情之一,因为您可以点击隐藏节点是没有意义的。 不过,您可以使用 alpha 0.0 的节点(也适用于 iOS8)会很好,但这在 iOS9 中也已修复 因此将 alpha 设置为 0.0 将不起作用。

解决方案

您可以使用 SKNode 的containsPoint方法:

返回一个布尔值,指示一个点是否位于父坐标系内。

在您的情况下,父母将是您的精灵。 在此处阅读containsPoint方法的工作原理。 基本上, containsPoint并不关心节点是否可见,或者它是否有父节点。 它只是检查某个点( location )是否位于父级( touchedNode )坐标系内。 所以这里是你如何使用这种方法来做到这一点:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        let location = touches.first!.locationInNode(self)

        self.enumerateChildNodesWithName("pieces") { node, stop in

            if node.containsPoint(location) && node.hidden == true {

                node.hidden = false
                stop.memory = true
            }
        }
    }

在这里,您正在枚举所有部分(我假设 self 是它们的父节点),如果某个节点包含触摸位置并且它是隐藏的,则使其可见(并停止进一步的、不必要的搜索)。

提示:

还可以考虑在此处使用可选绑定:

if let touch = touches.first {

    let location = touch.locationInNode(self)

    //do your stuff here
}

使用可选绑定是个好习惯,因为它更安全。

到目前为止,我还有另一种方法似乎有效:

//如果必须轮流,可以用黑盘重复whitedisk for循环。 我正在使用 .name 来标识选择了哪个方块

func drawBoard() {

        let numRows = 8
        let numCols = 8
        let x = scene?.size.width
        xOffset = ((x)! - ((x)! / 9) * CGFloat(numCols))
        squareSize = CGSizeMake(x!/9, x!/9)
        diskSize = CGSizeMake(x!/11, x!/11)

        // Draw the squares
        for row in 0...numRows-1 {
            for col in 0...numCols-1 {
                square = SKSpriteNode(texture: SKTexture(imageNamed: "square.png"), size: squareSize!)
                //row and column both start with zero, may want to start with 1 later
                square!.name = "square \(col)-\(row)"
                square!.userInteractionEnabled = false
                square!.position = CGPointMake(CGFloat(col) * squareSize!.width + xOffset, CGFloat(row) * squareSize!.height + xOffset)
                self.addChild(square!)
            }
        }
        // Draw the White disks "hidden"
        for row in 0...numRows-1 {
            for col in 0...numCols-1 {
                let gamePiece = SKSpriteNode(texture: SKTexture(imageNamed: "whitedisk.png"), size: diskSize!)
                gamePiece.name = "whitedisk \(col)-\(row)"
                gamePiece.userInteractionEnabled = false
                //print("Disk Name: \(gamePiece.name)")
                gamePiece.position = CGPointMake(CGFloat(col) * squareSize!.width + xOffset, CGFloat(row) * squareSize!.height + xOffset)
                gamePiece.hidden = true
                self.addChild(gamePiece)
            }
        }
}

// 磁盘变量是 whitedisk 或 blackdisk 取决于轮到谁 此函数在确定选择了哪个方块后显示游戏块

func placeDisk(name: String, disk: String) {
    var myName = name
    let theDisk = disk
    myName = myName.stringByReplacingOccurrencesOfString("square", withString: theDisk)
    let node = self.childNodeWithName(myName)
    //print("Display: \(myName) - Node: \(String(node))")
    node?.hidden = false
}

// 我对 touchesEND 函数过度使用,但你也可以使用 touches begin

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        for touch in touches {
            let positionInScene = touch.locationInNode(self)
            let name = self.nodeAtPoint(positionInScene).name
            if name != nil {
                print("Touched: \(name)")
               placeDisk(name!, disk: "whitedisk")
            }
        }
    }

这是来自苹果的文档:

使用 Alpha 处理隐藏节点上的用户交互

半透明节点——那些 alpha 小于 1 但大于 0 的节点——仍然接收用户交互。 您可以将节点的 alpha 设置为leastNonzeroMagnitude以使其有效透明,但仍然对触摸或鼠标移动做出响应,尽管给它一个clear 颜色具有相同的效果。

在我的棋盘游戏中,我有一个带有clearcolor的子对象。 它没有纹理,因此它变得不可见(如果你有纹理,我猜你可以使用leastNonzeroMagnitude )。

我有一个 .sks 文件,我在这个屏幕截图中制作了清晰的颜色:

清晰的颜色

我选择一种自定义颜色并将其不透明度设置为 0。

我确实用以下代码检测到它:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let touch = touches.first else { return }
        let location = touch.location(in: self)
        let touchedNodes = nodes(at: location)
        let frontTouchedNode = atPoint(location).name
        print(touchedNodes)
        print(frontTouchedNode!)
    }

有关更多信息,请访问 Apple 官方文章的链接: 控制节点上的用户交互

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM