2015-12-17 4 views
3

Так что я делаю игру с spritekit с помощью быстрой. И мне было интересно, что лучше всего использовать жестом?touchsBegan Vs UITapGestureRecognizer

В настоящее время у меня есть override func touchesBegan обработка всех кранов и UILongPressGestureRecognizer обработка длинных кранов/трюмов.

Знаете ли вы, нажмите кнопку нажатия и прыгает с героем. Длительное удержание делает героя утки.

По какой-то причине моя функция longPress не всегда называется (иногда вы можете нажать и удерживать 10 раз, а затем перестать быть вызванным (не распознано), в других случаях это 5, оно варьируется), и это привело к целый день вчера пробовал новые вещи и расследовал, что привело меня к этому вопросу.

Лучше использовать touchesBegan или переместить все мои сенсорные вызовы на новую функцию, обработанную UITapGestureRecognizer?

Я действительно перемещал все от touchesBegan до UITapGestureRecognizer, но кажется очень вялым. Но я, возможно, неправильно это сделал?

Это как recognisers устанавливаются:

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) 

} 

Эти функции, которые обрабатывают жесты:

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 
    } 
} 

Это функция, которая обрабатывает штрихи/краны:

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) 
} 

Если я переведу все от touchesBegans до tapRecogniser (пустая функция выше), я должен осуществить это тоже, чтобы преобразовать координаты касания местоположения:

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 
} 

Я пробовал оба, но последние, кажется realllllly медленно и вяло. Может быть, я забываю реализовать что-то, что рекомендуется?

Кажется, мой длинный жест не всегда называется, может ли быть конфликт между ними?

+1

Я бы не использовал ничего, что связано с UIKit в игре с spritekit. если вы хотите проверить, как долго прикосновение - это просто время, использующее ваш метод обновления. старайтесь использовать как можно больше инструментов spritekit в своей игре. Все, что связано с UIKit (меню игры или элементы управления), я бы разместил внутри UIViewController. – hamobi

+0

Все, в том числе меню, создается в игреScene и дифференцируется по GameStates (inGame, Menu, gameOver) и т. Д. Итак, вы рекомендуете таймер в 'touchhesBegan' и' if timer> longPressValue duck, иначе прыгаете? 'Или делает SpriteKit имеет различные tapGestures? – Reanimation

+0

у него нет прокси-серверов. Вам просто нужно захватить время, когда вы держите палец вниз, и сбросьте таймер, когда вы отпустите. это любопытная вещь. – hamobi

ответ

2

так что если вы держите на красном квадрате в течение двух секунд, вы получите сообщение, когда вы отпустите сообщение исчезнет. вам, возможно, придется добавить несколько булевых там, чтобы убедиться, что ваш персонаж не повторяет какое-либо действие в каждом кадре после 2-секундной удержания кнопки. этого должно быть достаточно, чтобы вы начали работать, надеюсь, что

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 
     } 
    } 
} 
+0

Oh awesome. Спасибо. Сейчас я сделаю это. Спасибо за публикацию. – Reanimation

+0

@hamobi отличная запись. Просто используя методы touch для запуска и остановки таймеров (NSTimeIntervals не NSTimer, который не должен использоваться в SpriteKit) при использовании обновлений currentTime отлично. Обратите внимание: поскольку вы используете currentTime вместо системного времени, он отлично работает, когда игра приостанавливается по любой причине. –

+0

@SkylerLauren thanks :) – hamobi