WatchOS3 SpriteKitでボタンを実装

<h2>SpriteKitでボタンを実装</h2>

WatchOSでゲーム開発をする時に必ず必要になるボタンですが、SpriteKitやSceneKitにはありませんのでSpriteNodeを継承した独自クラスを作成しました。
ボタンを押して離した時にblock文で記述されたコードを実行するので、そこでサウンドを再生するなど工夫して使えます。
またソースコードを参考にして自分好みのクラスにして開発効率をあげてください。


```objc:SpriteButtonNode.h
//
//  SpriteButtonNode.h
//  
//
//  Created by 河合代照 on 2016/11/03.
//  Copyright © 2016年 河合代照. All rights reserved.
//
#import <SpriteKit/SpriteKit.h>

@interface SpriteButtonNode : SKSpriteNode
{
    SKTexture *m_texture;
    SKTexture *m_downTexture;
    dispatch_block_t m_buttonDidTouchBlock;
}
-(id)init:(SKTextureAtlas *)atlas Texture:(NSString *)textureStr DownTexture:(NSString *)downTextureStr TouchedBlock:(dispatch_block_t)block;
-(void)changeTexture:(CGPoint)point; //ボタンのテクスチャの切り替え
-(void)changeUpTexture; //ボタン押していないテクスチャに切り替える
-(void)buttonDidTouch:(CGPoint)point; //ボタンを押して離した時
@end
```

```objc:SpriteButtonNode.m
//
//  SpriteButtonNode.m
//
//
//  Created by 河合代照 on 2016/11/03.
//  Copyright © 2016年 河合代照. All rights reserved.
//

#import "SpriteButtonNode.h"

@implementation SpriteButtonNode

-(id)init:(SKTextureAtlas *)atlas Texture:(NSString *)textureStr DownTexture:(NSString *)downTextureStr TouchedBlock:(dispatch_block_t)block
{
    self = [super initWithTexture:[atlas textureNamed:textureStr]];
    if(self)
    {
        //self.anchorPoint = CGPointMake(0, 0);
        //self.position = CGPointMake(0, 50);
        m_texture = [atlas textureNamed:textureStr];
        m_downTexture = [atlas textureNamed:downTextureStr];
        m_buttonDidTouchBlock = block;
        
        self.texture = m_texture;
    }
    
    return self;
}

-(void)buttonDidTouch:(CGPoint)point
{
    //衝突している場合
    if([self containsPoint:point])
    {
        if(m_buttonDidTouchBlock != nil)
        {
            m_buttonDidTouchBlock();
        }
        
        self.texture = m_texture;
    }
}

-(void)changeTexture:(CGPoint)point
{
    //衝突している場合
    if([self containsPoint:point])
    {
        self.texture = m_downTexture;
    }
    else
    {
        self.texture = m_texture;
    }
}

-(void)changeUpTexture
{
    self.texture = m_texture;
}

@end
```

---
使い方：
※説明が簡素ですみません。
ポイントはLongPressGestureRecognizerを使用してタップ開始とタップ終了を判断させています。
タップ開始時にボタンを押下したテクスチャに変更され離した時に元のテクスチャに戻すために
使用しました。

```objc:InterfaceController.m

   // init内で記述 ------------------------------------------

   SpriteButtonNode *spriteButton = (SpriteButtonNode *)[[SpriteButtonNode alloc] init:atlas Texture:@"Button_Disable" DownTexture:@"Button_Press" TouchedBlock:^{
        SKAction *action = [SKAction playSoundFileNamed:@"ok.mp3" waitForCompletion:true];
        [spriteButton runAction:action];
    }];
    spriteButton.anchorPoint = CGPointMake(0, 0);
    spriteButton.position = CGPointMake(0, self.contentFrame.size.height - spriteButton.size.height);
        
    [skScene addChild:spriteButton]; //skSceneはSpriteKitのScene

   //-------------------------------------------------------


// IBでLongPressGestureRecognizerを使ってください
// Min Duration 0
// Taps 0
// Movement 10

- (IBAction)longPressAction:(id)sender
{
    WKLongPressGestureRecognizer *recognizer = (WKLongPressGestureRecognizer *)sender;
    //左上を0,0とした時の座標
    CGPoint point = recognizer.locationInObject;
    
    //左下を0,0とした時の座標に変換させる
    point.y -= self.contentFrame.size.height;
    if(point.y < 0){ point.y *= -1; }
    
    if(recognizer.state == WKGestureRecognizerStateBegan)
    {
        [spriteButton changeTexture:point];
    }
    else if(recognizer.state == WKGestureRecognizerStateEnded)
    {
        [spriteButton buttonDidTouch:point];
    }
    else if(recognizer.state == WKGestureRecognizerStateCancelled)
    {
        [spriteButton changeUpTexture];
    }
    else
    {
        [spriteButton changeUpTexture];
    }
}
```