uz7 uz7 - 18 days ago 7
Swift Question

share menu opens at twice rather just when button is pressed

I have added a share menu to my game, when the game is over the game over pop up appears with a share menu. when i press anywhere on the screen the share menu pops up and the game goes back to the beginning prompting the player to Tap to play again. Then when the player taps on the screen the share menu pops up again which makes the game unplayable after the first play through. I think i need to set the share menu to pop up only when SKSpriteNode for the share button is pressed, if the player taps anywhere else on the screen the game should just reset. Would be grateful if you could take a look at code and see where i am going wrong.

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {

var shareButton = SKSpriteNode()

var santa = SKSpriteNode()

var bg = SKSpriteNode()

var scoreLabel = SKLabelNode()

var tapToPlayLabel = SKLabelNode()

var score = 0

var gameOverScreen = SKSpriteNode()

var timer = Timer()

enum ColliderType: UInt32 {

case santa = 1
case Object = 2
case Gap = 4

}

enum ButtonName: String {

case play
case share

}

var gameOver = false

func makeBlocks() {

let moveBlocks = SKAction.move(by: CGVector(dx: -2 * self.frame.width, dy: 0), duration: TimeInterval(self.frame.width / 100))

let gapHeight = santa.size.height * 4

let movementAmount = arc4random() % UInt32(self.frame.height / 2)

let blockOffset = CGFloat(movementAmount) - self.frame.height / 4

let blockTexture = SKTexture(imageNamed: "block1.png")

let block1 = SKSpriteNode(texture: blockTexture)

block1.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY + blockTexture.size().height / 2 + gapHeight / 2 + blockOffset)

block1.run(moveBlocks)

block1.physicsBody = SKPhysicsBody(rectangleOf: blockTexture.size())
block1.physicsBody!.isDynamic = false

block1.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
block1.physicsBody!.categoryBitMask = ColliderType.Object.rawValue
block1.physicsBody!.collisionBitMask = ColliderType.Object.rawValue

block1.zPosition = -2

self.addChild(block1)

let block2Texture = SKTexture(imageNamed: "block2.png")

let block2 = SKSpriteNode(texture: block2Texture)

block2.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY - block2Texture.size().height / 2 - gapHeight / 2 + blockOffset)

block2.run(moveBlocks)

block2.physicsBody = SKPhysicsBody(rectangleOf: blockTexture.size())
block2.physicsBody!.isDynamic = false

block2.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
block2.physicsBody!.categoryBitMask = ColliderType.Object.rawValue
block2.physicsBody!.collisionBitMask = ColliderType.Object.rawValue

block2.zPosition = -2

self.addChild(block2)

let gap = SKNode()

gap.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY + blockOffset)

gap.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: blockTexture.size().width, height: gapHeight))

gap.physicsBody!.isDynamic = false

gap.run(moveBlocks)

gap.physicsBody!.contactTestBitMask = ColliderType.santa.rawValue
gap.physicsBody!.categoryBitMask = ColliderType.Gap.rawValue
gap.physicsBody!.collisionBitMask = ColliderType.Gap.rawValue

self.addChild(gap)

}

func didBegin(_ contact: SKPhysicsContact) {

if gameOver == false {

if contact.bodyA.categoryBitMask == ColliderType.Gap.rawValue || contact.bodyB.categoryBitMask == ColliderType.Gap.rawValue {

score += 1

scoreLabel.text = String(score)


} else {

self.speed = 0

gameOver = true

timer.invalidate()

let gameOverScreenTexture = SKTexture(imageNamed: "GameOverPopup.jpg")

var j: CGFloat = 0

gameOverScreen = SKSpriteNode(texture: gameOverScreenTexture, size: CGSize(width: 600, height: 600))

gameOverScreen.position = CGPoint(x: self.frame.midX, y: self.frame.midY)

gameOverScreen.size.height = self.frame.height / 3


gameOverScreen.zPosition = -1

self.addChild(gameOverScreen)


//share button

let shareButtonTexture = SKTexture(imageNamed: "shareButton.png")

var k: CGFloat = 0

shareButton = SKSpriteNode(texture: shareButtonTexture, size: CGSize(width: 500, height: 100))

shareButton.position = CGPoint(x: self.frame.midX, y: self.frame.midY)

shareButton.size.height = self.frame.height / 10

shareButton.name = "shareButton"

shareButton.zPosition = 0

self.addChild(shareButton)




}
}

}

func openShareMenu(value: String, image: UIImage?) {
guard let view = view else { return }

// Activity items
var activityItems = [AnyObject]()

// Text
let text = "Can you beat my score "
activityItems.append(text as AnyObject)

// Add image if valid
if let image = image {
activityItems.append(image)
}

// Activity controller
let activityController = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)


// Excluded activity types
activityController.excludedActivityTypes = [
UIActivityType.airDrop,
UIActivityType.print,
UIActivityType.assignToContact,
UIActivityType.addToReadingList,
]

// Present
view.window?.rootViewController?.present(activityController, animated: true)
}



override func didMove(to view: SKView) {

addChild(shareButton)

self.physicsWorld.contactDelegate = self

setupGame()

}

func setupGame() {

timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.makeBlocks), userInfo: nil, repeats: true)

let bgTexture = SKTexture(imageNamed: "bg.png")

let moveBGAnimation = SKAction.move(by: CGVector(dx: -bgTexture.size().width, dy: 0), duration: 7)
let shiftBGAnimation = SKAction.move(by: CGVector(dx: bgTexture.size().width, dy: 0), duration: 0)
let moveBGForever = SKAction.repeatForever(SKAction.sequence([moveBGAnimation, shiftBGAnimation]))

var i: CGFloat = 0

while i < 3 {

bg = SKSpriteNode(texture: bgTexture)

bg.position = CGPoint(x: bgTexture.size().width * i, y: self.frame.midY)

bg.size.height = self.frame.height

bg.run(moveBGForever)

bg.zPosition = -3

self.addChild(bg)

i += 1

}


let santaTexture = SKTexture(imageNamed: "santa1.png")
let santaTexture2 = SKTexture(imageNamed: "santa2.png")

let animation = SKAction.animate(with: [santaTexture, santaTexture2], timePerFrame: 0.1)
let makeSantaMove = SKAction.repeatForever(animation)

santa = SKSpriteNode(texture: santaTexture)

santa.position = CGPoint(x: self.frame.midX, y: self.frame.midY)

santa.run(makeSantaMove)

santa.physicsBody = SKPhysicsBody(circleOfRadius: santaTexture.size().height / 2)

santa.physicsBody!.isDynamic = false

santa.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
santa.physicsBody!.categoryBitMask = ColliderType.santa.rawValue
santa.physicsBody!.collisionBitMask = ColliderType.santa.rawValue

self.addChild(santa)

let ground = SKNode()

ground.position = CGPoint(x: self.frame.midX, y: -self.frame.height / 2)

ground.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.frame.width, height: 1))

ground.physicsBody!.isDynamic = false

ground.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue
ground.physicsBody!.categoryBitMask = ColliderType.Object.rawValue
ground.physicsBody!.collisionBitMask = ColliderType.Object.rawValue


self.addChild(ground)

scoreLabel.fontName = "Helvetica"

scoreLabel.fontSize = 60

scoreLabel.text = "0"

scoreLabel.position = CGPoint(x: self.frame.midX, y: self.frame.height / 2 - 220)

self.addChild(scoreLabel)

tapToPlayLabel.fontName = "Helvetica"

tapToPlayLabel.fontSize = 70

tapToPlayLabel.text = "Tap to Play!"

tapToPlayLabel.position = CGPoint(x: self.frame.midX, y: self.frame.height / 2 - 500)

self.addChild(tapToPlayLabel)


}

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

if gameOver == false {

tapToPlayLabel.isHidden = true

santa.physicsBody!.isDynamic = true

santa.physicsBody!.velocity = CGVector(dx: 0, dy: 0)

santa.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 320))

} else {

tapToPlayLabel.isHidden = false

gameOver = false

score = 0

self.speed = 1

self.removeAllChildren()

setupGame()

}


if let name = shareButton.name {

if name == "shareButton" {

openShareMenu(value: "\(self.score)", image: nil)


}

}

}

override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}

}

Answer

You are calling the touches method wrong. You are not using the name of the touched node to see if it is the share button. You merely assign a property (if let name = ...) and see if its the share button. You need to compare with the name of the actual node that is touched. You are also running your gameOver code anytime touchesBegan fires, you need to differentiate.

Try this

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

         for touch in touches {
             let location = touch.location(in: self) // get location of touch
             let nodeTouched = atPoint(location) // get touched node

             // Pressed button
             if let nodeName = nodeTouched.name {
                  switch nodeName {
                  case ButtonName.share.rawValue:
                     openShareMenu(value: "\(self.score)", image: nil)
                     return // return early if share button is pressed so your gameOver code below etc doesnt fire.

                  default: 
                      break
                }
           }

           // Did not press button, usual code
            if gameOver == false {..... }
      }
 }

Hope this helps