Как мне конвертировать координаты в SpriteKit? - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь получить asp конверсию в SpriteKit, но, несмотря на то, что прочитал документацию и несколько постов на SO , я не могу понять, что это правильно. Насколько я понимаю, есть две системы координат, которые работают независимо друг от друга, одна для scene и одна для view, поэтому я просто не могу использовать такие вещи, как UIScreen.main.bounds.maxX для определения углов экрана что узел может относиться к. Я правильно понимаю?

В любом случае, вот моя попытка преобразования координат:

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)

print возвращает ту же самую позицию, в которой находился, так что, очевидно, я этого не делаю верно, но я пробовал несколько разных созвездий, но практически безрезультатно; координаты остаются прежними. Я также пытался let myPoint = CGPoint(x: UIScreen.main.bounds.maxX, y: UIScreen.main.bounds.maxY), но то же самое там; нет конверсии.

Чего мне не хватает? В своей голове я прочитал приведенное выше преобразование как "convert myPoint из view системы координат и использую его для моего node mySquare.

1 Ответ

2 голосов
/ 02 марта 2020

Есть много систем координат, плавающих вокруг, и так много потенциальных источников путаницы:

  1. Координаты сцены: это мир вашей игры, и о чем вы обычно думаете, когда представляете координаты и как общее положение вещей.
  2. Узел: Узлы имеют свою собственную систему координат. Как только вы начинаете строить иерархию, это имеет значение. Представьте, например, экранный джойстик с фоном, показывающим график c направлений движения и центральную «ручку», которой игрок может манипулировать. Вы можете представить джойстик как узел с двумя дочерними элементами. Один дочерний элемент является спрайтом для фона, а другой - спрайтом для кнопки. Фоновый спрайт, естественно, будет в положении (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. Координаты вида: вид - это окно на сцене, то есть то, что на самом деле отображается. Если у вас полноэкранная игра, вид в основном определяется размером экрана в пунктах. То, как вид карты координат на координаты сцены, определяет, какую часть сцены вы на самом деле видите. Если вам нужно go между координатами вида и координатами сцены, вы используете методы convertPoint(fromView:) и convertPoint(toView:) сцены.

Если вы не делаете ничего особенного и имеете размер сцены то же самое, что и размер вида, тогда отображение вида сцены будет иметь (0,0) в сцене в левом нижнем углу вида. Другое распространенное соглашение - иметь (0,0) в сцене в центре экрана, установив для сцены anchorPoint значение (0,5,0,5). Или, возможно, вы спроектировали сцену таким образом, чтобы размер мира составлял 2000х2000, и в этом случае будет использоваться нетривиальное масштабирование и возможный почтовый бокс или обрезка (в зависимости от настройки scaleMode сцены). Или, если в вашей игре есть узел камеры и, например, камера настроена на то, чтобы следить за игроком, тогда отображение вида на сцену будет меняться по мере движения игрока.

В вашем коде вызывается mySquare.convert(from:) на самом деле даже не имеет смысла, так как квадрат не был добавлен к сцене в то время, когда вы выполняете «преобразование».

В любом случае, если вы действительно хотите сделать что-то вроде «put» квадрат в верхнем левом углу экрана ", тогда вы можете взять точку в рамке вида и преобразовать ее в координаты сцены и установить для нее позицию квадрата.

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

Редактировать: Я бы Тем не менее, побуждайте вас думать в основном с точки зрения общей сцены, после некоторого первоначального рассмотрения того, как игра должна отображаться на устройствах с экранами разных размеров и форматов. ios. Если вы мыслите в терминах сцены, то сцена frame (а не рамка вида) становится наиболее естественной ссылкой, когда вы воображаете «у левого края» или «у правого нижнего края».

...