How do I convert coordinates in SpriteKit?

scr*_*Man 2 coordinate-transformation ios sprite-kit skshapenode swift

I'm trying to grasp the conversion thing in SpriteKit but despite having read the documentation and several posts on SO I can't seem to get it right. As far as I understand there are two coordinate systems that work independently of one another, one for the scene and one for the view, which is why I simply can't use the things like UIScreen.main.bounds.maxX to determine screen corners that the node can relate to. Am I getting this right?

Anyway, here's my attempt at converting coordinates:

let mySquare = SKShapeNode(rectOf: CGSize(width: 50, height: 50))
mySquare.fillColor = SKColor.blue      
mySquare.lineWidth = 1

let myPoint = CGPoint(x: 200, y: 0)

let newPosition = mySquare.convert(myPoint, from: self)     
mySquare.position = newPosition

print(newPosition)  
self.addChild(mySquare)
Run Code Online (Sandbox Code Playgroud)

返回print的位置与输入的位置完全相同,所以显然我做得不对,但我尝试了许多不同的星座,但几乎没有结果;坐标保持不变。我也尝试过,let myPoint = CGPoint(x: UIScreen.main.bounds.maxX, y: UIScreen.main.bounds.maxY)但那里是一样的;没有转换。

我缺少什么?在我的脑海中,我将上面的转换理解为“myPointview坐标系转换并将其用于我的nodemySquare”。

bg2*_*g2b 5

周围有很多坐标系,因此有很多潜在的混乱来源:

  1. 场景坐标:这是您的游戏世界,也是您在想象坐标以及如何整体定位事物时通常会想到的内容。
  2. 节点:节点有自己的坐标系。一旦你开始建立层次结构,那就很重要了。例如,想象一下屏幕上的操纵杆,其背景显示移动方向的图形,以及玩家可以操纵的中央“旋钮”。您可以将操纵杆表示为具有两个子节点的节点。一个孩子是背景精灵,另一个是旋钮精灵。背景精灵自然会位于位置 (0,0),即整个操纵杆的中心。旋钮会四处移动,(0,0) 表示居中,(0,100) 表示向上一点。场景中的整个操纵杆可能位于 (200,300)。然后,背景精灵将显示在场景中的 (200,300) 处,旋钮向上时将显示在场景中的 (200,300)+(0,100) = (200,400) 处。和用于在节点层次结构内进行转换convert(from:)。您可以通过或convert(to:)询问旋钮在整个场景坐标中的位置。您很少需要进行此类转换。knob.convert(.zero, to: scene)joystick.convert(knob.position, to: scene)
  3. 视图坐标:视图是场景上的一个窗口,即实际显示的内容。如果您有全屏游戏,则视图基本上由屏幕尺寸(以点为单位)决定。视图坐标映射到场景坐标的方式决定了您实际看到场景的哪一部分。如果需要在视图坐标和场景坐标之间切换,可以使用场景的convertPoint(fromView:)convertPoint(toView:)方法。

如果您不做任何特殊的事情并且场景大小与视图大小相同,则场景视图映射将在视图左下角的场景中具有 (0,0)。另一个常见的约定是通过将​​场景设置anchorPoint为 (0.5,0.5),使场景中的 (0,0) 位于屏幕中心。或者,您可能已经设计了场景,使世界大小为 2000x2000,并且将存在重要的缩放以及可能涉及的信箱或裁剪(取决于场景的设置scaleMode)。或者,如果您的游戏有一个摄像机节点,并且例如摄像机设置为跟随玩家,那么视图到场景的映射将随着玩家的移动而变化。

在您的代码中,调用mySquare.convert(from:)实际上没有任何意义,因为在您进行“转换”时正方形尚未添加到场景中。

无论如何,如果您确实想做“在屏幕的左上角放置一个正方形”之类的事情,那么您可以获取视图框架中的点并将其转换为场景坐标并将正方形的位置设置为该点。

override func didMove(to view: SKView) {
  ...
  mySquare.position = convertPoint(fromView: CGPoint(x: view.frame.minX, y: view.frame.minY))
  addChild(mySquare)
  ...
}
Run Code Online (Sandbox Code Playgroud)

编辑:在初步考虑游戏应如何映射到具有不同尺寸和长宽比的屏幕的设备之后,我鼓励您主要考虑整体场景。一旦您根据场景进行思考,那么frame当您想象“在左边缘”或“右下角附近”时,场景(而不是视图的框架)就成为最自然的参考。