Подтвердить что ты не робот

Универсальные 2D-игры и абсолютные Node Позиционирование

У меня есть вопрос относительно универсальных игровых активов и абсолютного позиционирования SKNodes в Sprite Kit (iOS 8 +).

Я попытаюсь представить свою проблему в следующем примере:

Представьте себе 2D сверху вниз игру с SKSpriteNode, которая представляет собой дом. В доме много детей SKSpriteNode, которые представляют собой стулья, письменный стол, диван и т.д.

У меня есть 3 версии домашнего имущества:

  • 1x - 200 x 200px (не-сетчатые iPads),
  • 2x - 400 x 400px (Retina iPhones и iPads),
  • 3x - 600 x 600px (iPhone 6 Plus).

Внимание!: Позиции дочерних узлов (стулья, стол и т.д.) Определяются в файле .plist. Что-то вроде этого (представление JSON):

children: [
    {
        position = {20,20};
    },
    ...
]

Поскольку позиция определяется в точках, а не в пикселях, все становится позиционированным, как ожидалось, в соответствии с масштабом экрана устройства. Для устройств 1x положение остается {20,20}, для 2x - {40,40}, а для 3x позиция {60,60}.

Проблема

Проблема заключается в том, что 200x200px и 400x400px активы относятся к малым для iPad устройств, чтобы добиться одинакового внешнего вида на всех устройствах.

Вопрос

Как успешно представлять/импортировать активы таким образом, чтобы мне добиться одинакового (если не то же) внешнего вида устройств/размеров экрана без нарушения расположения дочерних узлов?

Мое занятие:

Возьмите 1:

Я мог бы просто использовать существующие ресурсы 400x400px для устройств iPad без сетчатки и 600x600px активов на устройствах Retina iPad для дома node, но расположение дочерних узлов будет нарушено. Это связано с тем, что значение позиции дочернего элемента не изменилось и все равно будет {20,20} и {40,40} для устройств iPad соответственно, тогда как активы будут больше. Это приведет к неточным положениям ребенка по отношению к дому node.

Возьмите 2:

Я мог бы также масштабировать размер SKScene (эффект масштабирования) при использовании обычных ресурсов 200x200px и 400x400px для устройств iPad соответственно. Это работает, и он удерживает работу дочерних узлов, но качество воспроизведения сцены/активов не так хорошо, как должно быть. Кроме того, это похоже на взлом, и мы этого не хотим.

Возьмите 3:

Я мог бы также использовать в два раза большие активы для устройств iPad и удвоить положение дочерних узлов во время выполнения. В этом случае я бы использовал ресурс 400x400px для устройств iPad без сетчатки и новый ресурс 800x800px для устройств iPad Retina. Хотя это выглядит великолепно и поддерживает работу с дочерними узлами, это выглядит как по-настоящему большая позиция для хранения дочерних элементов node во время выполнения:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    position.x *= 2.0f;
    position.y *= 2.0f;
}

Спасибо, что нашли время, чтобы прочитать вопрос!

4b9b3361

Ответ 1

Я мог бы просто использовать существующие активы 400x400px на iPad без сетчатки устройств и 600x600px активов на устройствах Retina iPad для дома nodeно расположение дочерних узлов будет нарушено. Это потому что значение позиции ребенка не изменится и все равно будет {20,20} и {40,40} для устройств iPad соответственно, тогда как активы будет больше. Это приведет к неточным отношениям с детьми к дому node.

Вы можете просто масштабировать свой дом node (а не сцену) до большего размера. Все, что вам нужно сделать, это установить масштаб вашего дома на значение, которое хорошо выглядит на больших устройствах. И на самом деле, вместо того, чтобы проверять iPad, мы можем придумать формулу, которая устанавливает масштаб в зависимости от размера экрана. Что-то вроде кода ниже должно работать. Обратите внимание, что он предполагает, что ваш дом идеально расположен на iPhone 4, и он будет последовательно масштабироваться для всех больших экранов. Обратите внимание, что вы действительно можете выбрать любой произвольный размер в качестве базового кода, но выбор самого маленького экрана и масштабирование проще всего. Просто не забудьте предоставить более крупные текстуры, чтобы текстуры не размывались при масштабировании.

[house setScale:self.scene.size.width/320.0];

ИЛИ

Вы можете использовать два узла. Корень node для размещения "фактического" положения, а затем изображение node для отображения изображения. Это позволит вам отделить ваши позиционные данные от отображаемого. Вы можете изменить размер и положение своего дочернего образа node, но вы хотите, не испортив фактическое положение корня node. Вы даже можете включить данные дополнительных изображений node в свой JSON.


Я мог бы также масштабировать размер SKScene (эффект масштабирования), используя нормальный размер 200x200px и 400x400px для устройств iPad соответственно. Это работает, и он поддерживает позиционирование дочерних узлов но рендеринг качества сцены/активов не очень хорош, поскольку он должно быть. Кроме того, это похоже на взлом, и мы этого не хотим.

Этот параметр может определенно работать, если ваше приложение может каким-то образом обрабатывать различные пропорции. Например, вы можете разрешить прокрутку сцены, если масштаб сцены больше экрана устройства. Потеря качества возникает из-за того, что вы масштабируете текстуры, превышающие их ожидаемый размер. Вам нужно предоставить более крупные текстуры, чтобы поддерживать высокое качество при масштабировании. В этом случае вы могли бы просто использовать свои 600x600 изображений (или, может быть, даже больше) и позволить масштабированию с масштабированием. Например, в моей игре RTS Sprite-Kit для OS X я масштабирую всю сцену, чтобы получить одинаковое представление обо всех устройствах. И я не теряю никакого качества, потому что я уверен, что обеспечиваю очень большие текстуры, поэтому нет потери качества при масштабировании.


Я мог бы также использовать в два раза большие активы для iPad-устройств и удвоить положение дочерних узлов во время выполнения. В этом случае я бы использовал 400x400px для не-сетчатых устройств iPad и нового 800x800px активов для IPad устройств сетчатки. Хотя это выглядит великолепно и удерживает ребенка узлы позиционируют работу, это похоже на действительно большую фиксацию взлома child node во время выполнения с этим:

Это также может работать, особенно если ваш iPad требует специальной компоновки. Однако, если это возможно, избегайте проверки специально для iPad и вместо этого используйте размер экрана для создания правил компоновки, чтобы ваши узлы динамически изменяли все размеры экрана (см. Строку выше). Иногда это невозможно, если ваш iPad-макет сильно отличается от iPhone, и в этом случае у вас не будет выбора, кроме как проверить iPad.


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

Я также рекомендовал бы вы увидеть мои два ответа ниже. Не уверены, но они могут помочь вам в понимании универсального позиционирования и масштабирования в наборе Sprite.

fooobar.com/questions/127902/...

fooobar.com/questions/127905/...

Удачи вам в игре, сообщите мне, если у вас есть вопросы.

Ответ 2

Нет простого способа сделать то, что вы хотите. Один из подходов - использовать фиксированный размер экрана на ваших устройствах. IPhone 5 полностью подходит для iPhone 6+, все используют соотношение сторон 16: 9 для своих экранов. В то время как iPad и iPhone 4s и более ранние, все используют соотношение сторон экрана 4: 3.

Перед представлением GameScene вы можете определить соотношение сторон экрана, а затем установить фиксированный размер вида, подобный этому, в формате 16: 9:

GameScene *startGame = [[GameScene alloc] initWithSize:CGSizeMake(736, 414)];
startGame.scaleMode = SKSceneScaleModeAspectFit;

или это для 4: 3

GameScene *startGame = [[GameScene alloc] initWithSize:CGSizeMake(1024, 768)];
startGame.scaleMode = SKSceneScaleModeAspectFit;

Точные значения действительно не имеют значения, только коэффициенты.

Знание точного размера экрана позволит вам размещать объекты более точно, независимо от экрана iPhone 5 или экрана 6+.

Ответ 3

Используя объекты изображения, вы также можете указать IP-версии изображения.

Однако на самом деле не существует способа добавить некоторую дополнительную логику в ваше приложение, разветвляясь в зависимости от того, выполняется ли ваша работа на iPad и настраивается ли положение вручную.

Мы могли бы обсудить, как лучше всего включить это: я не поклонник этого "если я не это устройство" проверяет все на протяжении всего кода. Создайте абстрактный суперкласс и два подкласса, каждый макет обработки (или все, что вы захотите назвать) для одного идиома интерфейса. Вам нужно будет только один раз проверить (при их создании), а полиморфизм позаботится об остальном.

Ответ 4

Вы можете использовать программное обеспечение как PaintCode, чтобы динамически генерировать текстуру, идеально соответствующую вашим потребностям.

Все, что вам нужно сделать, это определить размеры frame для каждого из ваших устройств.