how to replace the image of SKSpriteNode on click

0

i am facing issue on replacing the image of SKSpriteNode on click as i am not able access SKSpriteNode in touchesBegan().

i have the location and the node which is getting touched but i am not able to replace the image . i have tried replacing image like this "balloon.texture = SKTexture(imageNamed: "explode")" i cant use this code as i am creating my SKSpriteNode inside the block. Here is my code

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
}
}

i just want to replace the image of the balloon if user click on the balloon. please help or suggest if there is any thing wrong in this code as i am new in iOS game development and SpriteKit.

ios
swift
sprite-kit
skspritenode
asked on Stack Overflow Jan 16, 2019 by harinder rana • edited Jan 17, 2019 by Mark Szymczyk

1 Answer

1

In the for loop in your touchesBegan function, node is type SKNode. You need to downcast to SKSpriteNode. When you downcast to SKSpriteNode, you can change the texture.

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.
        }
    }
}

I noticed in your for loop that you have the same code inside the if blocks for blue and purple balloons. You could easily move the duplicated code into its own function, popBalloon or whatever you want to name it, and call that function when you tap a balloon. If there's no difference in the balloons besides their color, you could just give each balloon the name "balloon" and check the one name instead of checking for multiple names of balloons. That would shorten your code.

You could also make your code easier to understand by creating a Balloon struct or class and have a sprite node as one of its properties. Write code that deals with balloons instead of sprite nodes and other SpriteKit terms.

answered on Stack Overflow Jan 17, 2019 by Mark Szymczyk

User contributions licensed under CC BY-SA 3.0