5

I'm building a sprite kit based game, and the lack of "right click" is really making it hard to convey some important information to my users. As a solution, I'm thinking about gestures like long press, two finger tap, etc.

How can one implement gestures on a SKSpriteNode?

Here's what I'm currently using to get a button-like behavior when an SKSpriteNode is touched.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self selectSkill:YES];
}
Ponyboy47
  • 924
  • 9
  • 15
Alex Stone
  • 46,408
  • 55
  • 231
  • 407

3 Answers3

2

Before UIGestureRecognizer, you kept state variables that tracked where touches where and when they started. Here's a swift solution where buttonTouched: is a method that checks whether the UITouch was on the button you're checking.

var touchStarted: NSTimeInterval?
let longTapTime: NSTimeInterval = 0.5

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if buttonTouched(touch) {
            touchStarted = touch.timestamp
        }
    }
}

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    if let touch = touches.anyObject() as? UITouch {
        if buttonTouched(touch) && touchStarted != nil {
            let timeEnded = touch.timestamp
            if timeEnded - touchStarted! >= longTapTime {
                handleLongTap()
            } else {
                handleShortTap()
            }
        }
    }
    touchStarted = nil
}

override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
    touchStarted = nil
}
Christopher Pickslay
  • 17,523
  • 6
  • 79
  • 92
1

Here is a good component that can help https://github.com/buddingmonkey/SpriteKit-Components

adimona
  • 127
  • 7
0

There is no easy way to do it, but one way I can think of would be to add a sub SKView to your SKScene and place an UIImageView as the only thing inside that SKView. Then you can add a gesture recognizer like normal to the SKView.

Here's an example of what I'm talking about:

UIImageView *button = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ButtonSprite"]];

SKView *spriteNodeButtonView = [[SKView alloc] initWithFrame:CGRectMake(100, 100, button.frame.size.width, button.frame.size.height)];

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(someMethod:)];
[spriteNodeButtonView addGestureRecognizer:tap];

[spriteNodeButtonView addSubview:button];

You can put the SKView wherever you want and use any of the gesture recognizers on an SKView: UITapGestureRecognizer, UILongPressGestureRecognizer, UISwipeGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UIPanGestureRecognizer, or UIScreenEdgePanGestureRecognizer.

Then for your method implementation do something like this:

-(void)someMethod:(UITapGestureRecognizer *)recognizer {
    CGPoint touchLoc = [recognizer locationInView:self.view];
    NSLog(@"You tapped the button at - x: %f y: %f", touchLoc.x, touchLoc.y);
}
Ponyboy47
  • 924
  • 9
  • 15
  • You can also check out [this post](http://stackoverflow.com/questions/19082202/spritekit-setting-up-buttons-in-skscene). Someone created an SKButton class that just creates an SKSpriteNode that works like a UIButton. If you'd like to use something more like a button..I use his SKButton class and it works fine for everything I've needed so far, but I haven't needed to use any gesture recognizers.. – Ponyboy47 Dec 14 '13 at 21:34