如何在单击时替换SKSpriteNode的图像

时间:2019-01-16 11:01:50

标签: ios swift sprite-kit skspritenode

由于无法在touchesBegan()中访问SKSpriteNode,我在单击时替换SKSpriteNode的图像时遇到了问题。

我具有要触摸的位置和节点,但是我无法替换图像。我试图替换像这样的图像“ balloon.texture = SKTexture(imageNamed:” explode“)”我无法使用此代码,因为我正在块内创建我的SKSpriteNode。这是我的代码

class GameScene: SKScene {
let brickCategoryBitMask: UInt32 = 0x1 << 2
var balloonArray = ["Blue","Green","Yellow","Purple","Red"]
let viewSize = UIScreen.main.bounds.size
var gameScore: SKLabelNode!

override func didMove(to view: SKView) {
    addRandomBalloon()
}

func addRandomBalloon() {
    // This function randomly places balloon around the game scene
    //
    let wait = SKAction.wait(forDuration: 0.7)

    let block = SKAction.run({
        let randomX = self.randomFloat(from: 50, to: self.frame.size.width - 50)
        let randomY = self.randomFloat(from: 200 , to: self.frame.size.height - 100)

        let randomBalloon = self.balloonArray.randomElement()!
        let balloon = SKSpriteNode(imageNamed: randomBalloon)
        balloon.position = CGPoint(x: randomX, y: randomY)
        balloon.size = CGSize(width: 25, height: 25)

        balloon.physicsBody = SKPhysicsBody(circleOfRadius: balloon.frame.width)
        balloon.physicsBody?.linearDamping = 0
        balloon.physicsBody?.allowsRotation = false
        balloon.physicsBody?.isDynamic = false // Prevents the ball from slowing down when it hits a brick
        balloon.physicsBody?.affectedByGravity = false
        balloon.physicsBody?.friction = 0.0
        balloon.physicsBody?.categoryBitMask = self.brickCategoryBitMask

        balloon.run( SKAction.scale(to: 4, duration: 0.5))
        self.addChild(balloon)

        ///assigning unique name to each balloon
        if randomBalloon == "Blue"{
            balloon.name = "blue_balloon"
        }else  {
            balloon.name = "purple_balloon"
        }

        removeBalloon(node: balloon, balloonName: balloon.name!)  //remove balloon after certain time
    })

    func removeBalloon(node : SKSpriteNode, balloonName : String){
        let deadlineTime = DispatchTime.now() + .seconds(2)
        DispatchQueue.main.asyncAfter(deadline: deadlineTime, execute: {
            if self.balloonIsTapped == true{
            }else{
                 node.removeFromParent()
            }
        })  
    }

   let sequence = SKAction.sequence([wait, block])
    run(SKAction.repeatForever(sequence), withKey: "addBlock")

}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
     if let touch = touches.first {
         let location = touch.location(in: self)
         let tappedNodes = nodes(at: location)

         for node in tappedNodes {
            if node.name == "blue_balloon"  {
                    score = score+1
                balloonIsTapped = true
                node.run( SKAction.scale(to: 1, duration: 0.4)){
                    node.removeFromParent()
                    self.balloonIsTapped = false
                }
            }

            if node.name == "purple_balloon"  {
                score = score+1
                balloonIsTapped = true
                node.run( SKAction.scale(to: 1, duration: 0.4)){
                    node.removeFromParent()
                    self.balloonIsTapped = false
                }
            }
        }

    }

}

// Marker: Random number generation
func randomFloat(from: CGFloat, to: CGFloat) -> CGFloat {
    let random: CGFloat = CGFloat(Float(arc4random()) / 0xFFFFFFFF)
    return random * (to - from) + from
}
}

如果用户单击气球,我只想替换气球的图像。请帮助或建议此代码中是否存在任何错误,因为我是iOS游戏开发和SpriteKit的新手。

1 个答案:

答案 0 :(得分:1)

touchesBegan函数的for循环中,node的类型为SKNode。您需要向下转换到SKSpriteNode。向下转换为SKSpriteNode时,可以更改纹理。

for node in tappedNodes {
    if let tappedBalloon = node as? SKSpriteNode {
        if tappedBalloon.name == "blue_balloon" {
            // Set tapped balloon's texture
            tappedBalloon.texture = // The texture you want here.
            // Handle tapping a balloon, such as increasing the score.
        }
    }
}

我在您的for循环中注意到,蓝色和紫色气球的if块内有相同的代码。您可以轻松地将重复的代码移至其自己的函数popBalloon或任何您想为其命名的函数中,并在点击提示框时调用该函数。如果气球在颜色上没有什么区别,则可以为每个气球命名"balloon",然后检查一个名称,而不用检查气球的多个名称。那会缩短您的代码。

您还可以通过创建Balloon结构或类并使sprite节点作为其属性之一来使代码更易于理解。编写处理气球而不是Sprite节点和其他SpriteKit术语的代码。