Swift: центральная точка пальцев в UIRotationGesture находится не в том месте в SKView?

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

Чтобы исправить это, я собирался создать SKNode и поместить его между пальцами в качестве точки привязки для вращения и масштабирования камеры.

Однако я не могу заставить расположение центральной точки пальцев совпадать с правильными координатами в игровой сцене.

Я создал несколько красных прямоугольников для отладки и поиска моей проблемы и выглядит так: Скриншот Gamescene

Куда бы я ни поместил пальцы на всю игровую сцену, чтобы повернуть ее, центр, где, по ее мнению, он должен быть, всегда находится в этом красном пятне.

SKView размещается на раскадровке как представление SpriteKit и привязывается к левому и правому краям экрана с верхним и нижним отступом:

Внутри контроллера просмотра:

    @IBOutlet weak var Gameview: SKView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let scene = GameScene(size:Gameview.frame.size)
        Gameview.presentScene(scene)
    }

Внутри GameScene.swift let a = sender.location(in: self.view), похоже, проблема.

class GameScene: SKScene, UIGestureRecognizerDelegate {

    var newCamera: SKCameraNode!

    let rotateRec = UIRotationGestureRecognizer()
    let zoomRec = UIPinchGestureRecognizer()
    //let panRec = UIPanGestureRecognizer()


    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                           shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer)
        -> Bool {return true}



    override func didMove(to view: SKView) {

        rotateRec.addTarget(self, action: #selector(GameScene.rotatedView (_:) ))
        rotateRec.delegate = self
        self.view!.addGestureRecognizer(rotateRec)

        zoomRec.addTarget(self, action: #selector(GameScene.zoomedView (_:) ))
        zoomRec.delegate = self
        self.view!.addGestureRecognizer(zoomRec)

        //panRec.addTarget(self, action: #selector(GameScene.pannedView (_:) ))
        //self.view!.addGestureRecognizer(panRec)


        newCamera = SKCameraNode()
        newCamera.position = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
        self.addChild(newCamera)
        self.camera = newCamera

        //drawBoard()
        //I removed this function as it had nothing to do with the question

    }

    @objc func rotatedView(_ sender:UIRotationGestureRecognizer) {
        print(sender.location(in: self.view))
        let square = SKSpriteNode(color: #colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1), size: CGSize(width: 10, height: 10))
        let a = sender.location(in: self.view)
        let b = -a.x
        let c = -a.y
        let d = CGPoint(x: b, y: c)


        square.position = d
        self.addChild(square)


        newCamera.zRotation += sender.rotation
        sender.rotation = 0
        if sender.state == .ended {
            let rotateAmount = abs(Double(newCamera.zRotation) * Double(180) / Double.pi)
            let remainder = abs(rotateAmount.truncatingRemainder(dividingBy: 90))
            //print(rotateAmount)
            //print(remainder)
            if remainder < 10 {
                newCamera.zRotation = CGFloat((rotateAmount-remainder)*Double.pi/180)
            } else if remainder > 80 {
                newCamera.zRotation = CGFloat((rotateAmount-remainder+90)*Double.pi/180)
            }

        }

    }



    @objc func zoomedView(_ sender:UIPinchGestureRecognizer) {
        let pinch = SKAction.scale(by: 1/sender.scale, duration: 0.0)
        newCamera.run(pinch)
        sender.scale = 1.0
    }

    //@objc func pannedView(_ sender:UIPanGestureRecognizer) {
    //    sender.translation(in: )
    //}


    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            let previousLocation = touch.previousLocation(in: self)
            let deltaY = location.y - previousLocation.y
            let deltax = location.x - previousLocation.x
            newCamera!.position.y -= deltaY
            newCamera!.position.x -= deltax
        }
    }
}

Я удалил функцию drawboard(), поскольку она была избыточной в контексте вопроса.


person Community    schedule 20.09.2017    source источник


Ответы (1)


Вам нужно было преобразовать координаты из sender.location в координаты в skview, используя функции, показанные на странице:

https://developer.apple.com/documentation/spritekit/skscene

--> https://developer.apple.com/documentation/spritekit/skscene/1520395-convertpoint

в функцию rotatedview(), поместив код:

let bluesquare = SKSpriteNode(color: #colorLiteral(red: 0.2392156869, green: 0.6745098233, blue: 0.9686274529, alpha: 1), size: CGSize(width: 10, height: 10))

let a = sender.location(in: self.view)
bluesquare.position = self.convertPoint(fromView: a)

self.addChild(bluesquare)

... добавит синие спрайты в центр ваших двух пальцев.

person Community    schedule 21.09.2017