Reputation: 107
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.
Upvotes: 0
Views: 461
Reputation: 20088
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.
Upvotes: 2