over 4 years ago

SKNode でタップイベントを取得しようとしてドハマりしたのでメモを残しておきます
模索した方法は

  • addGestureRecognizer: の類を探す
  • UIButtonaddSubview: してみようとする
  • SKScenetouchesBegan:withEvent: から判断する
  • おとなしく継承クラスを作る

です。

要約すると SKNodeUIResponder を継承してるから直接タップイベントが取得できるけどサブクラスを作るのは面倒臭いからなにかいい方法なないかなと探した結果(たぶん)なかった、です。
何かいい方法を知っている方がいたら教えて下さいm(_ _)m

. addGestureRecognizer: の類を探す

ありませんでした。

. UIButton を addSubview: してみようとする

SKNode には addChild: しかなかったです。
UIView 系統のクラスは追加できないのかな…

. SKScene の touchesBegan:withEvent: から判断する

座標を取得して, どのノードがタップされたか判定して, 重なりを考慮して, ノードの名前からアクション見つけて発火する
面倒臭いです。却下。
ノードとアクションの対応も管理しなきゃいけないし保守性に欠けます。

. 結局サブクラスを作った

今回はタップに反応するメニューボタンを作りたかったので SKLabelNode を継承して作りました。
使い方は

  • userInteractionEnabledYES にする
  • touchAction に適当な SKAction を突っ込む
  • あとは SKLabelNode といっしょ

です。以上。これで UIControlEventTouchUpInside と同じようなタイミングで touchAction を発火してくれます。

短いのでコードを全文載せておきます。
改造するなり好きに使ってくださいm(_ _)m

MenuLabel.h

#import <SpriteKit/SpriteKit.h>

@interface MenuLabel : SKLabelNode

@property (nonatomic,retain) SKAction *touchAction;

//optional
@property (nonatomic,retain) SKAction *touchBeganAction;
@property (nonatomic,retain) SKAction *touchEndAction;

@end

MenuLabel.m

#import "MenuLabel.h"

@implementation MenuLabel

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    
    if(self.touchBeganAction){
        [self runAction:self.touchBeganAction];
    }else{
        [self runAction:[SKAction scaleTo:1.1 duration:0.1]];
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    CGPoint location = [[touches anyObject] locationInNode:self];
    
    if(self.touchEndAction){
        [self runAction:self.touchEndAction];
    }else{
        [self runAction:[SKAction scaleTo:1.0 duration:0.1]];
    }
    
    CGRect frame = CGRectMake(-self.frame.size.width/2, -self.frame.size.height/2, self.frame.size.width, self.frame.size.height);
    if(self.touchAction && CGRectContainsPoint(frame, location)){
        [self runAction:self.touchAction];
    }
}

@end
Python - リスト内包表記 →
 
comments powered by Disqus