Проблемы с преобразованием между координатными пространствами в SpriteKit

Я пытаюсь заставить SKShapeNode следовать за UITouch

Моя проблема в том, что расположение UITouch относительно нижнего левого угла экрана, а положение SKShapeNode относительно местоположения, которое я дал ему при создании, центра экрана.

Например: ball центрируется в (189,0, 335,0), центре вида. Я нажимаю на мяч, место касания говорит мне, что событие касания произошло в (189,0, 335,0), но ball.position скажет мне (0,0, 0,0). Как я могу получить позицию ball в системе координат вида?

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    var touched = false
    var location = CGPoint.zero
    var ball: SKShapeNode = SKShapeNode(circleOfRadius: 15)
    var background: SKSpriteNode = SKSpriteNode(imageNamed: "background")

    override func didMove(to view: SKView) {
        background.size = frame.size
        background.position = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height / 2)
        addChild(background)

        let path = CGMutablePath()
        path.addArc(center: CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height / 2),
                    radius: 15,
                    startAngle: 0,
                    endAngle: CGFloat.pi * 2,
                    clockwise: false)
        ball = SKShapeNode(path: path) // Added to center of screen
        ball.lineWidth = 1
        ball.fillColor = .cyan
        ball.strokeColor = .cyan
        ball.glowWidth = 0.5
        addChild(ball)
        print(ball.position)
    }


    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
        moveNode()
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        touched = true
        for touch in touches {
            location = touch.location(in: view)
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            location = touch.location(in: view)

        }
    }

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

    func moveNode() {
        if touched {
            let speed: CGFloat = 1
            if location.x < ball.position.x {
                let newLocation = ball.position.x - speed
                ball.position = CGPoint(x: newLocation, y: ball.position.y)
            } else {
                let newLocation = ball.position.x + speed
                ball.position = CGPoint(x: newLocation, y: ball.position.y)
            }
        }
    }
}

person Davis Mariotti    schedule 15.03.2018    source источник
comment
Если вы используете location = touch.location(in: self), location будет в координатах сцены, а не в координатах вида.   -  person 0x141E    schedule 15.03.2018


Ответы (1)


Вы никогда не устанавливаете положение мяча так, чтобы оно было (0,0). Проблема в том, что мяч находится в точке (0,0), но его путь представляет собой точку (189 335) в координатах мяча. Изменить на:

override func didMove(to view: SKView) {
    background.size = frame.size
    background.position = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height / 2)
    addChild(background)

    let path = CGMutablePath()
    // construct a path relative to center of the ball
    path.addArc(center: CGPoint(x: 0, y: 0),
                radius: 15,
                startAngle: 0,
                endAngle: CGFloat.pi * 2,
                clockwise: false)
    ball = SKShapeNode(path: path)
    // locate the ball at the center of the screen
    ball.position = CGPoint(x: view.frame.size.width / 2, y: view.frame.size.height / 2)
    ball.lineWidth = 1
    ball.fillColor = .cyan
    ball.strokeColor = .cyan
    ball.glowWidth = 0.5
    addChild(ball)
    print(ball.position)
}
person Jean-Baptiste Yunès    schedule 15.03.2018