簡體   English   中英

如何在Spritekit節點上檢測滑動?

[英]How can I detect swipes on Spritekit Nodes?

所以我目前正在開發一個用Swift3編寫的2D無限運行器,並為我的節點和場景使用Spritekit。 我最近實現了一些代碼來檢測一般的滑動,它們將在下面。 所以我的問題是:如何檢測滑動操作並檢查Spritekit節點上的滑動方向? 我意識到之前已經問過這個,但我找不到一個有效的解決方案,因為我遇到的一切似乎都是針對Swift和Swift2,而不是Swift3。

這是我的滑動檢測代碼:

override func viewDidLoad() {
  super.viewDidLoad()
  let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeLeft.direction = UISwipeGestureRecognizerDirection.left
    self.view.addGestureRecognizer(swipeLeft)

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeRight.direction = UISwipeGestureRecognizerDirection.right
    self.view.addGestureRecognizer(swipeRight)

    let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeUp.direction = UISwipeGestureRecognizerDirection.up
    self.view.addGestureRecognizer(swipeUp)

    let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(self.respondToSwipeGesture))
    swipeDown.direction = UISwipeGestureRecognizerDirection.down
    self.view.addGestureRecognizer(swipeDown)
}

我用功能測試了這些:

func respondToSwipeGesture(gesture: UIGestureRecognizer) {
        if let swipeGesture = gesture as? UISwipeGestureRecognizer {
            switch swipeGesture.direction {
            case UISwipeGestureRecognizerDirection.right:
                print("Swiped right")
            case UISwipeGestureRecognizerDirection.down:
                print("Swiped down")
            case UISwipeGestureRecognizerDirection.left:
                print("Swiped left")
            case UISwipeGestureRecognizerDirection.up:
                print("Swiped up")
            default:
                break
            }
        }
}

滑動似乎可以正常工作,因為打印語句已經顯示正確的輸出以響應我的滑動。

我還添加了一個委托來避免可能的SIGABRT錯誤:

class GameViewController: UIViewController, UIGestureRecognizerDelegate

如果您想了解更多信息,請告訴我們!

編輯:添加了我初始化拼圖的代碼

//The class
class ChoosePiecesClass: SKSpriteNode{
    func moveWithCamera() {
        self.position.x += 5;
}


//initialize a piece
private var RandomPiece1: ChoosePiecesClass?;


override func didMove(to view: SKView) {
    RandomPiece1 = childNode(withName: "RandomPiece1") as? ChoosePiecesClass;
    RandomPiece1?.position.x = 195;
    RandomPiece1?.position.y = -251;
}

override func update(_ currentTime: TimeInterval) {
    RandomPiece1?.moveWithCamera();
}

在單擊“開始游戲”並觸發fatalError代碼時,編輯從控制台提供錯誤語句,導致游戲崩潰。

fatal error: init(coder:) has not been implemented: file /Users/ardemis/Documents/PuzzleRunner/PuzzleRunner 3 V3/PuzzleRunner/ChoosePieces.swift, line 33

它還顯示以下內容

EXEC_BAT_INSTRUCTION(code = EXEC_1386_INVOP, subcode = 0x0)

與fatalError聲明在同一行。

如果我試圖跟蹤特定的SpriteNodes,我不會使用UIGestures。 您可以輕松跟蹤TouchesBegan中的節點,並找出滑動方向發生的方向。 此示例在屏幕上有三個精靈將打印/記錄其中一個被刷卡的方向,並將忽略所有其他滑動。

編輯>我剛剛為我的Box對象創建了一個子類(抱歉,我沒有使用你的命名,但它具有相同的功能)。 可能有很多方法可以做到這一點,我選擇在子類上使用創建協議並使場景符合協議。 我將所有觸摸/滑動功能移動到子類中,當它完成檢測滑動時,它只調用委托並說明哪個對象已被刷過。

protocol BoxDelegate: NSObjectProtocol {
    func boxSwiped(box: Box)
}

class Box: SKSpriteNode {

    weak var boxDelegate: BoxDelegate!
    private var moveAmtX: CGFloat = 0
    private var moveAmtY: CGFloat = 0
    private let minimum_detect_distance: CGFloat = 100
    private var initialPosition: CGPoint = CGPoint.zero
    private var initialTouch: CGPoint = CGPoint.zero
    private var resettingSlider = false

    override init(texture: SKTexture?, color: UIColor, size: CGSize) {

        super.init(texture: texture, color: color, size: size)

        self.isUserInteractionEnabled = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func moveWithCamera() {
        self.position.x += 5
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first as UITouch! {

            initialTouch = touch.location(in: self.scene!.view)
            moveAmtY = 0
            moveAmtX = 0
            initialPosition = self.position
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first as UITouch! {

            let movingPoint: CGPoint = touch.location(in: self.scene!.view)

            moveAmtX = movingPoint.x - initialTouch.x
            moveAmtY = movingPoint.y - initialTouch.y
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

        var direction = ""
        if fabs(moveAmtX) > minimum_detect_distance {

            //must be moving side to side
            if moveAmtX < 0 {
                direction = "left"
            }
            else {
                direction = "right"
            }
        }
        else if fabs(moveAmtY) > minimum_detect_distance {

            //must be moving up and down
            if moveAmtY < 0 {
                direction = "up"
            }
            else {
                direction = "down"
            }
        }

        print("object \(self.name!) swiped " + direction)

        self.boxDelegate.boxSwiped(box: self)
    }
}

在GameScene.sks中

確保通過在聲明后添加協議使GameScene符合BoxDelegate

class GameScene: SKScene, BoxDelegate {

    var box = Box()
    var box2 = Box()
    var box3 = Box()

    override func didMove(to view: SKView) {

        box = Box(color: .white, size: CGSize(width: 200, height: 200))
        box.zPosition = 1
        box.position = CGPoint(x: 0 - 900, y: 0)
        box.name = "white box"
        box.boxDelegate = self
        addChild(box)

        box2 = Box(color: .blue, size: CGSize(width: 200, height: 200))
        box2.zPosition = 1
        box2.name = "blue box"
        box2.position = CGPoint(x: 0 - 600, y: 0)
        box2.boxDelegate = self
        addChild(box2)

        box3 = Box(color: .red, size: CGSize(width: 200, height: 200))
        box3.zPosition = 1
        box3.name = "red box"
        box3.position = CGPoint(x: -300, y: 0)
        box3.boxDelegate = self
        addChild(box3)
    }

    func boxSwiped(box: Box) {
        currentObject = box
        print("currentObject \(currentObject)")
    }

    override func update(_ currentTime: TimeInterval) {
        box.moveWithCamera()
        box2.moveWithCamera()
        box3.moveWithCamera()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM