So I'm making a spritekit game using swift. And I was wondering which is best to use gesture wise?
Currently I have a override func touchesBegan
handling all taps and a UILongPressGestureRecognizer
handling long taps/holds.
So you know, a tap presses buttons and jumps the hero. The long hold makes the hero duck.
For some reason my longPress function isn't always called (sometimes you can press and hold 10 times and then it stops being called (isn't recognised), other times it's 5, it varies), and this led to a whole day yesterday trying new things and investigating, which brought me to this question.
Is it better to use touchesBegan
or move all my touch calls to a new function handled by a UITapGestureRecognizer
?
I did move everything from touchesBegan
to UITapGestureRecognizer
but it seems very sluggish. But I may have been implementing it wrong?
This is how the recognisers
are set up:
func setupRecognizers() {
let tapRecognizer = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
view!.addGestureRecognizer(tapRecognizer)
let longTapRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("handleLongPress:"))
longTapRecognizer.minimumPressDuration = 0.2
view!.addGestureRecognizer(longTapRecognizer)
}
These are the functions that handle the gestures:
func handleTap(recognizer: UIGestureRecognizer) {
//currently all handled in touchesBegan
}
func handleLongPress(recognizer: UIGestureRecognizer) {
print("1 --------> longPress Called.... ", recognizer.state.rawValue, gameState)
if gameState == .Play {
//do stuff
//duck Hero
} else {
//switch gameState
}
}
This is the function that handles the touches/taps:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
for touch in touches {
let location = touch.locationInNode(self)
//do stuff
switch gameState {
case .MainMenu:
break
... //more states
}
}
super.touchesBegan(touches, withEvent: event)
}
If I move everything from touchesBegans
to a tapRecogniser
(the empty function above), I have to implement this too, to convert the touch location coordinates:
func handleTap(recognizer: UIGestureRecognizer) {
let location = convertPointFromView(CGPoint(x: recognizer.locationInView(nil).x, y: recognizer.locationInView(nil).y))
print("Converted Coords: ", location)
//then do all touchesBegan stuff
}
I've tried both, but the latter seems realllllly slow and sluggish. Maybe I'm forgetting to implement something that is recommended?
Seems my longPress gesture doesn't always get called, could there be some conflict between these?
so if you hold on the red square for two seconds you'll get a message, when you let go the message disappears. you might have to add some booleans in there to make sure your character isnt repeating some action every frame after the 2 second button hold. this should be enough to get you started hopefully
import SpriteKit
class GameScene: SKScene {
// time values
var delta = NSTimeInterval(0)
var last_update_time = NSTimeInterval(0)
var longTouchTimer = NSTimeInterval(0)
var touched = false
var testLabel = SKLabelNode(text: "you have touched for awhile now bro")
let touchSprite = SKSpriteNode(color: SKColor.redColor(), size: CGSizeMake(100, 100))
override func didMoveToView(view: SKView) {
touchSprite.position = CGPointMake(self.size.width/2, self.size.height/2)
addChild(touchSprite)
testLabel.hidden = true
testLabel.position = touchSprite.position
testLabel.position.y += 100
testLabel.fontSize = 20
addChild(testLabel)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if touchSprite.containsPoint(location) {
touched = true
}
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.locationInNode(self)
if !touchSprite.containsPoint(location) {
touched = false
longTouchTimer = 0
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
touched = false
longTouchTimer = 0
}
override func update(currentTime: NSTimeInterval) {
if last_update_time == 0.0 {
delta = 0
} else {
delta = currentTime - last_update_time
}
last_update_time = currentTime
if touched {
longTouchTimer += delta
}
if longTouchTimer >= 2 {
testLabel.hidden = false
} else {
testLabel.hidden = true
}
}
}