Help us understand the problem. What is going on with this article?

Swift倉庫・SKSpriteNodeでCButtonを作ってみました。

More than 5 years have passed since last update.

【SKSpriteNodeボタン】

SKSpriteNodeを使って、iOS・OSX対応のCButtonクラスを作ってみました。これはデリケートとしてもサブクラスとしても使えるようにもいたしました。

CButton.swift
import SpriteKit

#if os(iOS)
    import UIKit
#endif

enum eButtonActionStyle: Int {
    case none = 0
    case pop
    case count
}

enum eButtonStatus: Int {
    case none   = 0
    case down
    case up
    case cancelled

    func value() -> Int {
        switch self {
        case .none:
            return 0
        case .down:
            return 1
        case .up:
            return 2
        case .cancelled:
            return 3
        }
    }
}

class CButton: SKSpriteNode {

    var status: eButtonStatus = .none {
        willSet {
            // value がセットする前に呼ばれる
        }
        didSet {
            // value がセットされた直後に呼ばれる
            oldStatus = oldValue
            newStatus = status

            switch newStatus {
            case .none:
                buttonCancelled()
            case .down:
                buttonDown()
            case .up:
                buttonUpAction()
            case .cancelled:
                buttonCancelled()
            }
        }
    }

    convenience init(imageNamed: String!, buttonName: String!) {

        let sprite  = SKSpriteNode(imageNamed: imageNamed)
        let texture = sprite.texture
        let size    = sprite.size

        self.init(texture: texture, buttonName: buttonName, withString:nil, size: size)
    }

    convenience init(imageNamed: String!, buttonName: String!, withString: String!) {

        let sprite  = SKSpriteNode(imageNamed: imageNamed)
        let texture = sprite.texture
        let size    = sprite.size

        self.init(texture: texture, buttonName: buttonName, withString:withString, size: size)
    }

    init(texture: SKTexture!, buttonName: String!, withString: String!, size: CGSize) {

        super.init(texture: texture, color: SKColor.clearColor(), size: size)

        self.name       = buttonName
        self.size       = size
        self.status     = eButtonStatus.none

        self.userInteractionEnabled = true

        if withString {
            // Display Text
            labelActive = true
            buttonLabel = SKLabelNode(fontNamed:"Chalkduster")
            buttonLabel.text = withString
            buttonLabel.fontSize = 12
            buttonLabel.position = self.position
            addChild(buttonLabel)
        }

    }

    var delegate:CButtonDelegate?
    var oldStatus: eButtonStatus = .none
    var newStatus: eButtonStatus = .none
    var actionStyle: eButtonActionStyle = .pop
    var buttonLabel: SKLabelNode = SKLabelNode()
    var labelActive: Bool = false

    //
    //**************************************************************************
    #if os(iOS) // iOS SKScene Extensions
    //**************************************************************************
    //
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            status = .down
        }
    }

    // [ iOS ] : Touches Moved
    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            if containsPoint(touch.locationInNode(self.scene)) {
                status = .down
            } else {
                status = .cancelled
            }
        }
    }

    // [ iOS ] : Touches Ended
    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            if !containsPoint(touch.locationInNode(self.scene)) {
                status = .cancelled
            } else {
                status = .up
            }
        }
    }

    // [ iOS ] : Touches Cancelled
    override func touchesCancelled(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches {
            status = .cancelled
        }
    }

    //
    //**************************************************************************
    #else   // OSX SKScene Extensions
    //**************************************************************************
    //
    override func mouseDown(theEvent: NSEvent) {
        status = .down
    }

    // [ OSX ] : Mouse Moved
    override func mouseMoved(theEvent: NSEvent) {
        if containsPoint(theEvent.locationInNode(self.scene)) {
            status = .down
        } else {
            status = .cancelled
        }
    }

    // [ OSX ] : Mouse Moved
    override func mouseDragged(theEvent: NSEvent) {
        if containsPoint(theEvent.locationInNode(self.scene)) {
            status = .down
        } else {
            status = .cancelled
        }
    }

    // [ OSX ] : Mouse Up
    override func mouseUp(theEvent: NSEvent) {
        if !containsPoint(theEvent.locationInNode(self.scene)) {
            status = .cancelled
        } else {
            status = .up
        }
    }

    #endif
    //
    //******************************************************************************
    // SKScene Extension Results Called
    //******************************************************************************
    //

    private func buttonDown() {
        buttonColor(SKColor.redColor(), blend: 0.50)
        cbuttonDown(self)
        delegate?.cbuttonDown(self)
    }

    private func buttonUp() {
        buttonColor(SKColor.clearColor(), blend: 0.0)
        cbuttonUp(self)
        delegate!.cbuttonUp(self)
    }

    private func buttonCancelled() {
        buttonColor(SKColor.clearColor(), blend: 0.0)
        cbuttonCancelled(self)
        delegate?.cbuttonCancelled(self)
    }

    private func buttonColor(color: SKColor!, blend: CGFloat!) {
        self.color = color
        self.colorBlendFactor = blend
        if labelActive {
            buttonLabel.color = color
            buttonLabel.colorBlendFactor = blend
        }
    }

    private func buttonUpAction() {

        var sequence:SKAction = SKAction.runBlock {self.buttonUp()}
        if actionStyle == .pop {
            // Pop Two Times
            sequence = SKAction.sequence([
                SKAction.scaleTo(1.2, duration:0.1),
                SKAction.scaleTo(1.0, duration:0.1),
                SKAction.scaleTo(1.2, duration:0.1),
                SKAction.scaleTo(1.0, duration:0.1),
                SKAction.runBlock {self.buttonUp()} ])
        }
        self.runAction(sequence)
    }

    // [ OSX/iOS ] : Button Down
    func cbuttonDown(button: CButton) {
    }

    // [ OSX/iOS ] : Button Up
    func cbuttonUp(button: CButton) {

    }

    // [ OSX/iOS ] : Button Cancelled
    func cbuttonCancelled(button: CButton) {

    }

}

protocol CButtonDelegate {
    func cbuttonDown(button: CButton)
    func cbuttonUp(button: CButton)
    func cbuttonCancelled(button: CButton)
}

そして、下記のように登録使用します。

使用例:CSampleScene.swift
import SpriteKit

class CSampleScene: CScene, CButtonDelegate {

    init(size: CGSize) {
        super.init(size: size)

    }

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */

        let centerPoint = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))

        var theSprite = CButton(imageNamed:"buttonTest", buttonName: "testButton")
        theSprite.position = self.centerPoint
        theSprite.delegate = self
        addChild(theSprite)

        // フォント種類やサイズ変更は下記のように出来ます。
//      theSprite.buttonLabel.fontSize = 24
//      theSprite.buttonLabel.fontName = "AppleSDGothicNeo-Regular"

    }

    // Delegate Calls
    func cbuttonDown(button: CButton) {
        println("cbuttonDown Hit!!: \(button.newStatus)")
    }

    func cbuttonUp(button: CButton) {
        if button.name == "testButton" {
            //ボタン処理を行う
        }
    }

    func cbuttonCancelled(button: CButton) {
        println("cbuttonCancelled Hit!!: \(button.newStatus)")
    }

}
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away