アプリ制作記3 ボタンクラスの作成

前回は画面を作って表示するところまでやりましたが、今回はついにボタンをぽちるとイベントが呼ばれるところまでやりたいと思います。

 

まずは画面にボタンの代わりとなるノードを配置

ボタンを設置したいシーンを開いて、SKSpriteNodeを設置します。

f:id:daidaidaily:20180525190113p:plain

 

設置したノードのNameのところに、StartButtonを記入しておきます。まずはゲームを始めるためのスタートボタンを置こうと目論んでます。

f:id:daidaidaily:20180525190307p:plain

 

ボタンクラスの作成

SupportClassのフォルダをプロジェクトに追加して、その中にButtonNode.swiftファイルを作成します。

f:id:daidaidaily:20180525184426p:plain

 

Swiftを試行錯誤しながらがんばって作ったクラスの初期化をもとに、ButtonBodeクラスを宣言して初期化コード作成。

//ボタンクラスの初期化

init(aNormalImage:String, aPushedImage:String, aKey:String){

    _NormalTexture = SKTexture(imageNamed:aNormalImage)

    _PushedTexture = SKTexture(imageNamed:aPushedImage)

    _IsContinuePush = false

    _IsPushed = false

    _IsEnabled = true

    let col = SKColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)

    super.init(texture:_NormalTexture, color: col, size:_NormalTexture.size())

    //super.initの後にselfを指定

    self.name = aKey

    //タッチ検出機能を有効化

    self.isUserInteractionEnabled = true

}

 

第1引数は通常時のボタン画像、第2引数は押下時のボタン画像です。第3引数はこのボタンを押した時の目印となるキーワードを渡しています。後にシーンクラス上でボタンがタップされたことを判断する時に使用します。

 

isUserInteractionEnabledをtrueにしてタップを有効にしておきます。親クラスの初期化の部分はとりあえず動くようにしただけなので、なんでいきなり色の宣言がでてきたん!?って感じになってますけど、今は目をつぶっています。

 

初期化関数の他にもうひとつ、ボタンの配置とイベント受け取りのための設定をするための関数を作成します。  

var delegate:CButtonDelegate?

//1,delegate指定するscene 2,位置決め用spriteNode

    func SetDelegateAndPosition(aScene:SKScene, aPositionNode:SKSpriteNode){

        //btnのdelegateプロパティにシーンをセット

        self.delegate = aScene as? CButtonDelegate

        //画面にボタンを追加

        aScene.addChild(self)

        //大きさの指定

        self.size = aPositionNode.size

        //位置の指定

        self.position = aPositionNode.position

        //位置決めノードは画面から消してしまう

        aPositionNode.removeFromParent()

    }

//ボタン押下時に呼ばれる関数定義

protocol CButtonDelegate {

    func Pushed(aButton:ButtonNode)

}

 

第1引数はボタンを配置するシーンクラス。ボタンクラス内で宣言したdelegateクラスと紐づけることで、ボタンをタップした時に元のシーンクラスにイベントが飛ぶようにしています。元のシーンクラスではどのボタンを押したかがわかるように分岐が必要になります。

 

第2引数はボタンを設置する場所に置いたSKSpriteNodeクラスです。大きさと位置を取得した後は用済みということで画面から除外しています。

 

シーン側でのイベント受け取り

シーンではボタンクラスの作成と、ボタンイベントを受け取るコードを記述します。

import SpriteKit

import GameplayKit

 

//新しく作った名前「TitleScene」でSKSceneを生成する

class TitleScene: SKScene, CButtonDelegate {

    override func didMove(to: SKView) {

        //ボタンクラス作成

        let StartButton = ButtonNode(aNormalImage: "StartButtonNormal", aPushedImage: "StartButtonPushed", aKey: "StartButtonPushed")

        //ボタンの位置と押下イベント作成

        StartButton.SetDelegateAndPosition(aScene: self, aPositionNode: childNode(withName: "//StartButton") as! SKSpriteNode)

    }

    

    //ボタンクラスで作成したボタンが押された場合に呼ばれる関数

    func Pushed(aButton: ButtonNode) {

        if (aButton.name == "StartButtonPushed") {

            print("スタートボタンが押されました")

        }

    }

 

}

 

この例では、先ほど作成したスタートボタンをタップすると、まずPushed関数が呼ばれます。ボタンを初期化する際に渡したキーワードStartButtonPushedかどうかを判定して、ボタンの名前と一致すればスタートボタンが押されたことを判断します。

 

これで、スタートボタン以外にもボタンを置いて、どのボタンが押されたかを正しく認識できるようになります。

 

例によって試行錯誤でしたが、なんとか狙い通りの動きができまーしーたー。