LoginSignup
13
12

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-08-01

【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)")
    }

}
13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12