Позиционирование узлов на сцене для работы на всех размерах экрана SpriteKit

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

 sprite.position = CGPoint(scene.size.width/2, scene.size.height/2 + scene.size.height * 0.4) 

и да, это работает для элементов игрового процесса, таких как игрок. Я понял, что этот метод ужасно непредсказуем для позиционирования элементов HUD и экрана меню в виде кнопок, которые затем имеют тенденцию перекрываться из-за динамического размера спрайтов и/или неизвестного масштабирования сцены в зависимости от устройства пользователя. (Если я правильно расположил его на iPhone, он исчезнет с экрана на iPad и наоборот), например

sprite.size = CGSize(screen.size.width * 0.6, screen.size.width * 0.6)

Затем я продолжил делать расширение SKSpriteNode, чтобы он мог изменять свой размер в зависимости от заданных границ (CGRect), и тогда я понял, насколько сложным, беспорядочным и трудоемким было позиционирование одного узла на моей сцене. У меня должно быть совершенно неправильное представление о позиционировании узлов в моей сцене, или я делаю это неправильно. Теперь вы понимаете контекст, вот мои вопросы:

  • Должен ли я жестко кодировать позиции (я слышал, что это не очень хороший метод, но, поскольку SpriteKit выполняет масштабирование за вас, разве это не должно работать)?
  • Или я должен создать динамическую позицию в зависимости от соотношения сторон каждого устройства, например.

if scene.size.width/scene.size.height >= 16/9 { //Create position here for this device } else if scene.size.width/scene.size.height >.... { etc etc

Этот метод тоже кажется ненужным, но я могу ошибаться

OR

  • Является ли решение каким-то другим методом, о котором я не знаю

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


person AtomProgrammer    schedule 24.06.2016    source источник
comment
если вы используете заполнение аспекта, вам не нужно выполнять расчеты на основе% здесь   -  person Knight0fDragon    schedule 24.06.2016
comment
Действительно? Но высота сцены на iPad составляет 430 с чем-то, а на iPhone 6S — 532, что является заданной высотой сцены :/   -  person AtomProgrammer    schedule 24.06.2016
comment
так? вы выполняете заполнение аспекта, это означает, что размер сцены сохраняется независимо от размера экрана.   -  person Knight0fDragon    schedule 24.06.2016
comment
Тогда лучше всего будет жестко закодировать позиции и размеры? И просто посмотреть, что работает для всех устройств? :D   -  person AtomProgrammer    schedule 24.06.2016
comment
не обязательно жестко закодированы, но значения могут быть абсолютными. Если вы делаете сцену размером 100x100 с заполнением сторон, это означает, что на каждом устройстве ваша сцена имеет размер 100x100. Что происходит, так это масштабирование 100x100 до самых дальних границ вашего телефона, поэтому обрезка будет происходить на ближайших границах.   -  person Knight0fDragon    schedule 24.06.2016
comment
Подгонка аспекта противоположна, она масштабируется до ближайших границ и дает вам черные полосы на самых дальних границах.   -  person Knight0fDragon    schedule 24.06.2016
comment
Извините, что звучит глупо, но когда вы говорите «абсолютно», что вы имеете в виду? Но что вы так много для вашей помощи, а это уже второй раз, когда вы помогли мне, и я очень благодарен   -  person AtomProgrammer    schedule 24.06.2016
comment
если вы скажете CGPoint(10,10), это всегда займет у вас 10,10 баллов. Его не нужно жестко запрограммировать, его можно поместить в переменную, которая меняет свои числа. Вам не нужно делать CGPoint (10/scene.size.width, 10/scene.size.height)   -  person Knight0fDragon    schedule 24.06.2016
comment
Действительно? Значит, CGPoint(10/scene.size.width,...) не нужен?! Это сэкономит столько времени, спасибо!!   -  person AtomProgrammer    schedule 24.06.2016
comment
нужна только математика на основе процента времени, если вы использовали масштабирование .Fill, потому что оно не сохраняет соотношение сторон (но сохраняет размер). ResizeFill - единственный, который фактически изменяет размер сцены, и поскольку мы меняем размер сцены, вам не нужно делать математику в процентах, иначе вы бы использовали масштабирование .Fill   -  person Knight0fDragon    schedule 24.06.2016
comment
Хорошо, большое спасибо!!   -  person AtomProgrammer    schedule 24.06.2016
comment
на самом деле, я получил это задом наперед, вам это не нужно с .Fill, потому что размер сохраняется, вам это нужно с .ResizeFill, потому что размер не сохраняется, и если вы делаете .Fill и делаете новый skscene с размером экрана , то вы делаете это неправильно и должны просто делать .ResizeFill   -  person Knight0fDragon    schedule 24.06.2016
comment
Еще один момент: как вы обрабатываете биты, которые обрезаются, когда вы делаете HUD в верхней части экрана в портретном режиме?   -  person AtomProgrammer    schedule 24.06.2016
comment
А как насчет .AspectFill?   -  person AtomProgrammer    schedule 24.06.2016
comment
те, которые вам нужно учитывать с помощью математики, вам нужно выяснить необходимое заполнение   -  person Knight0fDragon    schedule 24.06.2016
comment
уже объяснил   -  person Knight0fDragon    schedule 24.06.2016
comment
Ахах, хорошо, извините, я не понял, что вы давали дополнительную информацию о других настройках масштабирования, спасибо!! Итак, если бы мне нужно было три метки для моего HUD в верхней части экрана, я бы сделал отступы сверху и по бокам и просто методом проб и ошибок изменил размер шрифта и значения отступов, чтобы они были одинаково расположены для каждого устройства?   -  person AtomProgrammer    schedule 24.06.2016
comment
нет, вы можете решить это с помощью математики, или вы можете поискать здесь, потому что я разместил математику, чтобы справиться с этим, как, я уверен, и другие, мне просто не хочется ее искать.   -  person Knight0fDragon    schedule 24.06.2016
comment
Хорошо, спасибо за помощь!!   -  person AtomProgrammer    schedule 24.06.2016


Ответы (1)


Поскольку вы используете AspectFill в качестве режима масштабирования, сцена автоматически масштабирует его. При этом вы затем сделаете размер экрана 768x1024 (портрет) или 1024x768 (пейзаж). Чтобы сделать это совместимым со всеми устройствами, просто сделайте фон 1024x1024, чтобы он хорошо выглядел на iPad, и вы можете настроить элементы HUD только для iPad, выполнив что-то вроде этого:

if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
    yourButton.position.y += 100
    yourLabel.position.y += 100
    etc
 }

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

person Nik    schedule 28.08.2016