Xcode Swift 3 / SpriteKit:点击精灵

Posted

技术标签:

【中文标题】Xcode Swift 3 / SpriteKit:点击精灵【英文标题】:Xcode Swift 3 / SpriteKit : Tapping Sprites 【发布时间】:2016-12-23 04:20:31 【问题描述】:

我一直在研究,并且肯定尝试了一段时间,以找到一种在您点击精灵时激活功能的方法。例如:如果您点击蓝色精灵,它会激活blue()。点击红色精灵,它会激活red()。我一直在寻找一段时间,所有的答案要么是旧版本的,要么完全不适合我。有人有什么想法吗?

编辑: 这是我正在使用的一些代码。

class GameScene: SKScene 

        var blue = SKSpriteNode()
        var red = SKSpriteNode()
        var green = SKSpriteNode()
        var help = SKLabelNode()
        var score = SKLabelNode()
        var points = 0
        var loseAmount = 1.0
        var firstAdvance = 0
        var loseTimer = Timer()

        override func didMove(to view: SKView) 

            self.physicsWorld.contactDelegate = self

            blue = self.childNode(withName: "blue") as! SKSpriteNode
            blue.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
            blue.name = "blue"
            blue.isUserInteractionEnabled = true

            red = self.childNode(withName: "red") as! SKSpriteNode
            red.position = CGPoint(x: self.frame.width / 2 + 100, y: self.frame.height / 2)
            red.name = "red"
            red.isUserInteractionEnabled = true

            green = self.childNode(withName: "green") as! SKSpriteNode
            green.position = CGPoint(x: self.frame.width / 2 - 100, y: self.frame.height / 2)
            green.name = "green"
            green.isUserInteractionEnabled = true

            help = self.childNode(withName: "help") as! SKLabelNode
            help.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 4 * 3)
            help.name = "help"
            help.isUserInteractionEnabled = false

            score = self.childNode(withName: "score") as! SKLabelNode
            score.position = CGPoint(x: self.frame.width / 2, y: self.frame.height - 40)
            score.name = "score"
            score.text = "\(points)"
            score.isUserInteractionEnabled = false

        

        func randomMove() 
            blue.position = CGPoint(x:Int(arc4random_uniform(244)+38),y:Int(arc4random_uniform(404)+38))
            red.position = CGPoint(x:Int(arc4random_uniform(244)+38),y:Int(arc4random_uniform(404)+38))
            green.position = CGPoint(x:Int(arc4random_uniform(244)+38),y:Int(arc4random_uniform(404)+38))

        

        func advance() 
            if (firstAdvance == 0) 
                firstAdvance = 1
                help.removeFromParent()
                points += 1
                playPointSound()
                randomMove()
                loseTimer = Timer.scheduledTimer(timeInterval: loseAmount, target: self, selector: #selector(GameScene.lose), userInfo: nil, repeats: true)

             else if (firstAdvance == 1) 
                points += 1
                loseAmount -= 0.01
                playPointSound()
                self.loseTimer.invalidate()
                loseTimer = Timer.scheduledTimer(timeInterval: loseAmount, target: self, selector: #selector(GameScene.lose), userInfo: nil, repeats: true)

            

        

        func lose() 
            playLoseSound()
            let endSceneTemp = EndScene(fileNamed: "EndScene")
            self.scene?.view?.presentScene(endSceneTemp!, transition: SKTransition.crossFade(withDuration: 0.1))
        

        func playPointSound() 
            let path = Bundle.main.path(forResource: "", ofType:nil)!
            let url = URL(fileURLWithPath: path)

            do 
                let sound = try AVAudioPlayer(contentsOf: url)
                pointSound = sound
                sound.play()
             catch 
                // couldn't load file :(
            
        

        func playLoseSound() 
            let path = Bundle.main.path(forResource: "", ofType:nil)!
            let url = URL(fileURLWithPath: path)

            do 
                let sound = try AVAudioPlayer(contentsOf: url)
                loseSound = sound
                sound.play()
             catch 
                // couldn't load file
            
        

        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
            for touch in (touches) 
                let positionInScene = touch.location(in: self)
                let touchedNode = self.atPoint(positionInScene)
                if let name = touchedNode.name 
                    if name == "blue" 
                        advance()
                    
                    if name == "red" || name == "green"
                        lose()
                    
                
            
        

        override func update(_ currentTime: TimeInterval) 

        
    

【问题讨论】:

这在很大程度上取决于您如何创建精灵,如何将它添加到场景中,以及场景中的其他内容。你能提供这些信息吗? @Confused 我的精灵是通过 .sks 文件创建的。场景中除了一个红色节点、一个蓝色节点和一个绿色节点外,没有太多东西。希望这会有所帮助。 【参考方案1】:

您只需要为您的精灵指定一个名称:

let redSpriteNode = SKSpriteNode(imageNamed: "red") // add sprite by code
//let redSpriteNode = self.childNode(withName: "red") as! SKSpriteNode // for adding from .sks file
redSpriteNode.name = "red"
let blueSpriteNode = SKSpriteNode(imageNamed: "blue")
redSpriteNode.name = "blue"

并在touchs开始方法中激活欲望功能。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        for touch in (touches) 
            let positionInScene = touch.location(in: self)
            let touchedNode = self.atPoint(positionInScene)
            if let name = touchedNode.name 
                if name == "red" 
                   red()
                
                if name == "blue" 
                   blue()
                
            
        
    

您可以像这样找到所有具有相同名称的节点:(reference)

self.enumerateChildNodes(withName: "red") _,_ in
   print(count)
   count = count + 1

【讨论】:

出于某种原因,这似乎对我不起作用。我正在使用 .sks 文件中的节点,是的。但是,这仍然对我不起作用。 @DJDJ 您是否使用 .sks 编辑器为每个节点分配了名称? 正如@0x141E 所说,您必须为节点设置名称 @0x141E @Mina 是的,我已经使用blue = self.childNode(withName: "blue") as! SKSpriteNodeblue.name = "blue" 为我的所有精灵设置了一个名称 请在您的问题中添加一些代码,这可能有助于我们找到问题。【参考方案2】:

对我来说最有效的方法是将 UITapGestureRecognizer 添加到 SKView,然后在场景中处理点击手势。

点击后,您可以获得视图中的位置,然后将其转换为场景中的位置。有了它,您可以查找nodeAtPoint: 的点击位置。

当您拥有该节点时,然后检查其名称并在该 SKSpriteNode 上执行操作,如果其名称是您想要在点击时执行某项操作的名称。

虽然您可以通过覆盖 touchesBegan:touchesMoved: 来做到这一点,但是当您尝试捕捉更复杂的触摸(例如捏合)时,您可以节省一点力气,因为您不需要弄清楚什么是轻触vs. 长按 vs. 先捏。

【讨论】:

我目前没有我的代码,但我会尝试一下。 我找不到要添加的 UITapGestureRecognizer,抱歉。你能告诉我或告诉我在哪里添加这个吗?

以上是关于Xcode Swift 3 / SpriteKit:点击精灵的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Xcode 8 和 Swift 3 在 SpriteKit 中以编程方式触发 segue

Xcode 8 SpriteKit:GameScene.swift 文件未被识别/运行

如何在情节提要中创建一个按钮以启动在 xcode swift 中使用 spritekit 创建的游戏

强制 Swift Playgrounds (xcode) 在不模拟 iOS 的情况下使用 MacOS SpriteKit

将 SKSpriteNode 移动 Y - Swift 2 + SpriteKit

这个带有 SpriteKit 代码的 Swift 没有达到预期的效果