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

SpriteKitで使うボタン(Swift)

More than 3 years have passed since last update.

SpriteKitを使って、アプリを作る際にUIButtonみたいなものが欲しくなったので簡単に作れる方法を検討した。

そもそも

SpriteKit初めてだったので、最初は1つのシーンファイルにSKSpriteNodeとかをパーツごとに置いていて、かつそれらにアニメーション付けて、、ステータスによって画像切替えて、、などしていたらファイルの行数が膨らみすぎて管理が難しくなってきた。

そこで、(当たり前かと思うが)パーツごとにSKNodeを継承したクラスを作成して、置きたいシーンにまとめて配置する。という方法を思いついた。

方法①

簡単な方法

わざわざ独自にクラスつくらずに、SKSpriteNode置いて、touchBegan()で判別する。

override func didMoveToView(view: SKView) {
    //テクスチャアトラスからボタン作成
    let button = SKSpriteNode(texture: SKTextureAtlas(named: "UIParts").textureNamed("button"))
    //イメージからそのままの場合は
    //let button = SKSpriteNode(imageNamed: "button.png") 


   button.position = CGPointMake(self.frame.width/2, self.frame.height/2)
   button.zPosition = 1
   button.name = "button"
   self.addChild(button)     
}


override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first as UITouch? {
        let location = touch.locationInNode(self)
            if self.nodeAtPoint(location).name == "button" {
                print("button tapped")
           }
        }
    }
}

zPositionが一番上にないとタッチしても反応がないので注意。

方法②

ちょっとめんどくさい方法

ボタンを押した時だけ、画像が切り替わるボタンを作成

ボタン用にクラスを1つつくる。
用意するもの

  • ボタンの画像(hoge.png)
  • ボタンをタップした後の画像(hoge_on.png)

SKNodeを継承したボタンクラス

クラスを作成するので、使用したいシーンでタップイベントを取ることができないので
デリゲートを使用してイベントをとることにした。
デリゲート関数にidつけて処理の分岐することにした。
確かUITextFieldとかもそんな感じでやってたのを真似した。

self.userInteractionEnabled = true

これないと個別につくったクラスでtouchBegan反応しないので注意

以下ソース

Button.swift
import SpriteKit
import Foundation

class Button: SKNode {
    weak var keyTapDelegate: ButtonTappedDelegate!

    var button:SKSpriteNode!
    var buttonOver:SKSpriteNode!
    var imageName: String!


    internal init(name: String) {
        super.init()
        imageName = name

        //通常
        button = SKSpriteNode(texture: SKTextureAtlas(named: "UIParts").textureNamed(imageName))
        //タップした状態
        buttonOver = SKSpriteNode(texture: SKTextureAtlas(named: "UIParts").textureNamed(imageName+"_on"))
        buttonOver.alpha = 0

        //必要!
        self.userInteractionEnabled = true

        self.addChild(button)
        self.addChild(buttonOver)
    }

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

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
         //ボタンの状態を切替え
        button.alpha = 0
        buttonOver.alpha = 1
        ButtonTapDelegate.buttonTapped(imageName)
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
         //ボタンの状態を切替え
        button.alpha = 1
        buttonOver.alpha = 0
    }
}

ボタンのタップを使用するシーンで使うためのプロトコル

名前を引数にとって、複数ある場合の処理わけをする

protocol ButtonTappedDelegate : class {
    //Buttonクラスでタッチされた
    func buttonTapped(name:String)
}

シーンで以上のボタンクラスを利用する

ボタンのタップイベントをデリゲート関数?から受け取って、名前別に処理をする

class Scene: SKScene, KeyTappedDelegate {

    override func didMoveToView(view: SKView) {
        let buttonHoge = Button(name: "hoge")
        buttonHoge.buttonTapDelegate = self
        buttonHoge.zPosition = 1.0
        self.addChild(buttonHoge)

        let buttonPiyo = Button(name: "piyo")
        buttonPiyo.buttonTapDelegate = self
        buttonPiyo.zPosition = 1.0
        self.addChild(buttonPiyo)
    }

    func buttonTapped(name: String) {
        switch name {
        case "hoge":
            print("hoge")
        case "piyo":
            print("piyo")
        default:
            print("hogepiyo")
    }
}

書いたソースコードからいらない部分省略して変数名とか変えただけなので動かなかったらすみません。

Why not register and get more from Qiita?
  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
No 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
ユーザーは見つかりませんでした