【问题标题】:iOS7 Sprite Kit how to get long press or other gestures on SKSpriteNode?iOS7 Sprite Kit 如何在 SKSpriteNode 上获得长按或其他手势?
【发布时间】:2014-01-02 00:15:35
【问题描述】:
我正在构建一个基于 sprite kit 的游戏,但缺少“右键单击”确实很难将一些重要信息传达给我的用户。作为一种解决方案,我正在考虑长按、两指点击等手势。
如何在 SKSpriteNode 上实现手势?
这是我目前用来在触摸 SKSpriteNode 时获得类似按钮的行为的方法。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self selectSkill:YES];
}
【问题讨论】:
标签:
ios
objective-c
sprite-kit
gestures
long-press
【解决方案1】:
没有简单的方法可以做到这一点,但我能想到的一种方法是将子 SKView 添加到您的 SKScene 并将 UIImageView 作为该 SKView 中唯一的东西。然后,您可以像往常一样向 SKView 添加手势识别器。
下面是我所说的一个例子:
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];
您可以将 SKView 放在您想要的任何位置,并在 SKView 上使用任何手势识别器:UITapGestureRecognizer、UILongPressGestureRecognizer、UISwipeGestureRecognizer、UIPinchGestureRecognizer、UIRotationGestureRecognizer、UIPanGestureRecognizer 或 UIScreenEdgePanGestureRecognizer .
然后为你的方法实现做这样的事情:
-(void)someMethod:(UITapGestureRecognizer *)recognizer {
CGPoint touchLoc = [recognizer locationInView:self.view];
NSLog(@"You tapped the button at - x: %f y: %f", touchLoc.x, touchLoc.y);
}
【讨论】:
-
您也可以查看this post。有人创建了一个 SKButton 类,该类只创建了一个 SKSpriteNode,其工作方式类似于 UIButton。如果您想使用更像按钮的东西..我使用他的 SKButton 类,它适用于我目前所需的一切,但我不需要使用任何手势识别器..
【解决方案3】:
在UIGestureRecognizer 之前,您保留状态变量来跟踪它们在何时何地开始接触的位置。这是一个快速解决方案,其中buttonTouched: 是一种检查 UITouch 是否在您正在检查的按钮上的方法。
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
}