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