1

I’m working on a SpriteKit game and at first I put 4 UIButton in my GameplayScene, but then I decided to create individual buttons as SKSpriteNode, programmatically made, and use a class (class Button: SKSpriteNode). I want my buttons fade and scale a little when pressed and then turn back to the original state. Buttons fade and scale down, but they stay in that state, don’t go back to normal state. What’s wrong with my code?

import SpriteKit

protocol ButtonDelegate: NSObjectProtocol { func buttonClicked(sender: Button) }

class Button: SKSpriteNode {

weak var delegate: ButtonDelegate!

var buttonTexture = SKTexture()

init(name: String) {
    buttonTexture = SKTexture(imageNamed: name)
    super.init(texture: buttonTexture, color: .clear, size: buttonTexture.size())
    self.isUserInteractionEnabled = true
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

var touchBeganCallback: (() -> Void)?
var touchEndedCallback: (() -> Void)?

weak var currentTouch: UITouch?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    touchBeganCallback?()
    if isUserInteractionEnabled {
        setScale(0.9)
        self.alpha = 0.5
        if let currentTouch = touches.first {
            let touchLocation = currentTouch.location(in: self)
            for node in self.nodes(at: touchLocation) {
        delegate?.buttonClicked(sender: self)

            }
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    setScale(1.0)
    self.alpha = 1.0
    touchEndedCallback?()
    print("tapped!")
}

}

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
DaniChi
  • 301
  • 3
  • 12

1 Answers1

0

Use SKAction to do this.

In touchesBegan remove setScale(0.9) and self.alpha = 0.5, use :

        let scaleAction = SKAction.scale(to: 0.5, duration: 1)
        self.run(scaleAction)

        let fadeAction = SKAction.fadeAlpha(to: 0.5, duration: 1)
        self.run(fadeAction)

in touchEnded do the same and add:

    self.removeAllActions()
    let scaleAction = SKAction.scale(to: 1, duration: 1)
    self.run(scaleAction)

    let fadeAction = SKAction.fadeAlpha(to: 1, duration: 1)
    self.run(fadeAction)

EDIT:

Here a test into a Playground:

enter image description here

Andrew21111
  • 868
  • 8
  • 17
  • Thanks, but I've got the same problem... It seems like "touchesEnded" doesn't work... – DaniChi Sep 26 '18 at 12:50
  • it could be because of the callback into touchBegan – Andrew21111 Sep 26 '18 at 13:02
  • @DaniChi I tried into a Playground and it works like a charme, look at the video I'm going to add to the answer. When you call touchBeganCallback?() what would you like to happen ? what do you do in its body ? Do you return from callback ? – Andrew21111 Sep 26 '18 at 13:30
  • 1
    You're right. I created another project, it also works perfectly with my old code. Anyway I think there are some issues with my GamePlayScene... I'm checking code – DaniChi Sep 26 '18 at 20:00
  • 1
    Thanks for helping me, I was really frustrated. I totally remade the app and now it works perfectly. I still can't understand what was wrong, the code is the same... – DaniChi Sep 28 '18 at 04:56
  • Ok, sorry, that’s not true: the problem is: after I added gesture recognizer to GameViewController, my buttons stop to work. If I push a button, it fades and scale, but stay in that state, don’t go back to normal state. I want the user could tap and swipe anywhere in the GamePlayScene, and could tap buttons to add things. Any help? – DaniChi Sep 28 '18 at 11:21
  • If you want the user to swipe and move the buttons, use touchMoved: function and update the buttons positions and remove gesture recognizer. This is because gesture recognizer intercept the touch. [check this](https://stackoverflow.com/questions/49185440/how-to-move-player-left-and-right-in-touchesmoved) to see how to use touchMoved. Adapt the solution to your needs – Andrew21111 Sep 28 '18 at 12:48